简体   繁体   English

在同一视图上添加和删除集合中的项目的视图

[英]A view to add and remove items from a collection on the same view

I'm creating a View that allows the user to add and remove objects in list in a particular way that the client wants. 我正在创建一个视图,该视图允许用户以客户端所需的特定方式添加和删除列表中的对象。 The user has to be able to add or remove multiple forms on the page before submitting. 在提交之前,用户必须能够在页面上添加或删除多个表单。 When the page posts it needs to display what's already in the list, with the option to remove each item, plus allow the user to add/remove more objects before submitting again. 页面发布后,它需要显示列表中已有的内容,并带有删除每个项目的选项,并允许用户在再次提交之前添加/删除更多对象。

I'm able to use JQuery and a Partial View to let the user add or remove new forms before submitting. 我可以使用JQuery和Partial View来让用户在提交之前添加或删除新表单。 What I can't figure out is how to provide a button to remove objects that are already in the list from a previous submit. 我不知道的是如何提供一个按钮来删除上一次提交中列表中已存在的对象。

Can anyone help me out with this? 谁能帮我这个忙吗? It would be greatly appreciated. 这将不胜感激。

Here's what I've figured out so far. 到目前为止,这是我想出的。 In my View: 在我看来:

@using (Html.BeginForm())
{
    <div id="recipients">
        @foreach (var p in Model)
        {
            @Html.Partial("_Recipient", p)
        }

        <div id="recipients0"></div>
    </div>
    <button id="add" type="button">Add</button>
    <button id="remove" type="button">Remove</button>
    <input type="submit" value="Save" />
}

<script type="text/javascript">
    $('#add').click(function () {
        var url = '@Url.Action("Recipient")';
        var div = $('#recipients');
        var divlast = $('div[id^="recipients"]:last');

        var num = parseInt(divlast.prop("id").match(/\d+/g), 10) + 1;


        var newdiv = $(document.createElement('div')).attr('id', 'recipients' + num)//rest of code

        $.get(url, function (response) {
            div.append(newdiv);
            newdiv.append(response);
        });
    })
    $('#remove').click(function () {
        var div = $('#recipients');
        var divlast = $('div[id^="recipients"]:last');
        var num = parseInt(divlast.prop("id").match(/\d+/g), 10);
        alert("div[id='recipients" + num + "']");
        $("div[id='recipients" + num + "']").remove();
        //div.remove('div[id^="recipients' + num + '"]');
    })

The Partial View with the form to add data to a new object: 具有将数据添加到新对象的窗体的局部视图:

@using (Html.BeginCollectionItem("recipients"))
{
    @Html.HiddenFor(m => m.ID)
    @Html.LabelFor(m => m.Recipient)
    @Html.TextBoxFor(m => m.Recipient)
    @Html.ValidationMessageFor(m => m.Recipient)
    <br />
    @Html.LabelFor(m => m.Amount)
    @Html.TextBoxFor(m => m.Amount)
    @Html.ValidationMessageFor(m => m.Amount)


}
<td>
    @Ajax.ActionLink(
        "Remove",
        "Remove",
        "CashRecipients",

        new AjaxOptions
        {
            HttpMethod = "POST",
            OnSuccess = "onDeleteSuccess"
        }
    )
</td>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>

<script>
    var onDeleteSuccess = function (result) {
        alert('Howdy');
    };
</script>

My controller: 我的控制器:

    public PartialViewResult Recipient()
    {
        return PartialView("_Recipient", new CashRecipientViewModel());
    }

    // GET: 
    public ActionResult Create()
    {
        List<CashRecipientViewModel> model = new List<CashRecipientViewModel>();

        return View(model);
    }

    // POST: CashRecipients/Create
    [HttpPost]
    public ActionResult Create([Bind(Include = "ID,Amount,Recipient")] IEnumerable<CashRecipientViewModel> recipients)
    {

        return View(recipients);

    }

My View Model: 我的视图模型:

public class CashRecipientViewModel
{
    public int? ID { get; set; }
    public decimal Amount { get; set; }
    [Required(ErrorMessage = "Please enter the name of the recipient")]
    public string Recipient { get; set; }
}

Having a single 'remove' button does not make sense and you need a 'remove' associated with each item in the collection. 仅具有一个“删除”按钮是没有意义的,您需要与该集合中的每个项目相关联的“删除”。 In addition, remove the id attributes from your <div> elements and use relative selectors. 此外,从<div>元素中删除id属性,并使用相对选择器。

Change the partial to 将部分更改为

@using (Html.BeginCollectionItem("recipients"))
{
    <div class="item" data-id="@Model.ID"> // add an enclosing element
        @Html.HiddenFor(m => m.ID)
        @Html.LabelFor(m => m.Recipient)
        @Html.TextBoxFor(m => m.Recipient)
        @Html.ValidationMessageFor(m => m.Recipient)
        @Html.LabelFor(m => m.Amount)
        @Html.TextBoxFor(m => m.Amount)
        @Html.ValidationMessageFor(m => m.Amount)
        <button type="button" class="remove">Remove</button> // add button
    </div>
}

The in the main view, your scripts will be 在主视图中,您的脚本将是

var url = '@Url.Action("Recipient")';
var recipients = $('#recipients');
$('#add').click(function () {
    $.get(url, function (response) {
        recipients.append(response);
    });
});
$('#recipients').on('click', '.remove', (function() {
    var container = $(this).closest('.item');
    var id = container.data('id');
    if (!id) {
        container.remove();
    } else {
        // see notes below
    }
}

For any items that have been added in the view, the value of property ID will be null and the code in the if block will remove the item from the view. 对于已在视图中添加的任何项目,属性ID的值将为null并且if块中的代码将从视图中删除该项目。 However for existing items that you may be editing (where the ID has a value), then you need to consider how to remove it from the database. 但是,对于您可能正在编辑的现有项目(其中的ID具有值),则需要考虑如何从数据库中将其删除。 Options include 选项包括

  1. Adding an additional property in the view model (say) public bool IsDeleted { get; set; } 在视图模型中添加其他属性(例如) public bool IsDeleted { get; set; } public bool IsDeleted { get; set; } public bool IsDeleted { get; set; } and including a hidden input in the partial for it. public bool IsDeleted { get; set; }并在部分内容中包含隐藏的输入。 You could then set it to true so when you submit, you can delete all recipients.Where(x => x.IsDeleted); 然后可以将其设置为true以便在提交时可以删除所有recipients.Where(x => x.IsDeleted);

     @Html.HiddenFor(m => m.IsDeleted, new { @class = "flag" }) } else { container.find('.flag').val('true'); } 
  2. Making an ajax call to a server method which deletes the item from the database, and if successful, remove the associated container from the DOM 对服务器方法进行ajax调用,该方法将从数据库中删除该项目,如果成功,则从DOM中删除关联的容器

     } else { $.post(yourDeleteUrl, { id: id }, function(response) { if(response) { container.remove() } else { // oops, something went wrong } }); } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM