在MVC3 Razor创建视图中动态添加表单元素

3

我希望创建一个表单,其中包含一组文本框。每当用户点击添加按钮时,这些文本框将根据用户的点击次数重建。以下是我想要实现的图片:enter image description here

控制器:

    //
    // GET: /Client/MyMove/Create

    public ActionResult Create()
    {
        return View();
    }

    //
    // POST: /Client/MyMove/Create

    [HttpPost]
    public ActionResult Create(Move move)
    {
        var viewModel = new CreateMoveViewModel();
        MembershipUser currentUser = Membership.GetUser();
        Guid currentUserId = (Guid)currentUser.ProviderUserKey;
        if (ModelState.IsValid)
        {                
            move.UserId = currentUserId;
            db.Moves.Add(move);
            move.AddMoveItem(2);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(move);
    }

Create.cshtml

@model MovinMyStuff.WebUI.Areas.Client.Models.CreateMoveViewModel
@using Telerik.Web.Mvc.UI
@{
    ViewBag.Title = "Create";
}

<h1>Post a Move</h1>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript">    </script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
    <div class="form-item-group last">
        <div class="form-item half">
            <div class="editor-label">
                Start Date
            </div>
Editorfor for Model1...
    <div>
        @Html.Partial("_MoveItem")
    </div>
</fieldset>
<div class="submit-button-wrapper">
    <input class="button" type="submit" value="Post" />
</div>
}

<div>
    @Html.ActionLink("Go Back", "Index", null, new { @class = "link-text" })
</div>

ViewModel

namespace MovinMyStuff.WebUI.Areas.Client.Models
{
public class CreateMoveViewModel
{
    public CreateMoveViewModel()
    {
        Moves = new Move();
        MoveItems = new MoveItem();
    }
    public Move Moves { get; set; }
    public MoveItem MoveItems { get; set; }
}
}

Partial View

@model MovinMyStuff.Domain.Entities.MoveItem

    <div class="editor-label">
        Choose Area of Your Home
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.MoveItemArea)
        @Html.ValidationMessageFor(model => model.MoveItemArea)
    </div>

    <div class="editor-label">
        Choose Your Item 
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.MoveItemType)
        @Html.ValidationMessageFor(model => model.MoveItemType)
    </div>

    <div class="editor-label">
        Quantity
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Quantity)
        @Html.ValidationMessageFor(model => model.Quantity)
    </div>
Other Properties of model...


    <div class="editor-label">
        @Html.HiddenFor(model => model.MoveId)
    </div>

1
你成功地解决了这个问题吗?我一直在尝试做类似的事情,但还需要添加字段验证的复杂性。 - Ciarán Bruen
3个回答

6
我强烈建议您阅读以下文章。它包含了一个实现您所需功能的示例,与IT技术有关。该示例涉及使用默认模型绑定器时可能遇到的问题并介绍了如何通过使用自定义的 Html.BeginCollectionItem 助手来克服这些挑战。请点击链接查看:following article

这个解决方案在几年后的情况下仍然准确吗?还是有更好的选择? - Tomasz Kowalczyk

2

我将尝试使用所需的模型创建一个部分视图,关键是每次单击按钮时使用ajax添加从部分视图生成的html,例如:

您的模型

 public class example
 { 
     public int Length { get; set;}
     public int Width  { get; set;}
     public int Height {get; set;}
 }

你的操作

public ActionResult Example()
{
     return View();
}

你的部分视图

@model FooExample.Model.Example    

@{
     Layout = null;
 }

<div>
     @Html.EditorFor(model => model.Length)  
</div>
<div>
     @Html.EditorFor(model => model.Width)  
</div>
<div>
     @Html.EditorFor(model => model.Height)  
</div>

您的主视图
<input type="button" id="btnAddRows" />

<table id="addViews">
     <tr>
        <td>
        </td> 
     </tr>
<table>

现在这是脚本。
$(document).ready(function(){
   $("#btnAddRows").click(function(){

       $.ajax({
            url: 'your path to the action',
            data : 'if you need to pass parameters',
            datatype: 'html',
            success: function(data){
               $("#addViews").append("<tr/><td>"+data+"</td><tr>");
           }  
       })

   });

});

我在处理中,请给我两分钟。 - Jorge
那样会为每个项目生成具有相同id和name的html吗?在这种情况下,我认为默认模型绑定程序将无法在提交时构建模型列表。 - Pablo Romeo
为您的编辑器定义,以生成ID生成的类。 - Jorge

1

以下是我过去如何实现类似情况的解释:

https://dev59.com/bmPVa4cB1Zd3GeqP9M1S#10583792

由于需要支持编辑和删除,所以它更加复杂。 主要思路是使用一个隐藏的模板(使用EditorTemplate创建),用于创建新行,并使用一些JavaScript自动命名所有新项目,以一种MVC默认绑定器可以自动解释并转换为适当的ViewModel列表的方式在Action中进行。


我看了你的例子,它看起来不错,但我不知道如何将它与我上面的代码联系起来... - J0NNY ZER0
在我的情况下,必须完全在客户端完成,而且我已经定义了一个“EditorTemplate”,可以呈现单个“行”。 由于我希望我的操作接收所有行作为ViewModels列表,因此我首先将我的模板行(当您单击“添加”时将显示的内容)呈现在隐藏的div上。 当用户单击“添加”时,您将使用jquery获取该隐藏div的内容进行克隆,将其附加为最后一项,并将所有输入的ID重命名为MVC所期望的名称。 但是在我的情况下,仅在需要保存时才转到服务器。 - Pablo Romeo
现在,假设您正在使用Telerik MVC扩展,难道您不能使用他们的Grid http://demos.telerik.com/aspnet-mvc/grid/editingajax吗?我认为您可以在不实际进行大量工作的情况下完成所有这些操作。 - Pablo Romeo
我相信肯定有更简单的方法。个人来说,我无法使用Telerik,这就是为什么我不得不手动完成它的原因。现在,你也可以尝试使用Knockout.js,这个例子看起来与你正在尝试做的非常相似,是吗?http://knockoutjs.com/examples/gridEditor.html - Pablo Romeo
我创建了一个编辑器模板。我只使用telerik来选择日期,没有其他的东西。我认为这个编辑器模板会很干净。我要睡觉了,明天再继续。谢谢你的想法。也许我们明天可以联系一下。(: - J0NNY ZER0
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接