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.
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 new to MVC and trying to pass the last created Id (once the save button has been clicked in the form).
Can anyone please tell me if it is possible to pass this value to the toastr display, and how this can be done, so once the save button is pressed it returns that Id number?
Additionally to my comment, here's a more complex answer.
Roughly it contains the following items:
Views: CreateItem, NewItemHandler
Controllers: ItemHandler
Javascript: site.js and jQuery
The CreateItem view is the dialog where the user enters their item values. In my case a simple form with two input fields and the mandatory submit button.
#{
ViewBag.Title = "CreateItem";
}
<h2>CreateItem</h2>
<form id="newItemForm">
Item name: <input id="itemname" type="text" name="fname"><br>
Item weight: <input id="itemweight" type="text" name="lname"><br>
<input type="submit" value="Submit">
</form>
The JavaScript should stop the redirection when clicking on submit, this is done by returning false within $("newItemForm").submit(...). Furthermore we no need to tell the server that it needs to create our item, so we have to create our own submit request, which I did with jQuery.post():
$('#newItemForm').submit(function () {
sendPostAndShowResult();
return false;
});
function sendPostAndShowResult() {
var name = $("#itemname").text();
var weight = $("#itemweight").text();
$.post("/Item/NewItemHandler",
{ "name": name, "weight": weight }
).done(function (data) {
alert("The ID of your new item is: " + $.trim(data)); //replace with toast
})
.fail(function () {
alert("Error while processing the request!");
});
}
Just a hint: I didn't use toast here, since I never used it, but I guess it shouldn't be too difficult to adapt.
The final piece of the puzzle is the NewItemHandler, which creates the item, figures out the ID and returns the value:
The View is quite easy. Since we don't need a Layout, it has been set to "".
#{
Layout = "";
}
#Html.Raw(Session["ItemID"])
As you see, we just need to get the "ItemID" into our Session object, this is done by the Controller.
[HttpPost]
public ActionResult NewItemHandler(string name, string weight)
{
int id = GenerateNewItem(name, weight);
Session["ItemID"] = id;
return View();
}
EDIT: I tried to adapt this approach to your solution:
You need to remove the return RedirectToAction() with return View(); in your Controller. This then returns (Save.cshtml) a response, with the ID in an ohterwise empty file (Layout = "").
Your Save.cshtml is empty I guess, so replace it with
#{
Layout = "";
}
#Html.Raw(Session["ItemID"])
In your controller the Save Method should look remotely like this.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Save(BidstonHwrc bidstonhwrc)
{
_context.BidstonHwrc.Add(bidstonhwrc);
try
{
_context.SaveChanges(); //either all changes are made or none at all
}
catch (Exception e)
{
Console.WriteLine(e);
}
int id = bidstonhwrc.Id;
Session["ItemID"] = id;
return View();
}
In your MCN Form you need to give your <form> tag an ID, via Razor:
#using (Html.BeginForm("Save", "BidstonHwrc",FormMethod.Post, new { id = "SaveBidstonHwrc" }))
The javascript code should look like this, simply adapt the IDs:
$('#SaveBidstonHwrc').submit(function () {
sendPostAndShowResult();
return false;
});
function sendPostAndShowResult() {
//foreach Model/ViewModel Property one line e.g.
var Id = $("Id").text();
var McnNumber = $("McnNumber").text();
$.post("/BidstonHwrc/Save",
{ "Id": Id, "McnNumber": McnNumber }
).done(function (data) {
alert("The ID of your new item is: " + $.trim(data)); //replace with toast
$(location).attr('href', '/Home/Index') //Redirect to Home
})
.fail(function () {
alert("Error while processing the request!");
});
}
I uploaded a project that should represent your solution a bit.
You can download it here (28MB): Project download
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.
Hi I am trying to get a querystring from an ajax call and it does not seem to work so well.Here is my code:
#Ajax.ActionLink("Add To Cart" ,
"AddToCart" ,
"Products",
new {
ProductId = #products.ElementAt(0).Value
},
new AjaxOptions{
Url = "/Products/AddToCart",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "UpdateCart",
HttpMethod = "GET"
})
Each link I have in my application calls something like this:
Products/AddToCart?ProductId=5
This is the controller it calls:
public ActionResult AddToCart(string ProductId)
{
string ProductCeva = ProductId;
}
Now from what I learned so far about MVC3 I assumed that the parameter ProductId would be 5 in our case , but when I debug the code , I get that it is null.
What am I doing wrong here and how can I get the ProductId query string in this casE?
Remove the Url = "/Products/AddToCart", bit from your AjaxOptions.
Why?
Here's why. The following code:
#Ajax.ActionLink(
"Add To Cart" ,
"AddToCart" ,
"Products",
new {
ProductId = #products.ElementAt(0).Value
},
new AjaxOptions {
Url = "/Products/AddToCart",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "UpdateCart",
HttpMethod = "GET"
}
)
generates:
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#UpdateCart" data-ajax-url="/Products/AddToCart" href="/Products/AddToCart?ProductId=5">Add To Cart</a>
Now even if the href of the generated anchor is correct (/Products/AddToCart?ProductId=5) that's not what is used for the AJAX request. The jquery.unobtrusive-ajax.js that you are using and which unobtrusively AJAXifies all anchors uses the data-ajax-url attribute (if present) when sending the AJAX request instead of the href attribute. Now look at the value of the data-ajax-url attribute and you will understand why you get null in your controller action.
You would also have seen this if you had used FireBug or a similar javascript debugging tool because when you would have inspected the Network tab to see why your AJAX request is not working you would have seen the wrong url being used.
Long story short two things to remember from this question (the first being more important as it allows you to deduce the second):
Use FireBug
the Url property of the AjaxOptions allows you to override the url to be used when sending the AJAX request.
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