2015-08-04 6 views
1

Прежде всего позвольте мне поблагодарить @Jasen, он провел 9 дней, помогая мне с проблемой, и это много значит для меня, что он взял его время, чтобы помочь мне. Именно с этим он помогал мне, но в последнюю секунду они решили, что хотят пойти с AJAX, так как контактная страница использует его, и удаление предметов из корзины использует его.jQuery AJAX событие только стрельба один раз

Позвольте мне перейти к моей проблеме, у меня есть представление (это MVC 5), что в цикле загружаются все продукты выбранной категории. Я хочу использовать jQuery nd AJAX для добавления элементов в корзину. Это отлично работает для первого элемента в списке при первом добавлении в корзину.

Я предполагаю, что моя проблема состоит в том, что все кнопки имеют идентификатор AddToCart и jQuery, то, как я его написал, не может решить, какую кнопку нажать.

Вот код для представления

@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"> &nbsp;&nbsp;&nbsp;@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>&nbsp;</div> 
            <div class="divQuantity">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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> 
} 

Может кто-то показать мне, что я делаю неправильно здесь, так что я могу получить эту работу?

EDIT # 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); 
    } 
}); 

Он работал прежде, чем сделать на стороне клиента изменения (предоставляется только один раз и только для первого элемента в списке), так как я не изменил код на стороне сервера, что могло бы пойти не так? EDIT # 2

Вот все, что в его entirity

@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"> &nbsp;&nbsp;&nbsp;@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>&nbsp;</div> 
            <div class="divQuantity">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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> 
} 

EDIT # 2

Вот код для AddToCartAJAX в OrdersController:

public ActionResult AddToCartAJAX(int id, int quantity, decimal price) 
{ 
    var cart = ShoppingCart.GetCart(this.HttpContext); 

    cart.AddToCart(id, quantity, price); 

    return RedirectToAction("Index"); 
} 

И AddToCart в ShoppingCrt.cs:

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; 
    } 
} 

Надежда, что помогает

+0

Он тот, кто помогал мне с другим вопросом. – PsychoCoder

+0

yes Я добавил AddToCart в класс кнопок lilke, которые вы предложили. – PsychoCoder

+0

и 'количество' для' @ Html.TextBoxFor (modelItem => item.Quantity'? Также 'td.find (". Количество "). Val()' и делают изменения в методе sucess и error для правильных селекторов – Satpal

ответ

3

Как вы создаете элементы в цикле, дублированные идентификаторы создаются. Это делает ваш HTML недействительным.

Идентификаторы в формате HTML должны быть уникальными., и это ожидаемое поведение.

Вы можете назначить общий класс, а затем использовать селектор классов. Здесь в примере я добавил 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" /> 

Script

$(".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"); 

Примечание: соответственно замените остальные селектор.

+0

Я внедрил ваши изменения в мой существующий код , но теперь, когда он попадает на мой вызов ajax, я получаю 500 (Внутренняя ошибка сервера), я проверял свои права, и они кажутся правильными. – PsychoCoder

+0

@PsychoCoder, это не имеет никакого отношения к разрешению и в соответствии с предложением, которое вы должны сделать много изменений для достижения результата и 500 означает, что что-то не так на стороне сервера. – Satpal

+0

Можете ли вы проверить мое редактирование, пожалуйста. Я знаю, что это должно быть что-то простое, что мне не хватает. – PsychoCoder

Смежные вопросы