首先让我感谢@Jasen,他花了 9 天的时间帮助我解决一个问题,他花时间帮助我对我来说意义重大。他正在帮助我解决这个问题,但在最后一刻他们决定使用 AJAX,因为联系页面使用它,从购物车中删除商品也使用它。
让我谈谈我的问题,我有一个 View (这是 MVC 5),它循环加载所选类别的所有产品。我想使用 jQuery 和 AJAX 将商品添加到购物车。这对于第一次添加到购物车时列表中的第一项非常有用。
我想我的问题是所有按钮都有一个 id AddToCart 和 jQuery,我编写的方式无法决定单击哪个按钮。
这是 View 的代码
@model IEnumerable<AccessorizeForLess.ViewModels.DisplayProductsViewModel>
@{
ViewBag.Title = "Products > Necklaces";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<link href="~/Content/Site.css" rel="stylesheet" />
<link href="~/Content/jquery.fancybox.css?v=2.1.5" rel="stylesheet" />
<link href="~/Content/jquery.fancybox-buttons.css?v=1.0.5" rel="stylesheet" />
<link href="~/Content/jquery.fancybox-thumbs.css?v=1.0.7" rel="stylesheet" />
<h2>Products > Necklaces</h2>
<div id="update-message"></div>
<p class="button">
@Html.ActionLink("Create New", "Create")
</p>
@*@using (Html.BeginForm("AddToCart", "Orders", FormMethod.Post))*@
{
<div id="container">
<div id="sending" style="display:none;"><img src="~/Content/ajax-loader.gif" /></div>
<div style="color:red" id="ItemAdded"></div>
<div class="scroll">
@foreach (var item in Model)
{
<div class="scroll2">
<div class="itemcontainer">
<table>
<tr>
<td id="@item.Id" class="divId">
<div class="DetailsLink" id="@item.Id"> @Html.ActionLink(@item.Name, "Details", new { id = item.Id })</div>
<br />
<div id="@item.Id"></div>
<div class="divPrice" id="@item.Price">@Html.DisplayFor(modelItem => item.Price)</div>
<div class="divImg"><a class="fancybox-thumbs" href="@item.Image.ImagePath" title="@item.Image.AltText" data-fancybox-group="thumb"><img src="@item.Image.ImagePath" alt="@item.Image.AltText" title="@item.Image.AltText" /></a></div>
<div> </div>
<div class="divQuantity"> Quantity: @Html.TextBoxFor(modelItem => item.Quantity, new { @id = "quantity", @style = "width:50px;", @class = "formTextBox" })</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" value="AddToCart" class="btn btn-default" id="AddToCart" />
</div>
</div>
<div style="height:15px;"></div>
</td>
</tr>
</table>
</div>
</div>
}
<div class="button">@Html.ActionLink("Back To Categories","Categories")</div>
<br />
</div>
</div>
@*}*@
这是我的 jQuery 代码:
@section scripts {
<script src="~/Scripts/jQuery-jScroll.js"></script>
<script src="~/Scripts/jquery.fancybox.js?v=2.1.5"></script>
<script src="~/Scripts/jquery.fancybox-thumbs.js?v=1.0.7"></script>
<script src="~/Scripts/jquery.fancybox-buttons.js?v=1.0.5"></script>
<script type="text/javascript">
//$(function () {
// $('.scroll').jscroll({
// autoTrigger: true
// });
$('.fancybox-thumbs').fancybox({
prevEffect: 'none',
nextEffect: 'none',
closeBtn: true,
arrows: false,
nextClick: false
});
// Document.ready -> link up remove event handler
$("#AddToCart").click(function () {
//first disable the button to prevent double clicks
$("#AddToCart").attr("disbled", true);
$("#AddToCart").prop("value", "Adding...");
$("#ItemAdded").text("");
//now show the loading gif
$("#sending").css("display", "block");
// Get our values
var price = parseFloat($(".divPrice").attr("id"));
var quantity = parseInt($("#quantity").val());
var id = parseInt($(".divId").attr("id"));
$.ajax({
url: "@Url.Action("AddToCartAJAX", "Orders")",
type: "POST",
data: { "id": id, "quantity": quantity, "price": price },
//if successful
success: function (data) {
successfulCall()
},
error: function (data) {
alert(data.Message);
}
});
function successfulCall() {
//enable the send button
$("#AddToCart").attr("disbled", false);
//hide the sending gif
$("#sending").css("display", "none");
//change the text on the button back to Send
$("#AddToCart").prop("value", "Add to Cart");
//display the successful message
$("#ItemAdded").text("Your item has been added to your order.");
//clear out all the values
$("input#quantity").val("0");
}
function errorCall() {
$("#AddToCart").attr("disbled", false);
$("#sending").css("display", "none");
$("#AddtoCart").prop("value", "Add to Cart");
$("#ItemAdded").text(data.message);
}
//alert('Clicked!');
});
//s});
</script>
}
有人可以告诉我我在这里做错了什么,以便我可以让它工作吗?
编辑#1
这里是更新后的 jQuery 代码:
$(".AddToCart").click(function () {
//first disable the button to prevent double clicks
$(this).prop("disbled", true).prop("value", "Adding...");
$("#sending").css("display", "block");
var td = $(this).closest('td')
//traverse DOM and find relevant element
var price = parseFloat(td.find(".divPrice").prop("id")),
quantity = parseInt(td.find("#quantity").val()),
id = parseInt(td.find(".divId").prop("id"));
$.ajax({
url: "@Url.Action("AddToCartAJAX", "Orders")",
type: "POST",
data: { "id": id, "quantity": quantity, "price": price },
//if successful
success: function (data) {
successfulCall()
},
error: function (data) {
errorCall(data);
}
});
它在进行客户端更改之前就起作用了(仅授予一次并且仅针对列表中的第一项),因为我没有更改服务器端代码,可能会出现什么问题? 编辑#2
这就是全部内容
@model IEnumerable<AccessorizeForLess.ViewModels.DisplayProductsViewModel>
@{
ViewBag.Title = "Products > Necklaces";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<link href="~/Content/Site.css" rel="stylesheet" />
<link href="~/Content/jquery.fancybox.css?v=2.1.5" rel="stylesheet" />
<link href="~/Content/jquery.fancybox-buttons.css?v=1.0.5" rel="stylesheet" />
<link href="~/Content/jquery.fancybox-thumbs.css?v=1.0.7" rel="stylesheet" />
<h2>Products > Necklaces</h2>
<div id="update-message"></div>
<p class="button">
@Html.ActionLink("Create New", "Create")
</p>
@*@using (Html.BeginForm("AddToCart", "Orders", FormMethod.Post))*@
{
<div id="container">
<div id="sending" style="display:none;"><img src="~/Content/ajax-loader.gif" /></div>
<div style="color:red" id="ItemAdded"></div>
<div class="scroll">
@foreach (var item in Model)
{
<div class="scroll2">
<div class="itemcontainer">
<table>
<tr>
<td id="@item.Id" class="divId">
<div class="DetailsLink" id="@item.Id"> @Html.ActionLink(@item.Name, "Details", new { id = item.Id })</div>
<br />
<div id="@item.Id"></div>
<div class="divPrice" id="@item.Price">@Html.DisplayFor(modelItem => item.Price)</div>
<div class="divImg"><a class="fancybox-thumbs" href="@item.Image.ImagePath" title="@item.Image.AltText" data-fancybox-group="thumb"><img src="@item.Image.ImagePath" alt="@item.Image.AltText" title="@item.Image.AltText" /></a></div>
<div> </div>
<div class="divQuantity"> Quantity: @Html.TextBoxFor(modelItem => item.Quantity, new { @style = "width:50px;", @class = "formTextBox quantity" })</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" value="AddToCart" class="btn btn-default AddToCart" />
</div>
</div>
<div style="height:15px;"></div>
</td>
</tr>
</table>
</div>
</div>
}
<div class="button">@Html.ActionLink("Back To Categories","Categories")</div>
<br />
</div>
</div>
@*}*@
@section scripts {
<script src="~/Scripts/jQuery-jScroll.js"></script>
<script src="~/Scripts/jquery.fancybox.js?v=2.1.5"></script>
<script src="~/Scripts/jquery.fancybox-thumbs.js?v=1.0.7"></script>
<script src="~/Scripts/jquery.fancybox-buttons.js?v=1.0.5"></script>
<script type="text/javascript">
//$(function () {
// $('.scroll').jscroll({
// autoTrigger: true
// });
$('.fancybox-thumbs').fancybox({
prevEffect: 'none',
nextEffect: 'none',
closeBtn: true,
arrows: false,
nextClick: false
});
// Document.ready -> link up remove event handler
$(".AddToCart").click(function () {
//first disable the button to prevent double clicks
$(this).prop("disbled", true).prop("value", "Adding...");
$("#sending").css("display", "block");
var td = $(this).closest('td')
//traverse DOM and find relevant element
var price = parseFloat(td.find(".divPrice").prop("id")),
quantity = parseInt(td.find(".quantity").val()),
id = parseInt(td.find(".divId").prop("id"));
$.ajax({
url: "@Url.Action("AddToCartAJAX", "Orders")",
type: "POST",
data: { "id": id, "quantity": quantity, "price": price },
//if successful
success: function (data) {
successfulCall()
},
error: function (data) {
errorCall(data);
}
});
function successfulCall() {
//enable the send button
$(this).prop("disbled", false).prop("value", "Add To Cart");
//hide the sending gif
$("#sending").css("display", "none");
//display the successful message
$("#ItemAdded").text("Your item has been added to your order.");
//clear out all the values
$("input#quantity").val("0");
}
function errorCall(data) {
$(this).prop("disbled", false).prop("value", "Add To Cart");
$("#sending").css("display", "none");
$("#ItemAdded").text(data.message);
}
//alert('Clicked!');
});
//s});
</script>
}
编辑#2
以下是 OrdersController 中 AddToCartAJAX 的代码:
public ActionResult AddToCartAJAX(int id, int quantity, decimal price)
{
var cart = ShoppingCart.GetCart(this.HttpContext);
cart.AddToCart(id, quantity, price);
return RedirectToAction("Index");
}
以及 ShoppingCrt.cs 中的 AddToCart:
public void AddToCart(int id, int quantity, decimal price)
{
// Get the matching cart and product instances
var order = entities.Orders.FirstOrDefault(
c => c.OrderGUID == ShoppingCartId
&& c.OrderItems.Where(p => p.ProductId == id).FirstOrDefault().ProductId == id);
if (order == null)
{
// Create a new order since one doesn't already exist
order = new Order
{
InvoiceNumber = Guid.NewGuid().ToString(),
OrderDate = DateTime.Now,
OrderGUID = ShoppingCartId,
IsShipped = false
};
entities.Orders.Add(order);
// Save changes
entities.SaveChanges();
//add the OrderItem for the new order
OrderItem oi = new OrderItem()
{
OrderId = order.OrderId,
OrderGUID = ShoppingCartId,
ProductId = id,
ProductQuantity = quantity,
ProductPrice = price
};
entities.OrderItems.Add(oi);
entities.SaveChanges();
}
else
{
// If the item does exist in the cart,
// then add one to the quantity
order.OrderItems.Where(p => p.ProductId == id).FirstOrDefault().ProductQuantity += quantity;
}
}
希望有帮助
最佳答案
当您在循环中创建元素时,会创建重复的标识符。这会使您的 HTML 无效。
HTML 中的标识符必须是唯一的。这是预期的行为。
您可以分配一个公共(public)类,然后可以使用类选择器。在示例中,我已将 AddToCart
CSS 类添加到按钮。
HTML
@Html.TextBoxFor(modelItem => item.Quantity, new {@style = "width:50px;", @class = "formTextBox quantity" })
<input type="button" value="AddToCart" class="btn btn-default AddToCart" />
脚本
$(".AddToCart").click(function() {
$(this).prop("disabled", true)
.prop("value", "Adding...");
var td = $(this).closest('td.divId')
//traverse DOM and find relevant element
var price = parseFloat(td.find(".divPrice").prop("id")),
quantity = parseInt(td.find(".quantity").val()),
id = parseInt(td.find(".divId").prop("id"));
//Your ajax call
});
我还建议您使用 data-*
前缀的自定义属性来存储任意数据。
<div class="divPrice" data-price="@item.Price"></div>
可以使用.data()
获取,它还将值转换为适当的类型。
var price = $('.divPrice').data("price");
注意:相应地更改其余选择器。
关于jQuery AJAX 事件仅触发一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31802192/