2

I am generating my form elements by looping over a array. So I have a array = ["name", "age"] and I loop over each item and create a textbox with the appropriate name and related data.

Therefore I creating my form element dynamically such that

 <input class="input-validation-error text-box single-line" data-val="true" data-val-required="@arr[i] is required" id="@arr[i]" name="@arr[i]" type="text" value="">
 <span class="field-validation-error" data-valmsg-for="@arr[i]" data-valmsg-replace="true"></span>

Instead of :

 @Html.EditorFor(model => model.age)
 @Html.ValidationMessageFor(model => model.age) 

However, because of this, the client-side messages are not being generated. It would catch the error in the server-side validation but client-side stop working.

enter image description here

How can I get the client-side message to work while keeping the ability to create the form dynamically, such that in the blew line of codes the model's property-name can be provided dynamically? Is there a way?

@Html.EditorFor(model => model[@arr[i]])
@Html.ValidationMessageFor(model => model[@arr[i]]) 

I know that above code doesn't work but its just to emphasize what I am looking for in a solution.

2 Answers 2

1

You need to explicitly register validation inline or with JavaScript.

More jQuery Validate Examples (Below is a brief example)

$("#myform").validate({
  rules: {
   name: "required"
  }
});

Inline ex:

<input id="age" name="age" required />
Sign up to request clarification or add additional context in comments.

Comments

1

This works:

@model Testy20161006.Controllers.MessageViewModel
@{
    Layout = null;
}

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>IndexStackOverflow900</title>

</head>
<body>
    <div>
        @using (Html.BeginForm())
        {
            int i = 0;
            foreach (var arr in Model.myArray)
            {
                <input class="input-validation-error text-box single-line" data-val="true"
                       data-val-required="@arr is required" id=@arr name=@arr type="text" value="">
                <br />
                @Html.ValidationMessage(arr);
                i++;
            }

            <input type="submit" value="submit" />
        }
    </div>
</body>
</html>

Controller/Model:

public class MessageViewModel
{
    public List<string> myArray = new List<string>();
    [Required]
    public string name { get; set; }
    [Required]
    public string age { get; set; }
}

public class HomeController : Controller
{
    [HttpPost]
    public ActionResult IndexStackOverflow900(MessageViewModel mvm)
    {
        if (ModelState.IsValid)
        {
        }
        else
        {
            //you can narrow it down to which field caused the error by inspecting ModelState
            //List<ModelErrorCollection> errors = controller.ModelState.Select(x => x.Value.Errors)
            //           .Where(y => y.Count > 0)
            //           .ToList();
            ModelState.AddModelError("name", "name is required");
            ModelState.AddModelError("age", "age is required");
        }

        FactorCode(mvm);
        return View(mvm);
    }

    public ActionResult IndexStackOverflow900()
    {
        MessageViewModel mvm = new MessageViewModel();
        FactorCode(mvm);
        return View(mvm);
    }

    public void FactorCode(MessageViewModel mvm)
    {
        mvm.myArray.Add("name");
        mvm.myArray.Add("age");
    }

1 Comment

Thanks @kblau I couldn't get server side validation to display when trying to update multiple records in a single form using a foreach (var item in Model.Round.Matches) and replacing your @Html.ValidationMessage(arg); with @Html.ValidationMessage($"Round.Matches[{item.ID}].HomeTeamID") was just what I needed.

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.