1

I have a MVC5 ViewModel with the following 2 properties:

    public class RegisterViewModel
{
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }       

    [Display(Name = "DOB")]        
    public DateTime DateOfBirth { get; set; }

    [Required]
    [Display(Name = "Business Name")]
    public string BusinessName { get; set; }
}

and the following view:

@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @id="frmRegister", @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <h4>Create a new account.</h4>
    <hr />
    @Html.ValidationSummary("", new { @class = "text-danger" })
    
    <div id="Registration"> 
        <div class="form-group">
            @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
            <div class="col-md-10">
                @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
            </div>
        </div>

    </div>
    <!--Extended registration fields here.  Will be hidden during inital registration.  During confirmation these should be visible-->
    <div id="Registration_Ext">

        <div class="form-group">
            @Html.LabelFor(m=> m.DateOfBirth, new { @class = "col-md-2 control-label" })
            <div  class="col-md-10">
                @Html.TextBoxFor(m=> m.DateOfBirth, new { @class = "form-control" })
            </div>
        </div>

        <!--Business Ext Registration fields-->
        <div id="Business_Ext">
            <div class="form-group">
                @Html.LabelFor(m => m.BusinessName, new { @class = "col-md-2 control-label" })
                <div class="col-md-10">
                    @Html.TextBoxFor(m => m.BusinessName, new { @class = "form-control" })
                </div>
            </div>
        </div>
    </div>
    
    <div class="form-group">
        <div class="col-md-2 control-label"> </div>
        <div class="col-md-10">
            <input id="submit" type="submit" class="btn btn-default" value="Register" />
            
        </div>
    </div>
}

At startup, I'm using JQuery to hide the "Registration_Ext" Div so that the DOB and BusinessName fields do NOT display:

 $(document).ready(function () {
        var ctl = $("#Registration_Ext");
        ctl.hide();

        $("#frmRegister").validate().settings.ignore = ":hidden *";
    });

I've tried several different ways to prevent validation on the non-displayed fields. What I've tried:

1) Disabling validation for hidden input

$('#Registration_Ext :input').validate().settings.ignore = '*';

2) Removing the element's validation class

 $(this).removeClass('input - validation - error');

3)Manually looping thru the "hidden" input and turning off their validation attribute:

$("#Registration_Ext :input").each(function () {

            $(this).attr('data-val', false);
            $(this).attr('data-val-required', null);             
        });

I also added this as I read that validation values could be cached upon inititalization:

$('#frmRegister').removeData('unobtrusiveValidation');
        $('#frmRegister').removeData('validator');
        $.validator.unobtrusive.parse('#frmRegister');

Validation is still occurring for the hidden fields. On the server (Controller) the ModelState.IsValid returns false every time. Am I doing something wrong here?

GrassFed
  • 35
  • 1
  • 8
  • Take a look at this http://stackoverflow.com/questions/3713281/attribute-dependent-on-another-field – Shyju Apr 12 '16 at 16:17
  • 2
    Removing client-side unobtrusive validation attributes *does not* stop server-side validation based on the property attributes. Either 1) don't include those fields in the model you use, 2) remove the validation on the unwanted property or 3) inject the unwanted fields as hidden fields (e.g. using `@Html.HiddenFor()`) – iCollect.it Ltd Apr 12 '16 at 16:48

2 Answers2

1

The ModelState object doesn't care what you do on the client side. It simply compares the values in the bound object to the validation attributes on that object. If those fields are posted back as empty strings, or not posted back at all, and they have the [Required] attribute, then they're not going to be valid.

If those fields aren't required, simply remove the [Required] attribute from them. If they're normally required, but not in this case, create a view model that either doesn't contain them, or doesn't apply the [Required] attribute to them, and use that view model for this view.

Dave
  • 4,375
  • 3
  • 24
  • 30
  • This is not what the OP is saying. They are asking how to oblige the [Required] attribute based on whether the field is hidden or not. – csharpforevermore Jul 06 '22 at 10:33
  • 1
    @csharpforevermore it's been forever since I looked at this but my I think my reasoning for this was: since the OP says that their client hides those fields (not that it hides them sometimes), that those fields are always hidden. Therefore, either those fields aren't really required at all... or else they're required in a different view, and the easiest solution is to just change the view model for this view instead of using the same one. – Dave Jul 07 '22 at 19:07
0

Please check this one.

    <div class="form-group">
        @Html.LabelFor(m=> m.DateOfBirth, new { @class = "col-md-2 control-label" })
        <div  class="col-md-10">
            @Html.TextBoxFor(m=> m.DateOfBirth, new { @class = "form-control ignore" })
        </div>
    </div>

    <!--Business Ext Registration fields-->
    <div id="Business_Ext">
        <div class="form-group">
            @Html.LabelFor(m => m.BusinessName, new { @class = "col-md-2 control-label" })
            <div class="col-md-10">
                @Html.TextBoxFor(m => m.BusinessName, new { @class = "form-control ignore" })
            </div>
        </div>
    </div>
</div>

Disable validation on selected controls using form id. '.ignore' is a class that is placed on the controls that you don't want to validate. Also don't use Server side validation ,on form submission use '$('#frmRegister').valid()' to check validation on other fields.

$("#frmRegister").data("validator").settings.ignore = ".ignore, :hidden";
saif iqbal
  • 219
  • 1
  • 9