【问题标题】:How to iterate through values of text boxes ,and send them to controller using ajax?如何遍历文本框的值,并使用 ajax 将它们发送到控制器?
【发布时间】:2016-12-11 07:11:42
【问题描述】:

我正在使用 asp.net mvc 开发购物车。我已经完成了购物车的完整功能,用户可以通过文本框删除产品或更新其数量。但我不喜欢购物车中每个产品右侧有 2 个额外链接的部分(更新数量和删除产品)。我可以删除产品链接,因为每个产品都有删除链接是有意义的。现在我只想拥有一个名为保存更改的按钮或链接。单击该按钮/链接时,我想从每个数量文本框中收集值,将其传递给控制器​​并执行其需要完成的操作并从控制器作为 json 对象返回。问题是我到目前为止只使用了几天的ajax,并且不知道如何从我的视图中的文本框中迭代/收集值并将它们发送到控制器。

这就是我的购物车的样子。

这是我的看法

@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="row-@Model.CartItems[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="CartItems_@(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);
        }

所以我正在查看一些教程并考虑使用&lt;input type="text"&gt; 字段而不是@html.TextBoxFor(model=&gt;model.CartItems[i].CartCount) 和$ajax() 来仅发布每个&lt;input&gt; 的recordID 和值...我可以为一个caritem 做到这一点唯一的名称/id 或类,但考虑到我有 CartItems 列表,我需要为每个 caritem 动态创建带有 for 语句的 &lt;input&gt; 数量字段。因此,当用户按下保存更改按钮时,它需要从每个输入字段中读取值并使用方法 UpdateCartQuantity 以及 recordID。对我来说主要问题是如何动态处理 &lt;input&gt; 的类/ID,因此每个都有唯一的 id 以及如何读取/发送该 recordID 和输入值。我也编辑了我的视图,现在我有 for 语句而不是你可以看到的 foreach。

【问题讨论】:

  • 你为什么不直接提交表单(你有什么理由想留在同一页面上吗?)。而且您不能使用foreach 循环为集合项生成表单控件。您需要一个 for 循环或自定义 EditorTemplate 以使 2 路模型投标工作 - 请参阅 this answer

标签: jquery asp.net ajax asp.net-mvc asp.net-mvc-3


【解决方案1】:
  1. jQuery 文本框的 focusout() 事件与 ajax 调用应该可以做到。
  2. aleksander 也有一个好观点。
  3. 您正在尝试生动地保存单个文本框对象状态。我看不出有什么用。除了你试图跟踪对象状态。毕竟他必须发布他的页面。

【讨论】:

    【解决方案2】:
    1. 为您的产品列表上课。
    2. 验证是用户输入的数字。
    3. 将价格设为只读。
    4. 使用 focusout() 事件和 jquery 来更新此视图的小计和总计。

    我认为这个功能是你正在寻找的。​​p>

    为什么代码比这更复杂。 在您的提交中,您需要 id 产品 id 和计数。此页面显示需要其他所有内容。

    【讨论】:

    • 你可以为“给你的产品列表上课”和 focusout() 输入一些示例代码吗?因为我是新手,这是我的第一个项目,也是第一次使用 asp.net 吗?
    【解决方案3】:

    只是猜测而已。有更好的方法,但这会给你一个想法。

    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 调用以使用产品 ID 和数量更新您的行数据库。因为产品数量是唯一的。返回一个 int 或 boolean 以显示给更新的用户(如果有)。您的 ajax 调用操作应该接受 productid 数量。如果需要,发送一些用户凭据,如果不需要它的帖子。

    1. focusout 页面会自动更新。
    2. 使用信息更新购物车数据库的 ajax 调用。
    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>
    

    给我post check code,如果可以的话,我想看看。希望这个代码块没问题。

    【讨论】:

    • 我做了一些修改,希望你现在对我的问题有更好的理解。我是编程新手,所以我很难解释我想要实现的目标。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-02
    • 1970-01-01
    • 2021-12-05
    • 2021-10-23
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多