简体   繁体   中英

HTML / Bootstrap validation says invalid when form is valid

I've got an HTML form using Bootstrap. On this form I have a select list (mandatory field). When the user selects the option "Other" from this list, I have a hidden text input field (single line) which then gets displayed for the user to provide further details. This text input is a mandatory field only when it is visible - the javascript that shows / hides it also adds / removes the "required" attribute.

This NEARLY works ok. If I select "Other" from the dropdown, the textbox is displayed, if I don't enter a value there I get the validation error I'd expect. The problem is that if I select other, display the text field, put the focus in the text field and then tab out (so it is displaying the validation error message) and then select another value from the select list without entering a value in the text field. It hides the text field and removes the "required" attribute as expected. The form is then valid - if I click the submit button, it submits as expected.

The problem seems to be with the css (possibly from the Bootstrap validation?). After I select another value from the select list to hide the text field, the submit button remains in the "invalid" state ie greyed out and with the "No!" mouse pointer when I hover over it. If I click on it, it submits OK which suggests that it's working properly but it just doesn't look like it, which is not ideal from a user's perspective.

Looking at it in the browser's developer tools, I can see that the "disabled" class is still applied to the submit button after removing the "required" attribute from the text field despite the form being valid. I could potentially just put a bit of javascript into the change event shown above to remove that attribute when hiding this text field, but that would be a problem once there are other fields in the mix as even if this field is valid there may be other invalid fields on the page that require the submit button to be in the disabled state.

HTML and javascript:

  //add change event handler to TemplateName dropdown to show/hide textbox for "other" option $("#TemplateName").change(function() { if ($("#TemplateName").val() == "Other") { $("#TemplateNameTextGroup").show("fast"); $("#TemplateNameText").attr("required", true); } else { $("#TemplateNameText").removeAttr("required"); $("#TemplateNameTextGroup").hide("fast"); } }); 
 <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/1000hz-bootstrap-validator/0.11.5/validator.min.js"></script> <form id="MyForm" data-toggle="validator" action="Success.html"> <!--DROPDOWN WITH "OTHER" FREE TEXT OPTION (MANDATORY)--> <div class="row"> <div class="form-group col-xs-6"> <label for="TemplateName">Template Name</label> <select class="form-control" id="TemplateName" data-error="This is a mandatory field" required> <option value="">Please select...</option> <option value="Option 1">Option 1</option> <option value="Option 2">Option 2</option> <option value="Option 3">Option 3</option> <option value="Option 4">Option 4</option> <option value="Other">Other</option> </select> <div class="help-block with-errors"></div> </div> <div class="form-group col-xs-6" id="TemplateNameTextGroup" style="display:none;"> <label for="TemplateNameText">Provide Details</label> <input type="text" class="form-control" id="TemplateNameText" data-error="Please provide details" /> <div class="help-block with-errors"></div> </div> <div class="help-block with-errors"></div> </div> <button type="submit" id="submitButton" class="btn btn-default">Submit</button> </form> 

If you using show() & hide() methods in any scripting language, its going to be make style(CSS) changes.ie display will be either none or show. So basically DOM element will be loaded and there will be only style changes based on show or hide. Instead of this don't load the DOM element in script.

I've found (kind of) a solution to this issue. Basically I explicitly fire off the blur event on the textbox immediately after removing the required attribute. This then forces the validation to check that field again, it then notices that the field is not required, and thus a blank value is valid, and thus puts the submit button into its valid state.

Updated javascript:

 //add change event handler to TemplateName dropdown to show/hide textbox for "other" option $("#TemplateName").change(function() { if ($("#TemplateName").val() == "Other") { $("#TemplateNameTextGroup").show("fast"); $("#TemplateNameText").attr("required", true); } else { $("#TemplateNameText").removeAttr("required"); $("#TemplateNameText").blur(); $("#TemplateNameTextGroup").hide("fast"); } }); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM