1

I have a model that contains a list property List<EducationalBackground> EducationalBackground and in the razor form I want the user to enter multiple institutions.

Model

public class Application
{
    ...
    [Required(ErrorMessage = "Required Field")]
    public List<EducationalBackground> EducationalBackground { get; set; }
    ...
    public Application() 
    {
        ...
        EducationalBackground = new List<Library.EducationalBackground>();
        ...
    }
}

Here is the class:

public class EducationalBackground
{
    public string InstituteName { get; set; }
    ...
}

In the razor view I am trying like this

@Html.TextBoxFor(m => m.EducationalBackground[0].InstituteName, new { @class = "form-control" })

but obviously it doesn't work because the list (EducationalBackground) is empty.

The user will have a "Add New Institution" button, so the initial list size is unknown

How do I properly accomplish this?

UPDATE Found my solution. Look for my post in the answer section

Rey
  • 3,663
  • 3
  • 32
  • 55
esausilva
  • 1,964
  • 4
  • 26
  • 54
  • 1
    Refer the answers [here](https://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) and [here](http://stackoverflow.com/questions/40539321/partial-view-passing-a-collection-using-the-html-begincollectionitem-helper/40541892#40541892) for some options for dynamically adding and deleting collection items –  Jun 09 '17 at 17:17

3 Answers3

2

I am not quite sure what is the purpose of your view to edit a list of EducationalBackground or to add new ones. If you want to edit them you obviously need to take them from somewhere like database for example.

  1. Edit case:

In the action you have:

EducationalBackground = new List<Library.EducationalBackground>
{
     new EducationalBackground(...),
     new EducationalBackground(...),
     new EducationalBackground(...),
     ..... //How many you want
}

In the view you have:

@foreach(var educationbackground in Model)
{
    @Html.TextBoxFor(m => educationbackground.InstituteName, new { @class = "form-control" })
}
  1. Add new ones.

If you want to add new ones and as you have answered you may use simple html syntax to achieve that: If you dont know the size of the list you want to add you may choose another way like in jQuery or angularjs to do this for you:

<script type="text/javascript">
    $(document).ready(function(){
        var size = 0;
        $("#btnAdd").click(function(){
             $(".someDiv").append("<input type='text' name='EducationalBackground["+size+"].InstituteName' class='form-control' />");
             size++;
        })
    })
</script>

EDIT for fiddle

Take a look at this fiddle here

Rey
  • 3,663
  • 3
  • 32
  • 55
  • 1
    This works if I have already a list and want to display them to the user. In my case I want the user to create the list of Institutions – esausilva Jun 09 '17 at 16:55
  • The user will have a "Add New Institution" button, so the list size is unknown. Thanks – esausilva Jun 09 '17 at 16:56
  • @JGeZau Should have posted the question with this explanation initially. – The_Outsider Jun 09 '17 at 17:02
  • Yeap but referring to your explanation that I was thinking of. Anyway I made a small idea in jquery how to use it so you can try it out. – Rey Jun 09 '17 at 17:02
  • jQuery code looks good, that's what I was thinking on writing. Thanks! – esausilva Jun 09 '17 at 17:04
  • 1
    @JGeZau look at the fiddle i edited and let me know if it correct one :) – Rey Jun 09 '17 at 17:07
  • 1
    This will not work (its creating duplicate `name` attributes and invalid html and will not bind when the form is submitted). Refer [this answer](http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943#30094943) for an explanation of why you cannot use a `foreach` loop –  Jun 09 '17 at 17:19
  • @StephenMuecke you are correct. Already forgot that. Thanks for pointing it out :+1: – Rey Jun 09 '17 at 17:33
1

Change the constructor of the Application class to this:

EducationalBackground = new List<Library.EducationalBackground>() 
{
    new Library.EducationalBackground()
};
Rey
  • 3,663
  • 3
  • 32
  • 55
Majid Parvin
  • 4,499
  • 5
  • 29
  • 47
1

I found my answer. I can bind multiple EducationalBackground items like this

<input type="text" name="EducationalBackground[0].InstituteName" class="form-control" />
<input type="text" name="EducationalBackground[1].InstituteName" class="form-control" />
<input type="text" name="EducationalBackground[2].InstituteName" class="form-control" />

When the form posts, it will create a list of size 3

The user will have a "Add New Institution" button, so following this pattern, I will use JS to generate, on the fly, new input elements

esausilva
  • 1,964
  • 4
  • 26
  • 54