【问题标题】:How to add multiple entities in Razor Pages with dynamic HTML to the editable entity?如何将具有动态 HTML 的 Razor Pages 中的多个实体添加到可编辑实体?
【发布时间】:2021-01-26 15:48:09
【问题描述】:

我有一个带有生成剃须刀页面的 ASP.NET Core 3.0 Web 应用程序。模型如下:

public class Element
{
    public int ElementID { get; set; }
    public string Name { get; set; }
    public string Discriminator { get; private set; }
}

public class BucketListElement : Element
{
    public int BucketListID { get; set; }
    public string Description { get; set; }
    public bool Completed { get; set; }

    public BucketList BucketList { get; set; }
    public Progression Progression { get; set; }
}

public class Progression
{
    public int ProgressionID { get; set; }
    public int ElementID { get; set; }
    public ICollection<BLETask> BLETasks { get; set; }
    public BucketListElement BLElement { get; set; }
}

public class BLETask
{
    public int BLETaskID { get; set; }
    public int ProgressionID { get; set; }
    public string Text { get; set; }
    public bool Completed { get; set; }
    public Progression Progression { get; set; }
}

一个 BucketListElement 有 1 个进度。一个进程可以有 0..* BucketListElementTasks (BLETask)。创建 BucketListElement 后,我​​们可以导航到 Edit 页面,在那里我希望能够执行以下操作: 用户可以按下“+”号,添加一个带有复选框的字段,或者可以按下“-”号,删除旁边带有复选框的字段。每个字段都需要填写,在保存尽可能多的 BLETask 后,应将用户创建和填写的字段数量(通过外键)分配给已编辑的 BucketListElement 的 Progression 实体。

Edit page layout after clicking the "+" sign twice (red part is needed)

如果我知道的话,我可以动态地操作 HTML 以使用 JavaScript / Ajax 添加和删除这些字段,但不幸的是我没有这方面的经验,这就是我向您寻求帮助的原因。

更新: 随着@mj1313 的建议更改,添加BLETasks 工作正常,但我希望能够编辑已经注册的BLETasks,所以我将此代码插入Edit.cshtml 到ID 为“Tasks”的。现在看起来像这样:

<div class="form-group">
<label asp-for="BucketListElement.Progression.BLETasks" class="control-label"></label>
<button id="addTask" class='btn btn-primary'>+</button>
<div id="Tasks" style="margin-top:10px">
    @{
        int indexCounter = 0;
        int taskCounter = 1;
        foreach (var task in Model.BucketListElement.Progression.BLETasks)
        {
            <div class="taskRow">
                <label>Task @taskCounter:</label>
                <input class="form-control" asp-for="@Model.BucketListElement.Progression.BLETasks[indexCounter].Text" required="required" />
                <input class="largerCheckbox" asp-for="@Model.BucketListElement.Progression.BLETasks[indexCounter].Completed" />
                <button class="btn btn-danger" style="padding-top:1px" onclick="deleteRow(this)" value="@indexCounter">-</button>
            </div>
            indexCounter++;
            taskCounter++;
        }
    }
</div>

现在从已经存在的 BLETasks 中只能删除最后一行(以及由脚本创建的那些(“+”按钮))。如果我在第一个 n-1 行的末尾按下“-”按钮,就像我点击了“保存”按钮一样。 如果我删除一个必填字段的文本(以便能够留在页面上)并单击第一个 n-1 行的“-”按钮之一,则会发生这种情况: After deleting a required field and deleting one of the first n-1 row

【问题讨论】:

    标签: asp.net-core asp.net-ajax razor-pages dynamic-html


    【解决方案1】:

    我根据你的描述做了一个例子,你可以参考下面的代码:

    编辑.cshtml:

    @page
    @model WebApplication9.Pages.EditModel
    @{
    }
    
    <style>
        .largerCheckbox {
            width: 25px;
            height: 25px;
            margin-left: 20px;
            margin-right: 20px;
            vertical-align: middle
        }
    
    </style>
    
    <div class="row">
        <div class="col-md-4">
            <form method="post">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <div class="form-group">
                    <label asp-for="BucketListElement.Name" class="control-label"></label>
                    <input asp-for="BucketListElement.Name" class="form-control" />
                    <span asp-validation-for="BucketListElement.Name" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="BucketListElement.Description" class="control-label"></label>
                    <input asp-for="BucketListElement.Description" class="form-control" />
                    <span asp-validation-for="BucketListElement.Description" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="BucketListElement.Progression.BLETasks" class="control-label"></label>
                    <button id="addTask" class='btn btn-primary'>+</button>
                    <div id="Tasks" style="margin-top:10px">
    
                    </div>
                </div>
                <div class="form-group">
                    <input type="submit" value="Create" class="btn btn-primary" />
                </div>
            </form>
        </div>
    </div>
    
    
    @section scripts{
        <script>
            var count = 1;
            $("#addTask").on("click", function () {
                var htmlstring = "<div class='taskRow'><label>Task" + count + "</label>";
                htmlstring += "<input type='text' name='BucketListElement.Progression.BLETasks[" + (count - 1) +"].Text' required='required'>";
                htmlstring += "<input type='checkbox' name='BucketListElement.Progression.BLETasks[" + (count - 1) +"].Completed' class='largerCheckbox' value='true'>";
                htmlstring += "<button class='btn btn-danger' style='padding-top:1px' onclick='deleteRow(this)' value='" + (count - 1)+"'>-</button></div>"
                $("#Tasks").append(htmlstring);
                count++;
            })
    
            function deleteRow(element) {
                var currentRow = parseInt($(element).val());
                let nextsiblings = document.querySelectorAll('.taskRow:nth-child(' + (currentRow + 1) + ') ~ *');
                for (var i = 0; i < nextsiblings.length; i++) {
                    var childElements = nextsiblings[i].children;
                    childElements[0].textContent = "Task" + (currentRow + 1);
                    childElements[1].setAttribute("name", "BucketListElement.Progression.BLETasks[" + currentRow + "].Text");
                    childElements[2].setAttribute("name", "BucketListElement.Progression.BLETasks[" + currentRow + "].Completed");
                    childElements[3].setAttribute("value", currentRow)
                    currentRow++;
                }
                $(element).parent("div").remove();
                count--;
            }
        </script>
    
    }
    

    编辑.cshtml.cs:

    public class EditModel : PageModel
    {
        [BindProperty]
        public BucketListElement BucketListElement { get; set; }
    
        public void OnGet()
        {
            BucketListElement = new BucketListElement
            {
                Name = "Element1",
                Description = "AAA"
            };
        }
    
        public void OnPost()
        {
            
        }
    }
    

    结果:

    【讨论】:

    • 您的建议非常准确,效果很好,但我做了一些更改(原始帖子中的更新),现在“-”按钮仅在最后一行和那些由脚本创建,我不知道为什么。
    • var childElements = nextsiblings[i].childNodes; 更改为var childElements = nextsiblings[i].children;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多