简体   繁体   English

asp.net核心嵌套表单

[英]asp.net core nested forms

I have 3 models - School, Classrooms & Courses. 我有3个模型 - 学校,教室和课程。

A school can have many classrooms, and a classroom can have many courses taught in it. 学校可以有很多教室,教室里可以开设许多课程。

public class School
{
    public int SchoolId { get; set; }
    public string SchoolName { get; set; }
    public List<Classroom> Classrooms { get; set; }
}

public class Classroom
{
    public int ClassroomId { get; set; }
    public string Room { get; set; }
    public List<Course> Courses { get; set; }
    public virtual int SchoolId { get; set; }
}

public class Course
{
    public int CourseId { get; set; }
    public string CourseName { get; set; }
    public virtual int ClassroomId { get; set; }
}

I want to create CRUD actions for School, where I can add 0 to many classrooms and within each classroom create 0 to many courses all in one form. 我想为School创建CRUD操作,在那里我可以为许多教室添加0,并且在每个教室中创建0到多个课程。 Allowing the user to dynamically add classrooms and courses within those classrooms all within creating a school 允许用户在创建学校的过程中动态地在这些教室中添加教室和课程

The way that I'm accomplishing this right now is hard coding (where School is the @Model): 我现在正在实现这一目标的方式是硬编码(学校是@Model):

<div class="col-md-10">
    <input asp-for="@Model.SchoolName" class="form-control" />
</div>
<div class="col-md-10">
    <input asp-for="@Model.Classroom[0].Room" class="form-control" />
</div>
<div class="col-md-10">
    <input asp-for="@Model.Classroom[0].Course[0].CourseName" class="form-control" />
</div>
<div class="col-md-10">
    <input asp-for="@Model.Classroom[0].Course[1].CourseName" class="form-control" />
</div>
<div class="col-md-10">
    <input asp-for="@Model.Classroom[0].Course[3].CourseName" class="form-control" />
</div>

I want the user to be able to add more classrooms and more courses or have the ability to remove them dynamically on the form. 我希望用户能够添加更多课堂和更多课程,或者能够在表单上动态删除它们。

You can use a partial view and JQuery to create dynamic rows in an html table. 您可以使用局部视图和JQuery在html表中创建动态行。

I had a asset transfer form that required at least one line item. 我有一个资产转移表,至少需要一个项目。 I placed a select list for the assets and a button to add the asset and it's details (the line item) to an html table via a partial view. 我为资产设置了一个选择列表,并通过局部视图将资产及其详细信息(行项目)添加到html表中。

Partial View 局部视图

 @model ITFixedAssets.Models.TransferLineItem @{//this helps with naming the controls within the main view/page Models.TransferLineItem TransferLineItem = new Models.TransferLineItem(); } <tr> <td> <a href="#"><span class="glyphicon glyphicon-trash" style="padding-right:5px;" data-action="removeItem" onclick="RemoveRow(this);"></span></a> </td> <td> <label asp-for="@TransferLineItem.Id" class="form-control" id="row" style="height:34px;margin-top:5px;"></label> </td> <td> <input asp-for="@TransferLineItem.Asset" class="form-control" /> </td> <td> <select asp-for="@TransferLineItem.Condition" class="form-control"> <option>Please Select</option> <option value="New">New</option> <option value="Good">Good</option> <option value="Bad">Bad</option> </select> <span asp-validation-for="@TransferLineItem.Condition" class="text-danger"></span> </td> <td> <input asp-for="@TransferLineItem.AssetDescription1" class="form-control" value="@ViewBag.AssetDescription1" /> </td> <td> <input asp-for="@TransferLineItem.AssetDescription2" class="form-control" /> </td> <td> <input asp-for="@TransferLineItem.InventoryNum" class="form-control" /> </td> <td> <input asp-for="@TransferLineItem.SerialNumber" class="form-control" /> </td> </tr> 

When the 'Add Asset' button is clicked it calls a JS function, which uses an ajax GET to run a 'code behind' function that returns the partial view, which is basically a skeleton of a row to be placed into the html table. 单击“添加资源”按钮时,它会调用JS函数,该函数使用ajax GET运行“代码隐藏”函数,该函数返回部分视图,该部分视图基本上是要放入html表的行的框架。

JS Function and 'Code Behind' function that returns the partial view. JS函数和'Code Behind'函数返回局部视图。

 function AddRow() { $.ajax({ type: "GET", url: "Create?handler=AddLineItemRow" }).success(function (data) { AddNewRow(data); }); } 

     public PartialViewResult OnGetAddLineItemRow()
    {
        PartialViewResult partialViewResult = new PartialViewResult();

        partialViewResult.ViewName = "_LineItem";

        return partialViewResult;

    }

If successful then the partial view ('data') is passed to another JS function that adds the row to the table and alters the generic id's and names of the controls to the appropriate 'array' style that is needed when the form is submitted in order to save the line items into the database. 如果成功,则将部分视图('data')传递给另一个JS函数,该函数将行添加到表中,并将控件的通用id和名称更改为在提交表单时所需的相应“数组”样式。为了将订单项保存到数据库中。

 //appends the transfer line item table with a new row (partial view) function AddNewRow(data) { //****************************************************** //*************add the new to the table********************** //append the table with the new row $('#LineItems').append(data); //****************************************************** //get value of asset drop down var asset = $("#assetList").val(); //****************************************************** //*****add the row number to the id values of the controls******** //get the length of the table for new row # //(subtract 1, not sure why unless it's adding the headers into the count) var rowNum = $("#LineItems tr").length - 1; //build new name to add to the controls var nameIndex = rowNum - 1; var newName = "[" + nameIndex + "]."; //get the row label var lblRow = $("#row"); //create new id for the row label var newId = "row_" + rowNum; //apply new id lblRow.attr("id", newId); //get the last row in the table var lastRow = $("#LineItems").find("tr").last(); ////format id values for the input controls //and add names for the controls lastRow.find("input").each(function () { // get id of this input control var ctrl = $(this).attr("id"); //concatenate the row number to the id var newId = ctrl + "_" + rowNum; //assign new id to control $(this).attr("id", newId); //add the index to the control' $(this).attr("name",$(this).attr("name").replace(".", newName)); }); //update the select list (for condition) id value var selectControl = lastRow.find("select"); //get id of the select control var scId = selectControl.attr("id"); //concatenate the row number to the id newId = scId + "_" + rowNum; //assign new id to control selectControl.attr("id", newId); //add new name to control selectControl.attr("name", selectControl.attr("name").replace(".", newName)); //this ajax calls the function 'OnGetPopulateLineItemRow' in the code behind //and passes the asset # and row # as parameters. the success function //receives the return value from the OnGetPopulateItemRow function and //passes that 'data' to the PopulateRow function below $.ajax({ type: "GET", url: "Create?handler=PopulateLineItemRow", data: { _asset: asset }, //data: { _asset: asset, row: rowNum } dataType: 'json', success: function (data) { PopulateRow(asset, data, rowNum); } }); } 

After the new row has been added to the table and the names and id's are changed, another ajax 'GET' is used to call a 'code behind' function to to get the values for the controls in the new row (as can be seen in the above snippet). 将新行添加到表中并更改名称和id后,另一个ajax'GET'用于调用'code behind'函数以获取新行中控件的值(可以看到)在上面的片段中)。

Function that gets the item details of the Asset 获取资产的项目详细信息的函数

 public JsonResult OnGetPopulateLineItemRow(string _asset)
    {

        //stores named value pairs for the result
        Dictionary<string, string> results = new Dictionary<string, string>();

        //get record from the database for the specified asset (_asset)
        var asset = from a in _context.Asset select a;
        asset = asset.Where(a => a.Asset1 == _asset); 

        //get value for each field
        var description1 = from d in asset select d.AssetDescription;
        var description2 = from d in asset select d.AssetDescription2;
        var inventoryNum = from d in asset select d.InventoryNo;
        var serialNum = from s in asset select s.SerialNo;

        //add the name value pairs to the collection
        results.Add("description1", description1.ToList()[0].ToString());
        results.Add("description2", description2.ToList()[0].ToString());
        results.Add("inventoryNum", inventoryNum.ToList()[0].ToString());
        results.Add("serialNum", serialNum.ToList()[0].ToString());


        return new JsonResult(results);

    }

Finally these results are passed back to the success function and JQuery is used to populate the values 最后,这些结果将传递回success函数,JQuery用于填充值

 function PopulateRow(asset, data,rowNum) { $("#row" + "_" + rowNum).text($("#LineItems tr").length - 1); $("#TransferLineItem_Asset" + "_" + rowNum).val(asset); $("#TransferLineItem_AssetDescription1" + "_" + rowNum).val(data["description1"]); $("#TransferLineItem_AssetDescription2" + "_" + rowNum).val(data["description2"]); $("#TransferLineItem_InventoryNum" + "_" + rowNum).val(data["inventoryNum"]); $("#TransferLineItem_SerialNumber" + "_" + rowNum).val(data["serialNum"]); //reset drop down $('#assetList').prop('selectedIndex', 0); } 

Just as a side note. 就像旁注一样。 Until recently I used ASP.net webforms. 直到最近我才使用ASP.net webforms。 I'm still trying to understand how to accomplish what I considered to be simple things with server side coding that really, to me, seem to be more complicated with MVC and Razor. 我仍然试图理解如何完成我认为是服务器端编码的简单事情,对我来说,对于MVC和Razor来说,似乎更复杂。

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

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