在ajax调用之后更新HTML表数据后输入选择器丢失

时间:2021-10-09 07:42:16

Question background:

问题背景:

I have an MVC4 project with a shopping cart as shown:

我有一个带购物车的MVC4项目如图所示:

在ajax调用之后更新HTML表数据后输入选择器丢失

This uses Touchspin.js to provide a way for users to update their cart Quanity of each item in the cart. The input contain selector to increment or decrement the amount:

这使用Touchspin.js为用户提供了一种方式来更新购物车中每件商品的购物车数量。输入包含增量或减量的选择器:

在ajax调用之后更新HTML表数据后输入选择器丢失

The issue:

问题:

If a user deletes an item from the cart I send the specified item ID through an ajax POST request to a method on the Cart Controller which in-turn deletes it from the cart items list. Once this is completed the item list is then returned to the Success function of the ajax call which builds up the html rows of the list items and then appends them to the cart Table.

如果用户从购物车中删除商品,我会通过ajax POST请求将指定的商品ID发送到购物车控制器上的方法,该方法又将其从购物车商品列表中删除。一旦完成,项目列表将返回到ajax调用的Success函数,该函数构建列表项的html行,然后将它们附加到购物车表。

The issue is I seem to be losing the Touchspin input selector HTML when the cart item table is rebuilt from the success call. It is using the same method when the page originally loads. Here an image displaying the incorrectly formatted HTML input with the red arrows denoting the missing selectors:

问题是,当从成功调用重建购物车项目表时,我似乎丢失了Touchspin输入选择器HTML。页面最初加载时使用相同的方法。这里的图像显示格式错误的HTML输入,红色箭头表示缺少的选择器:

在ajax调用之后更新HTML表数据后输入选择器丢失

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 is used to build up the rows of each item in the cart items list. This is append to the cart Table body.

AddRows用于构建购物车项目列表中每个项目的行。这是附加到购物车表主体。

<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.

Delete函数用于删除指定的购物车项目,然后在Success方法中使用AddRows方法重建购物车项目。

    $(".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 setup values.

TouchSpin输入选择器设置值。

<script>
    $("input[name='demo1']").TouchSpin({
        min: 1,
        max: 100,
        step: 1,
    });
</script>

2 个解决方案

#1


1  

You have to add Touchspin API to the input element with name demo1 every time you dynamically add it to the DOM.

每次将动态添加到DOM时,都必须将Touchspin API添加到名为demo1的input元素中。

There are various ways to bind API to dynamically loaded content

有多种方法可以将API绑定到动态加载的内容

Method 1

方法1

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

在将$ html附加到$('#Table1> tbody:last')之前,您可以在AddRows函数中调用demo1上的Touchspin

like your end of AddRows function should look like

喜欢你的AddRows函数的结尾应该是这样的

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

Method 2

方法2

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

您可以在$ .each函数之后的success1函数中调用demo1上的Touchspin。所以你的成功功能就变了

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 refactoring as Ste-fu mentioned in comment, so you can return 1 or 0(or some text to differentiate between some error or OK response) and if response is something signifying that the item is removed then you remove $row from your DOM , in that case your success function would become like this

但是,您的代码需要重构为注释中提到的Ste-fu,因此您可以返回1或0(或某些文本来区分某些错误或OK响应),如果响应是表示项目已被删除,则删除$ row从您的DOM,在这种情况下,您的成功函数将变为这样

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

#2


1  

you should call the JS code that define TouchSpin again everytime you add new HTML content.

每次添加新的HTML内容时,都应该再次调用定义TouchSpin的JS代码。

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

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

#1


1  

You have to add Touchspin API to the input element with name demo1 every time you dynamically add it to the DOM.

每次将动态添加到DOM时,都必须将Touchspin API添加到名为demo1的input元素中。

There are various ways to bind API to dynamically loaded content

有多种方法可以将API绑定到动态加载的内容

Method 1

方法1

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

在将$ html附加到$('#Table1> tbody:last')之前,您可以在AddRows函数中调用demo1上的Touchspin

like your end of AddRows function should look like

喜欢你的AddRows函数的结尾应该是这样的

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

Method 2

方法2

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

您可以在$ .each函数之后的success1函数中调用demo1上的Touchspin。所以你的成功功能就变了

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 refactoring as Ste-fu mentioned in comment, so you can return 1 or 0(or some text to differentiate between some error or OK response) and if response is something signifying that the item is removed then you remove $row from your DOM , in that case your success function would become like this

但是,您的代码需要重构为注释中提到的Ste-fu,因此您可以返回1或0(或某些文本来区分某些错误或OK响应),如果响应是表示项目已被删除,则删除$ row从您的DOM,在这种情况下,您的成功函数将变为这样

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

#2


1  

you should call the JS code that define TouchSpin again everytime you add new HTML content.

每次添加新的HTML内容时,都应该再次调用定义TouchSpin的JS代码。

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

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