I have a Contact object that has a number properties, including a child that is a list of Addresses.
public class Contact
{
public int? Id { get; set; }
public string Name { get; set; }
public IReadOnlyList<IAddress> Addresses
{
[Lazy Load Code to populate and return list]
}
[...]
}
I want to allow the user to edit the addresses without having to edit (or post) the whole Contact object. Currently in the UI I have the addresses listed out with an Edit button next each one:
I'm using the Modal syntax that is part of Bootstrap3, and have hidden DIVs that contain a form and the fields to edit an Address. When the user clicks on edit, a modal window form appears that allows the user to edit the Address. Model Binding and validation work within this form.
It works pretty well but I have a few underlying issues with the implementation. I wanted to use the builtin Validation and Model Binding with the Address objects, but I didn't want to post back the whole object just to edit one address.
So I ended up having to create a for loop that writes out the hidden DIVs calling a Partial View and passing Address as the model:
@for (int i = 0; i < Model.Addresses.Count; i++)
{
address = (Address)Model.Addresses[i];
@Html.Partial("_AddressModal", address);
}
The unfortunate side-effect is that the model binding cannot uniquely identify which Address to apply the ModelState to, so Model Binding applies it to all the Address in in the hidden DIVs, instead of the one that was updated. This is because they have the exact same property names.
I've got a work-around that was part of an earlier question. Basically it doesn't write the ModelState unless the object is invalid. For the invalid scenario I don't show the address list which basically hides the problem. Otherwise every edit button would show the same form content.
What I want to know is if there is a better UX approach to allow a user to edit one of the child Addresses in the list?
My goals are to find a better approach using ASP.NET MVC that:
- Follow the PRG (Post-Redirect-Get) pattern
- Don't redirect to a separate Page/View for editing, which forces the user to navigate back to the contact edit form again
- Avoid popups because of the blockers
- The solution allows the use Model Binding and Validation for the Address object
What you want is :
1 Form for the contact Another form for each address
in your controller you will have an action that expects a contact as a parameter (without addresses) and another action that expects an address.
boilerplate code:
and in the view :