创建在运行时增长的动态表单 [英] Create dynamic forms that grow at run time

查看:70
本文介绍了创建在运行时增长的动态表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在MVC应用程序内部的asp.net核心中工作.我正在使用根据模型创建视图和控制器的脚手架功能.下面是我正在使用的模型:

I'm working in asp.net core inside a MVC application. I'm using the scaffolding feature that creates the views and controller based on a model. Below is the model that i'm using:

class ShoppingList
{
    public int ShoppingListId { get; set; }
    public string Name { get; set; }
    public List<string> ListItems { get; set; }            
}

通过视图显示给用户的表单仅显示名称"字段.我希望表单能够显示列表项的字段,然后,如果用户要添加另一个列表项,则可以单击按钮以添加另一个字段.他们在运行时决定要添加多少购物清单项目.

The form that displays to the user via the view only displays the field for Name. I would like the form to be able to show a field for a list item, and then if the user wants to add another list item they can hit a button to add another field to do so. They at run time decide how many shopping list items they want to add.

这是我使用的剃刀cshtml表单:

Here is the razor cshtml form i'm using:

<form asp-action="Create">
     <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
           <label asp-for="Name" class="control-label"></label>
           <input asp-for="Name" class="form-control" />
           <span asp-validation-for="Name" class="text-danger"></span>
        </div>
     <div class="form-group">
     <input type="submit" value="Create" class="btn btn-default" />
     </div>
</form>

有没有简单的方法可以做到这一点?我不想对数字进行硬编码.

Is there an easy way to do this? I don't want to have to hard code a number.

推荐答案

如果要允许用户在客户端添加新的表单元素,则需要使用javascript用想要的新元素来更新DOM.添加.要列出现有项目,您可以使用编辑器模板.混合这两个将为您提供动态形式.下面是一个基本的实现.

If you want to allow the user to add a new form element on the client side you need to use javascript to update the DOM with the new element you want to add. To list the existing items you may use editor templates. Mixing these 2 will give you a dynamic form. The below is a basic implementation.

要使用编辑器模板,我们需要为属性类型创建一个编辑器模板.对于string类型(更像是通用类型),我不会这样做.我将创建一个自定义类来表示列表项.

To use editor templates, we need to create an editor template for the property type. I would not do that for string type which is more like a generic one. I would create a custom class to represent the list item.

public class Item
{
    public string Name { set; get; }
}
public class ShoppingList
{
    public int ShoppingListId { get; set; }
    public string Name { get; set; }
    public List<Item> ListItems { get; set; }

    public ShoppingList()
    {
        this.ListItems=new List<Item>();
    }
}

现在,在~/Views/YourControllerName~/Views/Shared/下创建一个名为EditorTemplates的目录,并创建一个名为Item.cshtml的视图,该视图将具有以下代码

Now, Create a directory called EditorTemplates under ~/Views/YourControllerName or ~/Views/Shared/ and create a view called Item.cshtml which will have the below code

@model  YourNameSpaceHere.Item
<input type="text" asp-for="Name" class="items" />

现在在您的GET控制器中,创建ShoppingList的对象并发送到视图.

Now in your GET controller, create an object of the ShoppingList and send to the view.

public IActionResult ShoppingList()
{
    var vm = new ShoppingList() {  };
    return View(vm);
}

现在在主视图中,您所要做的就是调用EditorFor方法

Now in the main view, All you have to do is call the EditorFor method

@model YourNamespace.ShoppingList
<form asp-action="ShoppingList" method="post">
    <input asp-for="Name" class="form-control" />
    <div class="form-group" id="item-list">
        <a href="#" id="add">Add</a>
        @Html.EditorFor(f => f.ListItems)
    </div>
    <input type="submit" value="Create" class="btn btn-default" />
</form>

标记具有用于添加新项目的锚标记.因此,当用户单击它时,我们需要添加一个新的输入元素,其名称属性值的格式为ListItems[indexValue].Name

The markup has an anchor tag for adding new items. So when user clicks on it, we need to add a new input element with the name attribute value in the format ListItems[indexValue].Name

$(function () {

   $("#add").click(function (e) {
       e.preventDefault();
       var i = $(".items").length;
       var n = '<input type="text" class="items" name="ListItems[' + i + '].Name" />';
       $("#item-list").append(n);
   });

});

因此,当用户单击时,它会向DOM添加一个具有正确名称的新输入元素,并且当您单击提交"按钮时,模型绑定将可以正常工作,因为我们具有正确的输入名称属性值.

So when user clicks it adds a new input element with the correct name to the DOM and when you click the submit button model binding will work fine as we have the correct name attribute value for the inputs.

[HttpPost]
public IActionResult ShoppingList(ShoppingList model)
{
    //check model.ListItems
    // to do : return something
}

如果要预加载一些现有项(例如用于编辑屏幕等),则要做的就是加载ListItems属性,编辑器模板将负责使用正确的name属性值呈现每个项的输入元素./p>

If you want to preload some existing items (for edit screen etc), All you have to do is load the ListItems property and the editor template will take care of rendering the input elements for each item with correct name attribute value.

public IActionResult ShoppingList()
{
    var vm = new ShoppingList();
    vm.ListItems = new List<Item>() { new Item { Name = "apple" } }
    return View(vm);
}

这篇关于创建在运行时增长的动态表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆