I am populating a table with education records from a section of an html page. I am using hidden inputs so as to be able to submit the data from my viewmodel. Because I cannot find a way to use Html helpers (such as Html.HiddenFor) from javascript codes, I had to prepopulate the table so as to copy the appropriate markup for the javascript to render, for example
'<td>' + degreeaward + '<input data-val="true" data-val-required="The Degree Awarded field is required." id="Educations_' + eduTableRowCount + '__DegreeAwarded" name="Educations[' + eduTableRowCount + '].DegreeAwarded" type="hidden" value=' + degreeaward + '>' + '</td>' +
The first problem is that the code becomes messy. The second is that because I am manually generating the list index number (eduTableRowCount) for the input id, if I delete one of the rows from the table, the numbering becomes distorted and I wont have all rows submitted. My view model class is:
public class EduAndProfessionalBackground
{
public long ProfileId { get; set; }
public List<WorkExperience> WorkExperiences { get; set; }
[Required(ErrorMessage ="You must add at least one education info")]
public List<Education> Educations { get; set; }
}
public class Education
{
[Required, Display(Name = "Institution Name")]
public string InstitutionName { get; set; }
[Required]
public string Concentration { get; set; }
[Required, Display(Name = "Degree Awarded")]
public string DegreeAwarded { get; set; }
[Required, Display(Name = "Start Date")]
public DateTime StartDate { get; set; }
[Display(Name = "End Date")]
public DateTime EndDate { get; set; }
public bool StillStudiesHere { get; set; } = false;
}
The code I use to prepopulate the table when the page first loads (according to the answer here):
for (int i = 0; i < Model.Educations.Count; i++)
{
<tr style="font-size:12px">
...
<td>
@Html.DisplayFor(m => m.Educations[i].Concentration)
@Html.HiddenFor(m => m.Educations[i].Concentration)
</td>
<td>
@Html.DisplayFor(m => m.Educations[i].DegreeAwarded)
@Html.HiddenFor(m => m.Educations[i].DegreeAwarded)
</td>
...
<td style="width:100px;text-align:center; padding:5px">
<button class="delete btn btn-primary btn-xs my-xs-btn" type="button" id="btnDeleteEdu">
<span class="glyphicon glyphicon-trash"></span> Delete
</button>
</td>
</tr>
}
The javascript code for adding more rows to the table:
var concentration = $("#Concentration").val();
var degreeaward = $("#DegreeAwarded").val();
var eduTableRowCount = document.getElementById("table_edu").getElementsByTagName("tr").length;
eduTableRowCount = eduTableRowCount - 1; // if the number of rows in the table is 4, the next item should have an index of 3
if ((instiName && concentration && degreeaward && start) && (end || stillStudiesHere)) {
var newEduItem = '<tr style="font-size:12px">' +
'<td>' + concentration + '<input data-val="true" data-val-required="The Concentration field is required." id="Educations_' + eduTableRowCount + '__Concentration" name="Educations[' + eduTableRowCount + '].Concentration" type="hidden" value=' + concenatration + '>' + '</td>' +
'<td>' + degreeaward + '<input data-val="true" data-val-required="The Degree Awarded field is required." id="Educations_' + eduTableRowCount + '__DegreeAwarded" name="Educations[' + eduTableRowCount + '].DegreeAwarded" type="hidden" value=' + degreeaward + '>' + '</td>' +
$('#table_edu').append(education);
}
The information I got from the following links: accessing viewmodels, this, this and JS and Html helpers are only on how to access data from viewmodels and have not helped in solving my problem. I would appreciate a better approach to achieve my aim and I would be glad to add more details if anything is unclear.