MVC 5 Ajax partial form validation

538 Views Asked by At

I'm using an Ajax.BeginForm in a strongly typed view. Within this form I have a few panels which hold model properties which in turn use their own models and editor templates. I want to post the whole model with Ajax back to the server at the end but before doing that I'm going from panel to panel and need to validate each of them before progressing to another one.

How do I do a partial (server side) validation (in controller action) of each panel and each model property on clicking Next button?

Can I call somehow a controller action on clicking each Next button and how do I pass the values of the particular tab I'm validating? All without refreshing the page.

The models:

public class OrderItem
{
    public int ItemId { get; set; }
    public ItemBasic BasicDetails { get; set; }
    public ItemSpecifics Specification { get; set; }
}

public class ItemBasic
{
    [Required]
    public string Type { get; set; }

    [Required]
    [StringLength(30)]
    public string SerialNumber { get; set; }
}

The view:

@model OrderItem

@Ajax.BeginForm(...)
{
    @Html.AntiForgeryToken()
    @Html.HiddenFor(x => x.ItemId)
    <div class="tab">
        @Html.EditorFor(x => x.ItemBasics)
        <input type="button" value="Next" />
    </div>
    <div class="tab">
        @Html.EditorFor(x => x.ItemSpecifics)
        <input type="button" value="Next" />
    </div>
    <input type="submit" value="Add to order" />
}

The whole page is much more complicated than that, I just simplified it for the sake of this question.

Previously I used PartialViews for each property (instead of editor templates) but with PartialView the parent model can't see the property models when posting the form at the end.

Also I need to load more data into some panels depending on the user input/ selection in a field and that needs to be loaded from server, so in essence I need to call an action on certain fields and populate other with the action result.

Eg. in the item specific panel the user adds a few items to its model List property, they display as list of rows in the panel which then each can be edited or deleted by calling a controller action.

With PartialView I just performed an action, added user input which added new ItemSpecific item to the List and returned the whole ItemSpecifics model as PartialViewResult to the given panel only displaying the list of added ItemSpecific items in the panel.

public class ItemSpecifics
{
    public string Name { get; set; }
    public string Description { get; set;}
    public string Ref { get; set;}
    public IEnumerable<ItemSpecifics> Items { get; set;}
}
2

There are 2 best solutions below

3
ROCKST4R On

the easiest way would be to do your validation client sided with java script because it's complicated to validate each panel seperated on the server. but you can do the validation server sided and run your checks in the controller and if a value does not pass the validation you can return a json result which will contain the matching error message.

i hope that this answer was helpful to you in some way

for the server sided validation try something like this:

if(validation one == false)
{
    errorList.Add("validation one error");
}
if(validation two == false)
{
    errorList.Add("validation two error");
}
if(validation three == false)
{
    errorList.Add("validation three error");
}
if(errorList.Any)
{
    return JsonReturn(false, "you failed");
}
return JsonReturn(true, "success!");
0
stann1 On

The easiest thing you can do is to use javascript for your client validation and then on the POST action in the backend, you can have custom logic for validating the submitted model.

Another way would be to return to your original approach with the partial views, but instead of using Razor helpers for the form, do a normal jquery post ($ajax({...}) for the input fields that you need.