1

I've a Person entity that contains set of "Education" entities. What I want is to collect "N" number of Education entries from the form. This "N" is controlled by "Add More Education Information" and "Remove Education Information" buttons.

At the beginning there's an empty form that'll collect one Education entry. ("person" object , which is stored in session, has one empty education entity initially, and I call View with this "person" object)

If user clicks "Add More Education Information" button, then another form is added (to get another education information, i.e. from another university, or another degree) [I add another education object to "person" and call view(person) again]

This works ok, but old data is lost. Better to say data in the forms is not mapped to Education entities and is lost, even if I call TryUpdateModel(person). Everytime I click "Add More Education Information" button all previously entered data is lost, and all forms become empty.

Question: Is there a better way of solving this kind of problems(dynamically changing number of forms)? Or what should I change to preserve old data?

Thanks.

I hope I could explain my problem.

1
  • You almost certainly don't want to add another form to the page (the browser will only submit one of them, absent JavaScript trickery), but rather add more fields to your existing form. I'm sure there's a way to map that stuff into an array in your controller, but I don't know ASP.NET MVC well enough to say how. Commented Oct 15, 2009 at 14:47

1 Answer 1

4

I think you'd be better off extending the single form and having it get an array of entities back. That is, have your first form use ids like:

 <%= Html.Hidden("Schools.index", 0) %>
 <%= Html.TextBox("Schools[0].Name") %>
 ...

Then, add new elements with an new index.

 <input type="hidden" id="Schools_index" name="Schools.index" value="1" />
 <input type="text" id="Schools[1]_Name" name="Schools[1].Name" />
 ...

And receive them as a collection

 public ActionResult AddEducation( Person person, School[] schools )
 {
 }

This will all you to submit all the information at one shot and not have to worry about partial submissions and what to do with incomplete submissions.

Note that your javascript will have to find the current maximum index to know what the names/ids of the new elements will be.

$('#addSchooButton').click( function() {
     var index = $('#form').find('[name=Schools.index]:last').attr('value') + 1;
     $('<input type="text" id="Schools[' + index + ']_Name" name="Schools[' + index + '].Name" />').appendTo( '#form' );
     ...
});

In actuality, you'd probably create an entire container -- perhaps by cloning an existing one and replacing the ids in the clone with appropriate ones based on the next index value.

For more information, reference Phil Haack's article on model binding to a list.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I finally was able to manage to accomplish what I wanted. Youe answer was really helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.