0

Say I have the following list properties being rendered to my create view:

        @for (var i = 0; i < Model.SiteSplits.Count(); i++)
        {
            <div class="clearfix"></div>
            <div class="form-group">
                @Html.LabelFor(model => model.SiteSplits[i].CostCode, htmlAttributes: new {@class = "control-label col-md-3"})
                <div class="col-md-9">
                    @Html.EditorFor(model => model.SiteSplits[i].CostCode, new {htmlAttributes = new {@class = "form-control"}})
                </div>
            </div>

            <div class="clearfix"></div>
            <div class="form-group">
                @Html.LabelFor(model => model.SiteSplits[i].SplitPercentage, htmlAttributes: new {@class = "control-label col-md-3"})
                <div class="col-md-9">
                    @Html.EditorFor(model => model.SiteSplits[i].SplitPercentage, new {htmlAttributes = new {@class = "form-control"}})
                </div>
            </div>
        }

This results in x3 cost code and split percentages which are passed back to the controller in a list on POST.

I've put a required annotation on the CostCode and SplitPercentage in the view model, which is resulting in all 3 of the Split/Codes being required.

Is there any way of making just the CostCode and SplitPercentage Required on just the first loop and have it ignore the validation for the second two so they are merely optional?

JsonStatham
  • 8,163
  • 26
  • 88
  • 160
  • I already gave you the solution to solve this is the comments to your self answer in your [last question](http://stackoverflow.com/questions/35067583/mvc-post-model-with-list-to-controller) - you cannot make the attributes apply to only one instance (and in any case, what of the user entered 2 or 3) –  Jan 29 '16 at 12:04
  • Sorry, hadn't seen this, will take a look. – JsonStatham Jan 29 '16 at 12:33

1 Answers1

1

To directly answer your question, you could include an addition property in your model say

public bool IsRequired { get; set; }

and then use a foolproof [RequiredIfTrue] or similar validation attribute on the other properties

[RequiredIfTrue("IsRequired")]
public string CostCode { get; set; }

and in the GET method, populate the SiteSplits collection with 3 default objects, setting the first one with IsRequired = true; and include a hidden input for the IsRequired property.

@Html.HiddenFor(m => m.SiteSplits[i].IsRequired)

However, this makes no sense in relation to your last question where you have indicated you want between 1 and 3 items. If the user added all 3, then the last 2 would not be validated and you could be saving invalid data.

A better option is to allow the user to dynamically add new items as required, which can be done by using the BeginCollectionItem helper or by creating a html template and copying and appending it to your collection (and updating its collection indexers) as discussed in the following answers

  1. POST a form array without successful
  2. Submit same Partial View called multiple times data to controller?
  3. Set class validation for dynamic textbox in a table

An example of using the BeginCollectionItem is also included in this article

Refer also this DotNetFiddle for a working example using a html template based on the models posted in your last question

Community
  • 1
  • 1