-
Notifications
You must be signed in to change notification settings - Fork 2.1k
[Question] Optional validation of items in collection #5678
Comments
You are on a wrong path! You dont need a fake object to create an editor tempate for a new item to add in a collection. There are several way to face the problems, but basically you use a standard partial view with a null model. Then to fix all input field names you set VieData.TemplateInfo.HtmlPrefix="Contacts[N+1]", where N is the last index used in the collection. Then you have several options on wgere to place everything, but for sure you need JavaScript. |
Probably I've been doing it wrong, but that was my first approach. Example public IActionResult Create() { return new View(); }
// View
@model Customer
@Html.EditorFor()
// Contacts
@Html.EditorFor(m => m.Contacts[0]) // Renders the template
@Html.EditorFor(m => m.Contacts) // Does not render template
@Html.EditorFor(m => Model.Contacts) // Does not render template What I'm a doing wrong? Thanks for the help |
The you render a partial for adding a new contact. |
@frankabbruzzese Thanks for the help that lead me to a solution. I will outline it here for others that might have the same question // PartialView _AddContact.cshtml
@model App.Features.Customer.CustomerContactModel
@{
ViewData.TemplateInfo.HtmlFieldPrefix = "Contacts[0]";
}
@Html.EditorForModel()
// PartialView _AddContacts.cshtml
@model IList<App.Features.Customer.CustomerContactModel>
@{
ViewData.TemplateInfo.HtmlFieldPrefix = "Contacts";
}
@Html.EditorForModel()
// Usage Edit.cshtml
@Html.Partial("_AddContact", new CustomerContactModel())
// Usage Create.cshtml
@Html.Partial("_AddContact")
// Controller action called from javascript
public IActionResult AddContact([FromForm] IList<CustomerContactModel> contacts)
{
if (ModelState.IsValid)
{
ViewData["inline"] = true; // Different template for inline edit
return PartialView(contacts);
}
return new JsonResult(ModelState)
{
StatusCode = (int) HttpStatusCode.BadRequest
};
} For some reason I've to init with an empty customer contact model in |
Closing because this question is resolved. Thanks! |
This is a rather broad question that might be the result of me just doing it wrong :) Anyhow
The case
This is the model
I have a UI where the user can add contacts dynamically (if they wish). So either no contacts, one or many valid contacts (name and either of email or phone)
The problem
I initate the collection with an empty object that is used to generate the editor template (
@Html.EditorFor(m => m.Contacts[0])
. This ensures the correct name and id attribute generation is used.If the user doesn't want to add any new contacts, the default contact is serialized and sent to the controller where validation fails.
Solution or workaround
What would be nice to have is an
[OptionalCollection]
attribute that, if the contained object is the default, removes it from the collection.It would also be possible to place the default
Contact
as a property onCustomer
and use it to generate the editor template (this would not generate correct attributes but that could be solved on the client side). But doing this would require a[SkipValidation]
attributeAnother option would be add a
data-skip="true"
on the input types that should not be sent to the server. This would off course require the submission of the form to pass through client side processingThanks
#5642
The text was updated successfully, but these errors were encountered: