Input selectors lost after HTML table data are updated after ajax call

Question:

I have an MVC4 project with a shopping cart:

enter image description here

This uses Touchspin.js to provide users with the ability to update their Quanity cart for each item in the cart. The input contains a selector to increase or decrease the number of:

enter image description here

Problem:

If the user removes the item from the recycle bin, I send the specified item identifier via the POST ajax request to the recycle controller method, which in turn removes it from the recycle list. Once this is completed, the list of items is then returned to the Success function of the ajax call, which builds the html strings of the list items and then adds them to the trash table.

The problem is that I seem to lose the TouchSpin HTML input selector when the basket item table is rebuilt from a success call. It uses the same method when the page initially loads. Here's an image showing an incorrectly formatted HTML input with red arrows indicating the missing selector:

enter image description here

The code:

  @{ Layout = "~/Views/Shared/MasterLayout.cshtml"; } <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script> <script src="~/Scripts/jquery.js"></script> <script src="~/Scripts/bootstrap.js"></script> <script src="~/Scripts/jquery.blImageCenter.js"></script> <script src="~/Scripts/bootstrap.touchspin.js"></script> <script src="~/Scripts/mimity.js"></script> <h2>Cart</h2> <br /> <table id="Table1" class="table table TableSection"> <thead> <tr> <td style="display:none;">id</td> <td></td> <td class="TableCell"><b>Item</b></td> <td class="TableCell"><b>Brand</b></td> <td class="TableCell"><b>Unit Price</b></td> <td class="TableCell"><b>Quantity</b></td> <td></td> </tr> </thead> <tbody></tbody> </table> <input class="btn btn-success btn-block updateCart" type="button" value="Update Cart" /> @Html.Partial("_ViewCartContents") <div class="PaymentButtons"> <div class="row"> <div class="col-sm-4"> <input class="btn btn-success btn-block updateCart" type="button" value="PayPal" onclick="location.href='@Url.Action("Index", "PayPalExpress")'" /> </div> <div class="col-sm-4 pull-left"> <input class="btn btn-success btn-block updateCart" type="button" value="Card Payment" onclick="location.href='@Url.Action("ShippingDetails", "PayPalDirectPayment")'" /> </div> </div> </div> </script> 

AddRows used to create rows for each item in the list of items in the cart. This is added to the body of the cart.

 <script type="text/javascript"> var AddRows = function (productId, productImage, productName, productBrand, productPrice, productQty) { var button = '<input class="btn btn-primary btn-block deleteItem" type="button" value="Remove"/>'; var image = '<img src="/Images/' + productImage + '" class="productCartImage"/>'; var selectors = '<input id="demo1" type="text" value="' + productQty + '" name="demo1">'; var $html = $('<tr class="item">' + '<td class="prodId" style="display:none;">' + productId + '</td>' + '<td class="prodImage hidden-xs">' + image + '</td>' + '<td class="prodName">' + productName + '</td>' + '<td class="prodBrand">' + productBrand + '</td>' + '<td class="prodPrice"> £' + productPrice + '</td>' + '<td class="prodQty TableCell">' + selectors + '</td>' + '<td>' + button + '</td>' + '</tr>'); $('#Table1 > tbody:last').append($html); }; </script> @foreach (var cartItem in (List<LoginTest.Models.CartItem>)ViewBag.Data) { <script> var cartItemId = '@cartItem.CartItemId'; var cartImage = '@cartItem.CartItemImage'; var cartItemName = '@cartItem.CartItemName'; var cartBrand = '@cartItem.CartItemBrand'; var cartItemPrice = '@cartItem.CartItemPrice'; var cartItemCartItemQty = '@cartItem.CartItemQty'; AddRows(cartItemId, cartImage, cartItemName, cartBrand, cartItemPrice, cartItemCartItemQty); </script> } 

The Delete function is used to delete the specified cart item, then in the Success method rebuild the cart items using the AddRows method.

  $(".deleteItem").click(function () { var $row = $(this).closest("tr"); var $text = $row.find(".prodId").text(); $.ajax({ url: '@Url.Action("RemoveCartItem")', type: 'POST', data: { "id": $text }, success: function (cartItems) { $('#Table1 > tbody:last').empty(); $.each(cartItems.cartList, function (i, item) { AddRows(item.CartItemId, item.CartItemImage, item.CartItemName, item.CartItemBrand, item.CartItemPrice, item.CartItemQty); }); } }); }); </script> 

TouchSpin Input Selector Settings

 <script> $("input[name='demo1']").TouchSpin({ min: 1, max: 100, step: 1, }); </script> 
+7
javascript jquery html ajax
source share
2 answers

You must add the Touchspin API to the input element called demo1 every time you dynamically add it to the DOM .

There are various ways to bind APIs to dynamically loaded content.

Method 1

You can call Touchspin on the demo1 function in AddRows just before adding $html to $('#Table1 > tbody:last')

how your end of the AddRows function should look like

  /*....Addrows funcion....*/ $html.find("input[name='demo1']").TouchSpin({ min: 1, max: 100, step: 1, }); $('#Table1 > tbody:last').append($html); }; 

Method 2

You can call Touchspin on demo1 in the success function right after the $.each function. So your success function becomes

 success: function (cartItems) { $('#Table1 > tbody:last').empty(); $.each(cartItems.cartList, function (i, item) { AddRows(item.CartItemId, item.CartItemImage, item.CartItemName, item.CartItemBrand, item.CartItemPrice, item.CartItemQty); }); $("input[name='demo1']").TouchSpin({ min: 1, max: 100, step: 1, }); } 

However, your code needs to be refactored , as pointed out by Ste-fu's comment, so you can return 1 or 0 (or some text to distinguish between some error or OK response) and if the answer is something that means the element has been deleted, you delete $row from your DOM , in which case your success function will look like

 success: function (status) { if(status==1)//means that item is removed from database then $row.remove(); //remove the closest row to the clicked element } 
+1
source share

you must call the JS code that defines TouchSpin again every time you add new HTML content.

$ (NewContentSelector). find ("input [name = 'demo1']"). TouchSpin ({min: 1, max: 100, step 1,});

+1
source share

All Articles