How to properly validate Twitter's Bootstrap form placed on several tabs with jQuery Validate?

情到浓时终转凉″ 提交于 2019-12-20 10:40:05

问题


I have one form located on several Twitter's Bootstrap tabs:

<form id="personal-data" class="form-horizontal">
  <div class="tabbable">
    <ul id="tab" class="nav nav-tabs">
      <li class="active"><a href="#home" data-toggle="tab">Home</a></li>
      <li class=""><a href="#profile" data-toggle="tab">Profile</a></li>
      <!-- ... -->
    </ul>

    <div id="myTabContent" class="tab-content">
      <div class="tab-pane fade active in" id="home">
        <fieldset>
          <div class="control-group">
            <div class="controls">
              <input type="text" id="field1">
            </div>
          </div>
        </fieldset>
      </div>
      <div class="tab-pane fade" id="profile">
        <fieldset>
          <div class="control-group">
            <div class="controls">
              <input type="text" id="field2">
            </div>
          </div>
        </fieldset>          
      </div>

When I validate the form with jQuery validate on active tab and field with invalid value is on the same tab, then validation fails (which is correct). But when I am on one tab and invalid value is on another tab, then validation returns true, which is incorrect. How can I fix it? How can I highlight that field on another tab?

Please see this demo (just press button next - it will show error message, then go to last tab and press finish there).


回答1:


I think your problem lies in the fact that validation occurs in visible elements only.

Reading this issue we see that on version 1.9

Fixed #189 - :hidden elements are now ignored by default

and a solution a few comments down

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



回答2:


My solution to enable tabs

...
highlight: function(label) {
        $(label).closest('.control-group').addClass('error');

        $(".tab-content").find("div.tab-pane:hidden:has(div.error)").each( function(){
            var id = $(this).attr("id");
            $('#tabs a[href="#'+id+'"]').tab('show');
        });
},
...

Is necessary that you add this code to allow change tab by js

$('a[data-toggle="tab"]').on('shown', function (e) {
  e.target // activated tab
  e.relatedTarget // previous tab
});



回答3:


thanks for your code it solved most of my problem, except the part to navigate to first tab with error. I got around as follows:

        var IsValid = true;

        // Validate Each Bootstrap tab
        $(".tab-content").find("div.tab-pane").each(function (index, tab) {
            var id = $(tab).attr("id");
            $('a[href="#' + id + '"]').tab('show');

            var IsTabValid = $("#SomeForm").valid();

            if (!IsTabValid) {
                IsValid = false;
            }
        });

        // Show first tab with error
        $(".tab-content").find("div.tab-pane").each(function (index, tab) {
            var id = $(tab).attr("id");
            $('a[href="#' + id + '"]').tab('show');

            var IsTabValid = $("#SomeForm").valid();

            if (!IsTabValid) {
                return false; // Break each loop
            }
        });



回答4:


Are these jQuery tabs you're using? You can deactivate all other tabs and gradually activate them while the submitted data on each form pass the validation. Disable them all but the first in your constructor and after each validation enable the next.

.tabs( "enable" , index )

Read more here.

You could also put one final validation method in the end and put all your content visible depending on the tabs so you can escape the reloading of the links.




回答5:


Building upon @juanmanuele's answer, this is how I managed to get it working with Bootstrap 3 tabs:

if($(".tab-content").find("div.tab-pane.active:has(div.has-error)").length == 0)
{
    $(".tab-content").find("div.tab-pane:hidden:has(div.has-error)").each(function(index, tab)
    {
        var id = $(tab).attr("id");

        $('a[href="#' + id + '"]').tab('show');
    });
}

To place focus on the 1st input with error:

$('a[data-toggle="tab"]').on('shown.bs.tab', function(e)
{
     e.target // activated tab

     $($(e.target).attr('href')).find("div.has-error :input:first").focus();

     //e.relatedTarget // previous tab
});



回答6:


Not exactly the solution for jQuery Validate, but you could use the "invalid" event on form elements, to catch HTML5 validation errors, and get the focused element, find the respectively tab-pane, and show it.

I have done this.

$("form").find("input, select").on("invalid", function() {
  var id = $(this).parents(".tab-pane").attr("id");

  $("#tabs-selector ul").find("li a[href='#" + id + "']").tab("show");
});

Hope this helps you. Again, this is for HTML5 or if jQuery Validate fires an invalid event.



来源:https://stackoverflow.com/questions/10145131/how-to-properly-validate-twitters-bootstrap-form-placed-on-several-tabs-with-jq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!