Вложенные формы в ASP.NET MVC - PullRequest
       1

Вложенные формы в ASP.NET MVC

9 голосов
/ 13 октября 2009

У меня есть корзина, в которой выполняются следующие условия:

  • В корзине есть одна кнопка «Удалить» для каждого товара
  • В корзине есть одно редактируемое текстовое поле количества для каждого товара
  • Существует одна кнопка «Обновить» для всей корзины покупок

Идея состоит в том, что пользователь может изменить количества для каждого продукта в корзине и нажать "Обновить", чтобы зафиксировать изменения.

Как бы вы запрограммировали кнопку «Обновить» с помощью MVC? Вы бы обернули всю корзину для покупок в форму, которая отправляет обратно в себя, и каким-то образом найдите количественные значения в FormCollection? Проблема этого подхода заключается в том, что, поскольку каждая из кнопок «Удалить» живет в своих собственных формах, я теперь буду делать вложенные формы на странице, и я даже не уверен, что это разрешено.

        <% using (Html.BeginForm("Index", "Cart")) { %> 
        <table>
            <tr>
                <th>&nbsp;</th>
            </tr>
        <% foreach (var item in Model) { %>
            <tr>
                <td>
                    <input name="qty" type="text" value="<%=item.Quantity%>" maxlength="2" />
                    <% using (Html.BeginForm("RemoveOrderItem", "Cart")) { %>                       
                        <%= Html.Hidden("ShoppingCartItemID", item.ShoppingCartItemID) %>
                        <input name="add" type="submit" value="Remove" />
                    <%} %>
                </td>
            </tr>
        <% } %>
        </table>

        <input name="update" type="submit" value="Update" />
        <%} %>  

Как бы я включил нижний ввод в эту форму?

Ответы [ 4 ]

9 голосов
/ 13 октября 2009

Вложенные формы явно не поддерживаются в HTML.

Однако вы можете иметь несколько форм, это разрешено. Оберните каждый продукт в отдельную форму, добавьте специфичный для продукта параметр к каждому URL-адресу публикации формы, чтобы в соответствующем действии контроллера вы знали, какой продукт необходимо обновить.

Примерно так:

<form action="/update/21342345">
</form>

Как бы я включил нижний ввод в эту форму?

Два варианта:

  1. Дайте каждой форме собственную кнопку отправки. Назовите это как «Обновить этот продукт». В параметре url вы укажете, какой из них обновить.
  2. Оберните созданную вами таблицу вместе с кнопкой отправки в одну форму. После отправки вам нужно будет обновить все продукты, содержащиеся в форме. или как-то определить, какие из них были изменения, и только обновить их.

Совет относится к обеим кнопкам - отправить и удалить. Вы можете указать задачу в URL-адресе сообщения, например:

action="/update/21342345"

или

action="/delete/21342345"
4 голосов
/ 13 октября 2009

Мы сделали это в нашем проекте, используя отдельную форму для удаления и совершенно другую форму для обновления. Они оба выполняют разные действия POST в CartController.

ОБНОВЛЕНИЕ: приведенный пример (в необработанном HTML):

<form action="/cart/updatequantity" method="post"> 
    <input type="hidden" name="ProductSku" value="ABC-123" /> 
    <input name="quantity" class="quantity" size="2" maxlength="2" type="text" value="1" /> 
    <input type="submit" value="Update" /> 
</form> 

<form action="/cart/removeitem" method="post"> 
    <input type="hidden" name="productSku" value="ABC-123" /> 
    <input type="submit" value="Remove" /> 
</form> 
2 голосов
/ 13 октября 2009

Я использую jQuery в аналогичной ситуации. Кнопка «Удалить» вызывает метод post (), и в случае успеха элемент div этого продукта удаляется со страницы (метод remove ()). Обновление можно отправить в нормальной форме. Вы также можете использовать jQuery для программирования метода обновления ajax, а затем динамически загружать корзину покупок без необходимости перезагружать всю страницу (с помощью метода $ (). html (), вызываемого в обратном вызове post ()).

Удалить может выглядеть так:

onclick = "if (подтвердите ('Пожалуйста, подтвердите.')) $ .Post ('/ Корзина / Удалить / 63', {}, функция (данные) { if (data == 'ok') {$ ('# cart-element-63'). remove ()) ";

1 голос
/ 07 июня 2011

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

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

<input class="btnRemove" name="remove" type="image" value="@item.ProductId" />

Каждое текстовое поле Количество имеет префикс "qnty-" с уникальным ключом для этого элемента корзины.

<input id="qnty-@item.ProductId" name="qnty-@item.ProductId" type="text" value="@item.Quantity" class="cartListQty" />

После того, как мое действие было отправлено в цикл через FormCollection. Если имя «удалить», я удаляю этот уникальный ключ из корзины. Если имя начинается с «qnty-», я получаю оставшуюся часть имени (уникальный ключ элемента корзины) и подгоняю количество элементов к значению текстового поля.

[HttpPost]
public ActionResult Index(FormCollection collection)
{
Cart myCart = cartRepo.LoadCart();
foreach (string item in collection.AllKeys)
{
    if (item.StartsWith("qnty-"))
    {
    int productId = Convert.ToInt32(item.Substring(5));
    // Adjust quantity
    }
    if (item == "remove") // Remove item from cart
}
cartRepo.Save();
return RedirectToAction("Index");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...