'Model Binding editable table fields within a form (Razor Pages)
My Asp.Net 6 - Razor Pages application has an editable table within a form.
I am trying to bind the editable table fields to a model but am not sure how to do so because td fields cannot be used with asp-for tag helpers.
I want to be able to retrieve the edited values from the table in the Page Model's OnPost() method.
These are the ids of the two editable table columns that I want to retrieve the values from:
For
id="importColumn", when a user clicks on a cell, the cell value for this column gets changed from a tick to a cross using a Javascript on-click handler.For
id="modifiedColumnNames", the user modifies the value of any cell within this column.
.cshtml Form:
<form method="post" asp-antiforgery="true">
<table id="columnsToImportTable" class="display roundedCorners" width="100%">
<thead>
<tr>
<th class="centreText">Column Name</th>
<th class="centreText">Import Column</th>
<th class="centreText">Database Column Name</th>
</tr>
</thead>
<tbody>
@for (var i = 0; i < Model.newLayer.ColumnNames.Count(); i++)
{
<tr>
<td class="greyOutBackground centreText defaultCursor">@Model.newLayer.ColumnNames[i]</td>
<td id="importColumn" class="greyOutBackground centreText pointerCursor green tick true">✔
<input type="hidden" asp-for="@Model.newLayer.ImportColumn[i]" value="true">
</td>
<td id="modifiedColumnNames">
<div contenteditable>@Model.newLayer.ColumnNames[i]</div>
<input type="hidden" asp-for="@Model.newLayer.ColumnNames[i]">
</td>
</tr>
}
</tbody>
</table>
<div>
<input id="importButton" type="submit" value="Import">
</div>
</form>
Javascript/Jquery click handler:
$('#columnsToImportTable td.tick').click(function(e) {
e.stopPropagation();
e.preventDefault();
var $this = $(this);
if ($this.hasClass('true')) {
$this.html('<td id="importColumn" class="greyOutBackground centreText pointerCursor red tick false centreElement">✖<input type="hidden" asp-for="@Model.newLayer.ImportColumn[i]" value="false"></td>');
} else {
$this.html('<td id="importColumn" class="greyOutBackground centreText pointerCursor green tick true centreElement">✔<input type="hidden" asp-for="@Model.newLayer.ImportColumn[i]" value="true"></td>');
}
$this.toggleClass('true');
});
The Model:
public class NewLayer
{
public List<string> ColumnNames { get; set; } = new List<string>();
public List<string> ColumnDataTypes { get; set; } = new List<string>();
public List<string> LayerNames { get; set; } = new List<string>();
public List<string> ImportColumn { get; set; } = new List<string>();
public string SelectedLayer { get; set; } = null!;
public string SelectedNameField { get; set; } = null!;
}
The Page Model:
public class IndexModel: PageModel {
private FileProcessor _FileProcessor = new FileProcessor();
private AppContext _context;
[BindProperty(SupportsGet = true)]
public NewLayer newLayer {get;set;}
public IndexModel(AppContext context) {
_context = context;
newLayer = new NewLayer();
}
public void OnGet() {
var filePath = "[FilePath]";
var ColumnNamesAndDatatypes = _FileProcessor.GetColumnNamesAndTypes(filePath);
for (var i = 0; i < ColumnNamesAndDatatypes.Count(); i++) {
newLayer.ColumnNames.Add(ColumnNamesAndDatatypes[i].ColumnName);
newLayer.ColumnDataTypes.Add(ColumnNamesAndDatatypes[i].DataType);
newLayer.ImportColumn.Add("true");
}
newLayer.LayerNames = _context.Layers.Select(l => l.LayerName).ToList();
}
public void OnPost(NewLayer newLayer) {
var test = this.newLayer;
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
