I'm new to asp.net & I'm trying to making a website where user can sort a table after login. So far sorting is working fine but everytime I click on the link, whol page reloads & data gets sorted. Instead I want only the table gets updated after clicking the link. I'm trying to use AJAX in my view but nothing happened. Here are my codes,
Controller
public ActionResult Login(string sortOrder)
{
if (Session["UserNAME"]!=null)
{
ViewBag.CodeSort = String.IsNullOrEmpty(sortOrder) ? "code_desc" : "";
var sortedOut = new MkistatVsUserLogin { mkistats = dsedb.mkistats.AsQueryable() };
switch (sortOrder)
{
case "code_desc":
sortedOut.mkistats = sortedOut.mkistats.OrderByDescending(s => s.MKISTAT_CODE);
break;
default:
sortedOut.mkistats = sortedOut.mkistats.OrderBy(s => s.MKISTAT_INSTRUMENT_CODE);
break;
}
return View(sortedOut);
}
else
{
return RedirectToAction("Home");
}
}
View
<th>#Html.ActionLink("Codename", "Login", new { sortOrder = ViewBag.CodeSort }, new AjaxOptions
{
HttpMethod = "GET",
UpdateTargetId = "mktTable",
InsertionMode = InsertionMode.Replace
})</th>
How can I solve this problem? Really need this help badly. Tnx.
Instead of using #Html you should be using #Ajax.
To enable Ajax in your application you need to have jQuery on your view. If you are creating the default setup it should be already included and setup.
Related
I'm working on the table paging, where each page calls the controller to get part of the data, then return the partial view and update it into HTML table.
Here's my controller look like:
public ActionResult SearchData(FormModel model, int? page)
{
/*Codes to get data from DB*/
return PartialView("_DataTable", model);
}
The form input is something like this:
#model Project.ViewModel
#using (Ajax.BeginForm("SearchData", "Player", new AjaxOptions
{ HttpMethod = "GET", UpdateTargetId = "data-table", InsertionMode = InsertionMode.Replace }))
{
#Html.LabelFor(m => m.FormModel.Username)
#Html.TextBoxFor(m => m.FormModel.Username, new { placeholder = "[Username]" })
#*And some more input, all are in FormModel class.*#
}
<div id="data-table">
#Html.Partial("_DataTable")
</div>
The way I generate the page is as follows:
for (var pageNum = Model.PlayerList.Pager.StartPage; pageNum <= Model.PlayerList.Pager.EndPage; pageNum++)
{
if (pageNum == Model.PlayerList.Pager.CurrentPage)
{
<td><span>#pageNum</span></td>
}
else
{
<td>
#Ajax.ActionLink(pageNum.ToString(), "SearchData", new {page = pageNum}, new AjaxOptions
{
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "data-table"
})
</td>
}
}
I can only pass in the page value, is it possible to include the form input Model into Ajax.ActionLink? Something like this:
new {model = Model.FormModel, page = pageNum}
I tried the method above, but didn't work. Any help would be appreciated.
you need add properties of FormModel like this
new {Username="some username",page = pageNum}
I came out with another solution. I put the form model inside TempData just before the controller returns the partial view. At the beginning of the controller, I check if the page value is null, the form input should take from TempData instead. This way, we only pass in the page value since the form input model should always the same, using Ajax.ActionLink as I posted on the question.
Here's the code:
public ActionResult SearchData(FormModel model, int? page)
{
if (page != null)
{
model = TempData["FormModel"] as FormModel ?? new FormModel();
}
/*Codes to get data from DB*/
TempData["FormModel"] = model;
return PartialView("_DataTable", model);
}
do it like this and change fields names and values as your model
note: unfortunately, you should send each value one by one, but not the whole model
#Ajax.ActionLink(pageNum.ToString(), "SearchData",
new
{
FielNameInModel1= Model.FieldNameInModel,
FielNameInModel2 = "xyz",
FielNameInModel3 = 5,
FielNameInModel4 = pageNum.ToString(),
},
new AjaxOptions { HttpMethod = "GET", InsertionMode = InsertionMode.Replace, UpdateTargetId = "AllProjectsDiv", OnComplete = "AjaxFormCompleted" }
, new { #class = "className") })
I am using Ajax.BeginForm() and a UpdateTargetId. However when the user has successfully completed the form and I have done the processing I want to redirect them to a brand new page.
Calling RedirectToAction() and returning a view from there does not work as it targets the id.
I also need to pass parameters to the action. So is my only option to make a JavaScript call of:
return JavaScript("window.location = 'http://www.somewhere.com/blah/blah?aMyParam=123'");
Is there a more elegant way to do this?
Although the way you are doing is correct but more elegant way to do this is shown below :-
Controller -
[HttpPost]
public ActionResult MyAction(MyModel model)
{
if (model.SomeCondition)
{
// return to the client the url to redirect to
return Json(new { url = Url.Action("MyAction2") });
}
else
{
return PartialView("_MyPartialView");
}
}
View -
#using (Ajax.BeginForm("MyAction", "MyController", new AjaxOptions { OnSuccess = "onSuccess", UpdateTargetId = "foo" }))
{
...
}
Javascript -
var onSuccess = function(result) {
if (result.url) {
window.location.href = result.url;
}
}
As shown above you can return Json(having url) from controller action and then redirect from onSuccess javascript function.
I know this sounds like a daft question but is there a way to 'mimic' WebAPI routing style (i.e maybe using the [HttpPost] decoration etc) for a MVC Controller. The gist of my problem is I have a 'container' MVC site. This contain in PreLoad loads up other MVC sites within the areas folder and incorporates them into itself. So it basically acts as a Plugin system. This all works great however I need to add in an API for this site which I thought would be a lot easier just if I made the API as another plugin.
I am using Ninject in my site which again works great getting the dependancies from the plugins all perfectly. The issue is that Ninject automatically detects the MVC Controllers but not the WebAPI ones and I've found out you can't have one project doing both WebAPI and MVC with Nijnect. So my next option is to try and mimic WebAPI within MVC (after all, they are based upon the same thing really.)
I initially thought this would be really easy, default the action name to 'Index' in the routing and them just put the 'AcceptVerbs' decoration on each method. Of course it didn't work.
Does anyone know how I would go about or an alternative to creating something like a RestAPI using only the MVC side (not switching to WebAPI)?
In your RouteConfig.cs file, you can specify which HTTP verb goes to which action by passing an HttpMethodContraint:
routes.MapRoute(
"route that matches only GETs for your url",
"your url",
new { controller = "some controller", action = "some action" },
new { httpMethod = new HttpMethodConstraint("GET") });
This will allow you to define routes to your controller that will mimic WebAPI.
You can use Controllers like usual and have them return the JsonResult. I use this approach for some of my views that need dynamic lists through lookup but don't need to be going to the web api. Along with attribute routing I was able to get web api-like functionality from my MVC
Example scenario is I have a form that fills some fields based on a value selected form a combo box. When a user selects an option I use JQuery to make a call to the WebAPI-like action in my controller.
[RoutePrefix("Pickup")]
[Route("{action=Create}")]
public class PickupController : FrontOfficeAuthorizedController {
[HttpPost]
public JsonResult GetSenderAddress(Guid? addressId) {
if(addreddId != null) {
//Do something to get an address
if(address != null) {
//Only send required info over the wire
return Json(new {
success = true,
address = new {
Address1 = address.Address1,
Address2 = address.Address2,
AddressType = address.AddressType,
CompanyOrName = address.CompanyOrName,
Contact = address.Contact,
Country = address.Country,
PostalCode = address.PostalCode,
Telephone = address.Telephone,
TownCity = address.TownCity,
}
});
}
}
return Json(new { success = false });
}
}
Here is a snippet of the javascript on the client side. Note I'm using Knockout along with JQuery
//Shipfrom properties
self.ShipFromaddressid = ko.observable();
//Update shipfrom address based on id
self.ShipFromaddressid.subscribe(function () { getAddress(); });
var getAddress = function () {
var selectedAddressId = { addressId: self.ShipFromaddressid() };
$.ajax({
url: '#(Url.Action<PickupController>(c=>c.GetSenderAddress(null)))',
type: 'Post',
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify(selectedAddressId),
success: handleResponse
});
};
var handleResponse = function (data) {
if (data.success) {
//console.log(data.address);
self.ShipFromCompanyOrName((data.address.CompanyOrName) ? data.address.CompanyOrName : "");
self.ShipFromContact((data.address.Contact) ? data.address.Contact : "");
self.ShipFromTelephone((data.address.Telephone) ? data.address.Telephone : "");
self.ShipFromAddress1((data.address.Address1) ? data.address.Address1 : "");
self.ShipFromAddress2((data.address.Address2) ? data.address.Address2 : "");
self.shipfromtowncity((data.address.TownCity) ? data.address.TownCity : "");
self.ShipFromPostalCode((data.address.PostalCode) ? data.address.PostalCode : "");
self.ShipFromCountry((data.address.Country) ? data.address.Country : "");
self.ShipFromAddressType((data.address.AddressType) ? data.address.AddressType : "");
}
};
Hi I am trying to create a shopping cart using ajax.I am kind of stuck it's the first time I use ajax.What I am trying to do is create an ajax.Actiolink that will update a Inner text of a span tag.Here is my code so far:
//This is the span I want to update
<span id="UpdateCart">0</span>
#Ajax.ActionLink("Add To Cart" ,
"AddToCart" ,
"Products",
new {
ProductId = #products.ElementAt(0).Value
},
new AjaxOptions{
Url = "/Product/AddToCart",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "UpdateCart",
})
public ActionResult AddToCart(string ProductId)
{
if( User.Identity.IsAuthenticated ) {
//CartHelperClass.AddToCart(ProductId);
return PartialView();
} else {
return RedirectToAction("LogIn" , "Account" , new {
returnUrl = "Products" , subCat = Request.QueryString["subcat"]
});
}
}
//This is my PartialView code:
<span id="UpdateCart">(5)</span>
I would like to be able to take the data inside the partialVieew and update the span at the Top when I click the link.In my case I can not tell if AdToCart action result is even called.
What am I doing wrong herE?
You are using Products in the action link but your are using Product in Url link, maybe one of them is wrong.
I am trying to write a link to a partial view on the same page. Everything works, except that I am not able to pass in the needed month parameter through my ajax.actionlink syntax. I've tried using the ViewDataDictionary, but to no avail. Also, RouteValueParameter was a thought I had, but I'm trying to pass a string, not an integer id.
Below is my code in the view, followed by the method in the controller:
<td>#Ajax.ActionLink("January", "ControllerMethod", new ViewDataDictionary{{"month", "January"}}, new AjaxOptions { UpdateTargetId = "view-month" })</td>
public ActionResult ViewMonths(string month)
{
//some code here
return PartialView("ViewMonths", schedule);
}
Any ideas?
Try this way
#Ajax.ActionLink("Link Text", "MyAction", "MyController", new { month = "January", plum = "2", moreparams = "U can do this all day"}, new AjaxOptions{ UpdateTargetId = "view-month" } )
Greatings