Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle repeating form fields in ASP MVC

I have a form which asks users for their personal info and their family members.
fields of the family members section is repeating.
my question is what is best practice to handle these kind of repeating forms?
I currently use AJAX to repeat forms but how to collect data from these repeating fields? enter image description here


since some one asked for how I repeat form, I do it like this: AJAX Call

$(document).on('click', '.btn-add-item', function (e) {
    e.preventDefault();
    var $results = $('#results');
    $.ajax({
        url: '/AJAX/AddFamilyForm',
        type: 'post',
        success: function (data) {
            $(data).appendTo($results);
            afterAJAX();
        }
    });
});

C# code

[HttpPost]
public PartialViewResult AddFamilyForm()
{
    if (!Request.IsAjaxRequest()) return null;
    return PartialView("_FamilyForm");
}
like image 962
mhesabi Avatar asked Aug 13 '14 12:08

mhesabi


2 Answers

This is some skeleton code on how to get this to work with proper model-binding in MVC. You'll need to write some JS to be able to delete/add new rows.

Model

public class MyModel
{
    public FamilyMembers[] FamilyMembers { get; set; }
}

View

<button id="addNewFamilyMember" type="button">Add</button>
@if (Model.FamilyMembers != null)
{
    for (int i = 0; i < Model.FamilyMembers.Length; i++)
    {
        <tr>
            <td>
                <button type="button">Delete</button>
                @Html.Hidden("FamilyMembers.Index", i)
            </td>
            <td>
                @Html.TextBoxFor(m => Model.FamilyMembers[i].Relation)
            </td>
            <td>
                @Html.TextBoxFor(m => Model.FamilyMembers[i].FullName)
            </td>
        </tr>
    }
}

Below is the code for adding a new member. It creates html dynamically and is able to bind to the posted model because of naming conventions. time gives each added row a unique id so all the data stays together.

JS (using Jquery)

var hidden = '@Html.Hidden("FamilyMembers.Index", "{id}")';
var relationHtml = '@Html.TextBox("FamilyMembers[{id}].Relation")';
var fullNameHtml = '@Html.TextBox("FamilyMembers[{id}].FullName")';

$("#addNewFamilyMember").on("click", function () {
        var time = Date.now();

        var deleteHtml = "<button type='button'>Delete</button>";

        $("#familyMembers-table").find("tbody")
         .append($("<tr><td>" + hidden.replace("{id}", time) + deleteHtml + "</td>" +
            "<td>" + relationHtml.replace("{id}", time) + "</td>" +
            "<td>" + fullNameHtml.replace("{id}", time) + "</td></tr>"));
});
like image 74
James Sampica Avatar answered Sep 22 '22 10:09

James Sampica


One of the solution could be combination of hidden field and control name.

Steps:

  1. Use a hidden field to keep the count the number of row.
  2. Create controls with name like text_relation_1 for first row and text_relation_2 for second row and so on
  3. Generate other controls in same way.
  4. Increase and decrease the hidden field value so that when values post you can know the number of rows added by the user

On your action use FormCollection and loop though hidden field number and get the values from FormCollection

Like suppose I created 3 rows then I can create a action like below

public ActionResult SomeActionMethod(FormCollection formCollection, string hid)
{
    for(int i=1;i<hid;i++)
    {
        var relationId="text_relation_"+i;
        var firstrealtion=formCollection[relationId];
        ...
    }
}
like image 32
शेखर Avatar answered Sep 19 '22 10:09

शेखर