I have the following classes:
public class Folder
{
public Folder()
{
Documents = new List<Document>()
}
public string Name { get; set; }
public List<Document> Documents { get; set; }
}
and:
public class Document
{
public string Name { get; set; }
public string Path { get; set; }
}
I need a razor view with a form that's going to save a new Folder
once submitted. Apart from the Name
field, I want the form to also contain a table for the Document
s and an Add button. I want to be able to add rows (documents) to the table by pressing the button. In other words, I want to add rows/documents dynamically. After pressing the button a new row with input fields should appear for the user to fill them out. After the user submits the form, the submitted model should contain as many Document objects in the list, as the rows of the table.
Below you can find what I tried so far. If anyone has a more elegant solution, it is more than welcome!
1) I tried scaffolding a partial view as shown below, but then the button calls a new action. Ideally, I don't want to leave the screen. I want to be able to add rows dynamically, and these rows/documents to be posted back inside my model when I hit submit. The file that was generated is the following:
@model IEnumerable<Document>
<p>
<div class="form-group">
<div class="col-md-offset-2 col-md-10 text-right">
<a asp-action="GetNewDocument" class="btn btn-primary">Add Document</a>
</div>
</div>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Path)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Path)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</tbody>
</table>
2) I tried working with editor templates and Ajax call to a controller action for returning a partial view for a newly created Document, but then when I submit the form, the Folder appears to have no Documents whatsoever. More specifically I have:
AddFolder.cshtml:
@model Folder
<div>
<h3>Add Folder</h3>
<input id="add-document" type="button" value="Add Document" class="btn btn-primary" />
</div>
<form asp-controller="Folder" asp-action="AddFolder" method="post" role="form">
<div class="form-group form-row">
<label asp-for="Name"></label>
<input asp-for="Name" type="text" />
</div>
div class="form-group form-row">
<table class="table table-hover" id="documentsTable">
<thead>
<tr>
<th scope="col">
DOCUMENT NAME
</th>
<th scope="col">
DOCUMENT PATH
</th>
</tr>
</thead>
<tbody>
@Html.EditorFor(m => m.Documents)
</tbody>
</table>
</div>
</form>
<script type="text/javascript">
$(document).ready(function () {
$("#add-document").click(function () {
$.ajax({
url: "GetNewDocument",
success: function (data) {
$("#documentsTable").append(data);
}
});
});
});
</script>
The GetNewDocument action method in the controller looks like this:
public PartialViewResult GetNewDocument()
{
return PartialView("NewDocument", new Document());
}
The NewDocument partial view:
@model Document
@Html.EditorForModel()
and the Document.cshtml in the EditorTemplates folder:
@model Document
<tr class="document-row">
@{
using (Html.BeginCollectionItem("Documents"))
{
<td>
@Html.TextBoxFor(m => m.Name)
@Html.ValidationMessageFor(m => m.Name)
</td>
<td>
@Html.TextBoxFor(m => m.Path)
@Html.ValidationMessageFor(m => m.Path)
</td>
}
}
</tr>
At this point I am not even sure if this is the right way to do what I want to do in Asp.Net Core.
But I am pretty sure I am missing something, since no Document
s are posted back and the list is null.
Any help is welcome. Thank you in advance.