2016-08-05 4 views
0

Я работаю над корзиной покупок, используя asp.net mvc. Я сделал полную функциональность корзины покупок, где пользователь может удалить продукт или обновить его количество через текстовое поле. Но мне не нравится часть, где у меня есть две дополнительные ссылки с правой стороны каждого продукта в корзине (количество обновлений и удаление продукта). Я прекрасно разбираюсь с ссылками на продукты, потому что имеет смысл удалить ссылку для каждого продукта. Теперь я хочу иметь только одну кнопку или ссылку с именем save changes. Нажав на эту кнопку/ссылку, я хочу собирать значения из каждого текстового поля количества, передать ее контроллеру и выполнить то, что нужно сделать, и вернуть его как объект json из контроллера. Проблема в том, что я использую ajax только в течение нескольких дней и не знаю, как итерации/собирать значения из текстовых полей в моем представлении и отправлять их контроллеру.Как перебирать значения текстовых полей и отправлять их контроллеру с помощью ajax?

Как выглядит моя корзина покупок. enter image description here

Это мой взгляд

@model OnlineShop.ViewModels.ShopingCartViewModel 
.... 
<p class="button"> 
    @Html.ActionLink("Checkout >>", "AddressAndPayment", "Checkout") 
</p> 

    <table class="table-bordered"> 
    <tr> 
     headers 
    </tr> 

    @for (int i = 0; i < Model.CartItems.Count; i++) 
    { 


     <tr id="[email protected][i].RecordID"> 
      <td> 
       <img src="@Url.Content(Model.CartItems[i].Product.ProductImg)" class="img-responsive" style="width:60px;height:60px;padding:5px;"/> 
      </td> 
      @*need to be done later*@ 
      <td> 

       @Html.ActionLink(Model.CartItems[i].Product.ProductName, "Details", "Store", new{id =Model.CartItems[i].ProductID}, null) 
      </td> 
      <td> 
       @Model.CartItems[i].Product.ProductPrice 
      </td> 
      <td> 
       @Html.TextBoxFor(model=>model.CartItems[i].CartCount,new { style="width:60px;text-align:center;"}) 
      </td> 
      <td> 
       <a href="#" class="UpdateLink" data-id="@Model.CartItems[i].RecordID" txt-id="[email protected](i)__CartCount"> 
        Update Quantity 

       </a>&nbsp;|&nbsp; 
      </td> 
      <td> 
       <a href="#" class="RemoveLink" data-id="@Model.CartItems[i].RecordID"> 
        Remove from 
        cart 
       </a> 
      </td> 
     </tr> 


    } 

    <tr> 
     <td> 
     </td> 
     <td></td> 
     <td></td> 
     <td></td> 
     <td align="center"> <b>Total</b></td> 

     <td id="cart-total" align="center"> 
      <b> @Model.CartTotal</b> 
     </td> 
    </tr> 
</table> 
</div> 

Сценарии

@section scripts { 
<script type="text/javascript"> 
    $(function() { 
     // Document.ready -> link up remove event handler 
     $(".RemoveLink").click(function() { 
      // Get the id from the link 
      var recordToDelete = $(this).attr("data-id"); 
      if (recordToDelete != '') { 
       // Perform the ajax post 
       $.post("/ShopingCart/RemoveFromCart", { "id": recordToDelete }, function (data) { 
        // Successful requests get here 
        // Update the page elements 
        if (data.ItemCount == 0) { 
         $('#row-' + data.DeleteID).fadeOut('slow'); 
        } else { 
         $('#item-count-' + data.DeleteID).text(data.ItemCount); 
        } 
        $('#cart-total').text(data.CartTotal); 
        $('#update-message').text(data.Message); 
        $('#cart-status').text('Cart (' + data.CartCount + ')'); 
       }); 
      } 
     }); 
    }); 
    $(function() { 
     // Document.ready -> link up remove event handler 
     $(".UpdateLink").click(function() { 
      // Get the id from the link 
      var recordToUpdate = $(this).attr("data-id"); 
      var countToUpdate=$("#" + $(this).attr("txt-id")).val(); 
      if (recordToUpdate != '') { 
       // Perform the ajax post 
       $.post("/ShopingCart/UpdateCartQuantity", { "id": recordToUpdate, "cartCount": countToUpdate}, function (data) { 
        // Successful requests get here 
        // Update the page elements 
        if (data.ItemCount == 0) { 
         $('#row-' + data.DeleteID).fadeOut('slow'); 
        } else { 
         $('#item-count-' + data.DeleteID).text(data.ItemCount); 
        } 
        $('#cart-total').text(data.CartTotal); 
        $('#update-message').text(data.Message); 
        $('#cart-status').text('Cart (' + data.CartCount + ')'); 
       }); 
      } 
     }); 
    }); 
    function handleUpdate() { 
     // Load and deserialize the returned JSON data 
     var json = context.get_data(); 
     var data = Sys.Serialization.JavaScriptSerializer.deserialize(json); 
     // Update the page elements 
     if (data.ItemCount == 0) { 
      $('#row-' + data.DeleteID).fadeOut('slow'); 
     } else { 
      $('#item-count-' + data.DeleteID).text(data.ItemCount); 
     } 
     $('#cart-total').text(data.CartTotal); 
     $('#update-message').text(data.Message); 
     $('#cart-status').text('Cart (' + data.CartCount + ')'); 
    } 
</script> 
} 

Спасибо за тяжелую работу, но меня смущает еще больше :) ... Я буду стараться лучше объясните, чего я пытаюсь достичь ... это мой метод управления

[HttpPost] 
     public ActionResult UpdateCartQuantity(int id , int cartCount) 
     { 
      var cart = ShopingCart.GetCart(this.HttpContext); 

      string productName = storeDB.Carts.Single(
       item => item.RecordID == id).Product.ProductName; 

      Product product = storeDB.Carts.Single(
       item => item.RecordID == id).Product; 

      int oldCount = (int)storeDB.Carts.Single(
       item => item.RecordID == id).CartCount; 

      int itemCount = 0; 
      if (oldCount==cartCount) 
      { 
       itemCount = oldCount; 
      } 
      else if (cartCount>oldCount) 
      { 
       itemCount = oldCount; 
       int sub = cartCount-oldCount; 
       for (int i = 0; i < sub; i++) 
       { 
        cart.AddToCart(product); 
        itemCount++; 
       } 
      } 
      else 
      { 

       itemCount = (int)cart.UpdateCartCount(id, cartCount); 

      } 
      var results = new ShopingCartRemoveViewModel 
      { 
       Message = Server.HtmlEncode(productName) + 
       " has quantity updated.", 
       CartTotal = cart.GetTotal(), 
       CartCount = (int)cart.GetCount(), 
       ItemCount = itemCount, 
       DeleteID = id 
      }; 


      return Json(results); 
     } 

Так я смотрел на некоторые учебники и думал использовать <input type="text"> поле вместо @html.TextBoxFor(model=>model.CartItems[i].CartCount) и $ajax() размещать только RecordId и значение каждого из <input> ... Я мог бы сделать это возможно для одного cartitem с уникальным именем/ID или класса, но с учетом что у меня есть список CartItems, мне нужно динамически создавать поля количества полей <input> с инструкцией для каждого картотека. Поэтому, когда пользователь нажимает кнопку сохранения изменений, ему нужно считывать значения из каждого поля ввода и обрабатывать с помощью метода UpdateCartQuantity вместе с recordID. Основная проблема для меня заключается в том, как динамически обрабатывать классы/идентификаторы этого <input>, поэтому каждый имеет уникальный идентификатор и как читать/отправлять этот идентификатор записи и вводимое значение. Также я отредактировал мой взгляд немного теперь, у меня есть для оператора вместо foreach, как вы можете видеть.

+0

Почему бы вам не просто отправить форму (есть ли причина, по которой вы хотите остаться на одной странице?). И вы не можете использовать цикл foreach' для создания элементов управления формой для элементов коллекции. Вам нужен циферблат 'for' или пользовательский' EditorTemplate' для 2-сторонней модели, ожидающей работы - см. [Этот ответ] (http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943 # 30094943) –

ответ

0
  1. событие фокуса jQuery textbox() с вызовом ajax должно это сделать.
  2. Александер также имеет хороший смысл.
  3. u r пытаясь сохранить индивидуальное состояние объекта текстового поля. Я не вижу использования для этого. за исключением того, что вы пытаетесь отслеживать состояние объектов. ведь он должен опубликовать свою страницу.
0
  1. дать класс вашему списку товаров.
  2. подтвердите номер введен пользователь ввод.
  3. сделать цену только для чтения.
  4. использовать событие focusout() и jquery для обновления промежуточного итога и всего этого представления.

Я думаю, что эта функциональность - это то, что вы ищете.

Почему код более сложный, чем этот. в вашем подписях u необходимо идентификатор id продукта и счет. для этого отображения страницы используется все остальное.

+0

Может ли вы ввести код примера для «дать класс вашему списку продуктов» и focusout(). Поскольку я новичок, это мой первый проект, а также первый asp.net use? –

0

Просто предположим, что все. там лучшие способы, но это даст вам идею.

public class Product 
    { 
     //unique 
     public int Id 
     { 
      get; 
      set; 
     } 
     public String Name 
     { 
      get; 
      set; 
     } 
     public Decimal Price 
     { 
      get; 
      set; 
     } 
     public Int32 Quantity 
     { 
      get; 
      set; 
     } 

     public Decimal SubTotal 
     { 
      get 
      { 
       return Price * Quantity; 
      } 
     } 

    } 

public class ProductList 
    { 
     public List<Product> productList = new List<Product> 
     { 
      new Product{Id=1, Name="Product 1", Quantity=4, Price=100}, 
      new Product{Id=2,Name="Product 2", Quantity=3, Price=200}, 
      new Product{Id=3,Name="Product 3", Quantity=2, Price=300}, 
      new Product{Id=4,Name="Product 4", Quantity=1, Price=400} 
     }; 

     public Decimal Total 
     { 
      get 
      { 
       Decimal total = 0M; 
       foreach(var item in productList) 
       { 
        total += item. SubTotal; 
       } 

       return total; 
      } 
     } 

    } 
    <script type="text/javascript"> 
     function UpdateSubANdTotal(price, quantity, subid) { 
      $(subid).html($(quantity).html() * $(price).prop("value")); 

      var elems = document.getElementsByClassName('subtotal'); 
      var tTotal = 0; 
      for (var i = 0; i < elems.length; i++) { 
       if (typeof elems[i].innerHTML !== null) { 
        tTotal = Number(tTotal) + Number(elems[i].innerHTML); 
       } 
      } 
      $('#ABTotal').text(tTotal); 

// как у обновили страницу, над кодом. // сделайте вызов ajax здесь, чтобы обновить db строки с идентификатором и количеством продукта. поскольку количество продукта уникально. return int или boolean для отображения пользователю обновленного, если таковые имеются. ваше действие по вызову ajax должно принимать количество продуктов. при необходимости, отправить некоторые учетные данные пользователя, если его сообщение не требуется.

  1. на странице фокуса обновляется автоматически.
  2. ajax звонок для обновления cart db с информацией.
  3. отображение обновлено для пользователя.
  4. если пользователь нажимает кнопку отправки. после действия будет обрабатывать корзины товаров и проверяет процесс продолжения ...
  5. если и хотят Ajax вызов может отправить весь список (корзина пуста) каждый раз, когда пользователь делает изменения, ваш выбор ...

код выше и это должно быть хорошо.

 } 
    </script> 

    <div class=""> 
     @foreach(var item in Model.productList) 
     { 
      String priceId = "M" + item.Id.ToString(); 
      String subTotId = "S" + item.Id.ToString(); 
      String QuanId = "Q" + item. Id. ToString(); 

      <div class=""> 
       <label >@item.Name</label> 
       <input name="pname[]" id="@priceId" type="text" value="@item.Price" onblur="UpdateSubANdTotal(@priceId, @QuanId, @subTotId)" /> 
       <label id="@QuanId">@item.Quantity</label> 
       <label class="subtotal" id="@subTotId">@item.SubTotal</label> 
      </div> 
     } 
    </div> 

    <label id="ABTotal">@Model.Total</label> 

дайте мне код чека, если вы можете, я хотел бы взглянуть. надеюсь, что этот блок кода в порядке.

+0

Я сделал несколько исправлений, надеюсь, что у вас есть лучшее понимание моего вопроса сейчас. Я новичок в программировании, поэтому мне трудно объяснить, чего я хочу достичь. –