This is how to create dynamic forms and send the values to the controller using Model Binding technique
You have a
Contact.cs Model:
public class Contact
{
public int StreetNo { get; set; }
[Required]
public string Address { get; set; }
[Required]
public int Telephone { get; set; }
}
Next, create an action method on the controller that has the parameter of
IList type:
[HttpPost]
public IActionResult Index(IList contactList)
{
if (ModelState.IsValid)
{
}
return View();
}
Next, in your 'View', create a
'html table and a button' to Add Rows in the table:
<button id="AddButton">Add New Contact</button>
<form method="post">
<table>
<thead>
<tr>
<td>Street No</td>
<td>Address</td>
<td>Telephone No</td>
<td></td>
</tr>
</thead>
<tbody></tbody>
</table>
<button>Submit</button>
</form>
<input type="hidden" id="totalContacts" value="0" />
I also have an
hidden input control that will keep track on the
number of rows added to the table.
Now add the following
jQuery code to the View that will do the rows addition and rows subtraction.
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script>
$(document).ready(function () {
$("#AddButton").click(function () {
tc = parseInt($("#totalContacts").val());
tc = tc + 1;
$("#totalContacts").val(tc)
$("tbody").append('<input type="text" name="[' + (tc - 1) + '].StreetNo" /><input type="text" name="[' + (tc - 1) + '].Address" /><input type="text" name="[' + (tc - 1) + '].Telephone" />Remove')
});
$("tbody").on("click", "span", function () {
tc = parseInt($("#totalContacts").val());
tc = tc - 1;
$("#totalContacts").val(tc)
$(this).parents("tr").remove();
});
});
</script>
Explanation: On the AddButton click event, a new row is added to the table from the below code:
$("tbody").append('<input type="text" name="[' + (tc - 1) + '].StreetNo" /><input type="text" name="[' + (tc - 1) + '].Address" /><input
type="text" name="[' + (tc - 1) + '].Telephone" />Remove')
Variable 'tc' gives the
total rows currently there in the table, and is used to create the
names of the elements (which is the most important part).
Remember the names have to be create by adding
[0]., [1]., [2]., etc before there names. This will help you to apply
Model Binding technique in this scenario.
Take for example:
If there are 1 row then:
<input type="text" name="[0].StreetNo">
<input type="text" name="[0].Address">
<input type="text" name="[0].Telephone">
If there are 2 rows then:
<input type="text" name="[0].StreetNo">
<input type="text" name="[0].Address">
<input type="text" name="[0].Telephone">
<input type="text" name="[1].StreetNo">
<input type="text" name="[1].Address">
<input type="text" name="[1].Telephone">
I have a span element on the last
td of each row of the table. Since it is dynamically generated so I used the
jQuery On method to apply it's click event. Inside the
span's click event, I am simply removing the row (in which it lies) by the
.remove() method. Also I am updating the rows counter in the hidden input control.
$("tbody").on("click", "span", function () {
tc = parseInt($("#totalContacts").val());
tc = tc - 1;
$("#totalContacts").val(tc)
$(this).parents("tr").remove();
});
You can run the code, click the button on the form and you will get all values in the controller using "Model Binding".