【问题标题】:Bootstrap 3 validation states with JQuery-validated form that uses Chosen pluginBootstrap 3 验证状态,带有使用 Chosen 插件的 JQuery 验证表单
【发布时间】:2015-08-13 09:51:49
【问题描述】:

上下文

  • 我有一个使用JQuery Validate Plugin 验证的表单。
  • 除了 textarea 之外,所有表单控件都是必需的。
  • 我正在使用 Bootstrap 3 验证状态来设置正在验证的表单控件的样式。
  • 对于选择控件,我使用的是Chosen Select Plugin

问题

我无法弄清楚如何解决以下问题:

1- 防止 textarea 控件应用成功验证状态,因为此表单控件未经过验证,因为它是可选的。

(要在下面的 JSFiddle 中重现问题,请单击带有空表单的提交按钮)

2- 将错误验证状态应用到下拉列表的边框。现在只有标签应用了错误验证状态。

3 - 删除错误验证状态和错误消息,并在用户从下拉列表中选择一个选项时应用成功类。现在错误消息和错误类仍然存在。

一个 JSFiddle

我创建了一个JSFiddle 来说明问题。

HTML

<div class="container" role="main">
    <!-- Contents of the popover associated with the task name text input -->
    <div id="namePopoverContent" class="hide">
        <ul>
            <li><small>...</small></li>
            <li><small>...</small></li>
        </ul>
    </div>

    <form class="form-horizontal" method="post" action="" id="taskForm">
        <div class="row">
            <div class="col-md-9">
                <div class="form-group">
                    <label for="taskName" class="control-label col-md-1">Name</label>
                    <div class="col-md-11">
                        <input type="text" class="form-control taskNameValidation" id="taskName" name="taskName" autofocus required data-toggle="popover">
                    </div>
                </div>
            </div>
            <div class="col-md-3"></div>
        </div>

        <div class="row">
            <div class="col-md-9">
                <div class="form-group">
                    <label for="taskDataset" class="col-md-1 control-label">Dataset</label>
                    <div class="col-md-11">
                        <select class="form-control chosen-select taskDatasetValidation" data-placeholder="Choose a dataset" name="taskDataset" id="taskDataset" required>
                            <option value=""></option>
                            <option value="runnableDataset_Id1">Dataset 1</option>
                            <option value="runnableDataset_Id2">Dataset 2</option>
                            <option value="runnableDataset_Id3">Dataset 3</option>
                            <option value="runnableDataset_Id4">Dataset 4</option>
                        </select>
                    </div>
                </div>
            </div>
            <div class="col-md-3"></div>
        </div>
        <div class="row">
            <div class="col-md-9">
                <div class="form-group">
                    <label for="taskDescription" class="col-md-1 control-label">Description</label>
                    <div class="col-md-11">
                        <textarea class="form-control" name="taskDescription" id="taskDescription" maxlength="1000" rows="4"></textarea>
                    </div>
                </div>
            </div>
            <div class="col-md-3"></div>
        </div>
        <div class="row">
            <div class="col-md-9">
                <div class="pull-right top-margin">
                    <input type="submit" class="btn btn-primary btn-sm" value="Submit" name="taskSetUpSubmit">
                </div>
            </div>
            <div class="col-md-3"></div>
        </div>
    </form>

JS

//Bootstrap popover
$('[data-toggle="popover"]').popover({ 
    trigger: "hover focus",
    container: "body",
    placement: "bottom",
    html: true,
    title: "Name Tips",
    content: function() { return $('#namePopoverContent').html();}
});

//Chosen select plugin
$(function() {
    $('.chosen-select').chosen();
    $('.chosen-select-deselect').chosen({ allow_single_deselect: true });
});

//JQuery validate plugin
$(function() {
    $.validator.setDefaults({
        errorClass: 'text-danger',
        ignore: ':hidden:not(.chosen-select)',
        errorPlacement: function (error, element) {
            if (element.hasClass('chosen-select'))
                error.insertAfter(element.siblings(".chosen-container"));
            else {
                error.insertAfter(element);
            }
        }
    });

    //rules and messages objects
    $("#taskForm").validate({
        highlight: function(element) {
            $(element).closest('.form-group').removeClass('has-success').addClass('has-error');
        },
        unhighlight: function(element) {
            $(element).closest('.form-group').removeClass('has-error').addClass('has-success');
        }
    });

    $('.taskNameValidation').each(function() {
        $(this).rules('add', {
            required: true,
            messages: {
                required: "Provide a space-separated name"
            }
        });
    });

    $('.taskDatasetValidation').each(function() {
        $(this).rules('add', {
            required: true,
            messages: {
                required: "Choose a dataset"
            }
        });
    });
});

我一直在努力解决这个问题,但没有任何运气。任何帮助将不胜感激。

【问题讨论】:

    标签: jquery twitter-bootstrap jquery-validate jquery-chosen


    【解决方案1】:
    1. 防止 textarea 控件应用成功验证状态,因为此表单控件未经过验证,因为它是可选的。

      空的textarea 是“有效的”,因为您的验证表明空字段是有效的,因此它是绿色的。您可以有条件地使用highlightunhighlight,这样它就不会应用于您的textarea。但是,当评估您的 maxlength 规则时,它将不起作用。 我知道没有解决方法会导致unhighlight 在该字段在技术上“有效”但仍为空时被忽略。 此插件中没有提供“可选”条件/状态...一旦表单被评估,字段要么是“有效”,要么是“无效”,两者之间没有任何关系。

      编辑:您可以使用自定义:blank 选择器有条件地在textarea 上应用highlightunhighlight,并将一个类应用到这个“可选”元素。然后,您仍然会看到红色和绿色的轮廓,但只有在填写此“可选”字段和/或评估您的规则时。

      highlight: function (element) {
          if (! ($(element).hasClass('optional') && $(element).is(':blank'))) {
              $(element).closest('.form-group').removeClass('has-success').addClass('has-error');
          }
      },
      unhighlight: function (element) {
          if (! ($(element).hasClass('optional') && $(element).is(':blank'))) {
              $(element).closest('.form-group').removeClass('has-error').addClass('has-success');
          }
      }
      
    2. 将错误验证状态应用到下拉列表的边框。现在只有标签应用了错误验证状态。

      您需要查看渲染的 DOM 并找到动态创建的 Chosen 元素。然后你需要编写 jQuery 来遍历这个元素,并通过highlightunhighlight 有条件地应用适当的类。

      highlight: function (element) {
          if ($(element).hasClass('chosen-select')) {
              $(element).siblings('.chosen-container').removeClass('has-success').addClass('has-error');
          }
          $(element).closest('.form-group').removeClass('has-success').addClass('has-error');
      },
      unhighlight: function (element) {
         if ($(element).hasClass('chosen-select')) {
             $(element).siblings('.chosen-container').removeClass('has-error').addClass('has-success');
         } 
         $(element).closest('.form-group').removeClass('has-error').addClass('has-success');
      }
      

      上面的这段代码has-errorhas-success类应用于渲染的Chosen div元素;你只需要调整你的 CSS 以便有一个红色边框。否则,请为此编写自己的 CSS 类,就像我在下面的演示中所做的那样。相应调整。

    3. 删除错误验证状态和错误消息,并在用户从下拉列表中选择一个选项时应用成功类。

      您必须编写一个change 处理程序,该处理程序在每次更改时调用select 元素上的.valid() 方法。这是因为您正在与呈现的选择列表而不是实际的 select 元素进行交互。否则,无法正确触发 jQuery Validate 插件。

      $('.chosen-select').on('change', function () {
          $(this).valid();
      });
      

    演示:https://jsfiddle.net/jxvqsodz/7/

    【讨论】:

    • 非常感谢您的帮助。我是所有 Web 开发技术的新手,非常感谢您的详细解释。
    • @user2669241,不客气。感谢您抽出宝贵时间正确撰写您的问题。
    • 这可能是一个愚蠢的问题,但我还是会问。你说“你需要查看渲染的 DOM 并找到动态创建的 Chosen 元素”,这是有道理的,但我该怎么做呢?当时调试时,我查看了页面源代码,但我只能看到我在代码中可以看到的内容:静态创建的控件。我想我的问题是如何调试动态创建的元素。谢谢!
    • @user2669241:我不能更具体,因为所有浏览器都有不同的工具和 GUI。但是,在浏览器的开发人员工具中,有一个选项可以检查 DOM,而不是源代码。
    • 谢谢!我会调查的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-27
    相关资源
    最近更新 更多