MVC hidden field being validated

11,242

Solution 1

Try this:

$.validator.setDefaults({
    ignore: ':hidden, [readonly=readonly]'
});

or for customizes

$.validator.setDefaults({
    ignore: "#automaticExtensionTypeList" 
});

Solution 2

The reason for this is that hidden fields are not designed for use when a field doesn't apply - they're designed for use when a field does apply but doesn't require input from the user. In your situation, you could:

  • Use view logic to avoid rendering the field at all unless it is applicable.
  • Use a custom validator instead of just a flat-out Required.
  • Use a valid 'default' value in the hidden field.

Personally, I'd go for the last as it'll be quickest to implement and doesn't have any obvious pitfalls - you can pick up this default value in your controller and then manipulate it as needed.

Solution 3

This is a common problem.

Hiddens will not stop validation.

I always handle this by creating a multiple forms with overlapping properties.

example:

<div id="HasControlls">
@Using(Html.BeginForm)
{
            @Html.LabelFor(model => model.AuctionTypeId)
            @Html.DropDownList("AuctionTypeId", Model.AuctionTypes, @AuctionControllerResource.SelectAuctionType, new { id="auctionType", required = "required" })
                @Html.ValidationMessageFor(model => model.AuctionTypeId)       </div>
        </section>
        <section>
            @Html.LabelFor(model => model.AutomaticExtensionType, new { hidden = "true", id = "automaticExtensionTypeLabel" })
            <div> @Html.DropDownList("AutomaticExtensionType", Model.AutomaticExtensions, @AuctionControllerResource.SelectAutomaticExtensionType, new { hidden="hidden", required = "required", id = "automaticExtensionTypeList" }) 
                @Html.ValidationMessageFor(model => model.AutomaticExtensionType)       </div>
}



<div id="HasNotControlls">
@Using(Html.BeginForm)
{
            @Html.LabelFor(model => model.AuctionTypeId)
            @Html.DropDownList("AuctionTypeId", Model.AuctionTypes, @AuctionControllerResource.SelectAuctionType, new { id="auctionType", required = "required" })
                @Html.ValidationMessageFor(model => model.AuctionTypeId)       </div>
        </section>
        <section>
                @Html.ValidationMessageFor(model => model.AutomaticExtensionType)       </div>
        </section>
}
Share:
11,242
Sachin Kainth
Author by

Sachin Kainth

I am a senior C#, .NET and AngularJS developer living in London.

Updated on June 07, 2022

Comments

  • Sachin Kainth
    Sachin Kainth almost 2 years

    I have a few fields on my page that appear and dissappear depending on the dropdown selections you make on the page.

    So, for example, I have

    <section>
                @Html.LabelFor(model => model.AuctionTypeId)
                <div> @Html.DropDownList("AuctionTypeId", Model.AuctionTypes, @AuctionControllerResource.SelectAuctionType, new { id="auctionType", required = "required" })
                    @Html.ValidationMessageFor(model => model.AuctionTypeId)       </div>
            </section>
            <section>
                @Html.LabelFor(model => model.AutomaticExtensionType, new { hidden = "true", id = "automaticExtensionTypeLabel" })
                <div> @Html.DropDownList("AutomaticExtensionType", Model.AutomaticExtensions, @AuctionControllerResource.SelectAutomaticExtensionType, new { hidden="hidden", required = "required", id = "automaticExtensionTypeList" }) 
                    @Html.ValidationMessageFor(model => model.AutomaticExtensionType)       </div>
            </section>
    

    The JQuery code I have for this is

    $('#auctionType').change(function () {
        var selectedAuctionType = $("#auctionType").val();
        var englishAuctionType = $("#englishAuctionTypeId").val();
        if (selectedAuctionType == englishAuctionType) {
            $("#automaticExtensionTypeList").show();
            $("#automaticExtensionTypeLabel").show();
        } else {
            $("#automaticExtensionTypeList").hide();
            $("#automaticExtensionTypeLabel").hide();
        }
    });
    

    Now, the showing and hiding work like they should. The problem is that when I submit the form and the field automaticExtensionTypeList is hidden, the form doesn't submit because automaticExtensionTypeList is a required field. The question is how can I tell MVC to only validate visible fields?

    I've had a look through some of the JQuery we have written in this project and we have this line

    $.validator.setDefaults({ ignore: [] });
    

    Apparantly this enables hidden validation. My question is, what line of code does the opposite?

  • Sachin Kainth
    Sachin Kainth about 11 years
    I'm not sure what you mean, could you elaborate?
  • Renaissance
    Renaissance about 11 years
    I would use 2 divs with completely distinct Forms. This way when I show/hide either I don't end up with pesky hidden [required]'s that stop my form submission
  • Dave Alperovich
    Dave Alperovich about 11 years
    wise beyond your years. Yes, all your approaches would work. They could all use a little more detail...
  • Sachin Kainth
    Sachin Kainth about 11 years
    Shall I add this to the view?
  • Sachin Kainth
    Sachin Kainth about 11 years
    That's the thing - I don't want to replace it because actually it is in an external library (KendoUI) and may be used elsewhere. What I do want to do is for my particular page override it.
  • Sachin Kainth
    Sachin Kainth about 11 years
    The place where I am doing $("#automaticExtensionTypeList").show();, could I not also add or remove the required attribute at that place?
  • Sachin Kainth
    Sachin Kainth about 11 years
    Don't quite know the syntax though - more of a C# than JQuery person.
  • Dave Alperovich
    Dave Alperovich about 11 years
    Syntax should not change (Im more C# too, but been doin a lot of JQ lately. getn kinda comfy with it ;)
  • Sachin Kainth
    Sachin Kainth about 11 years
    hmmm. Is it $("#automaticExtensionTypeList").Remove("required");?