代码之家  ›  专栏  ›  技术社区  ›  ramganesh

使用jquery验证验证focusout上的日期字段

  •  2
  • ramganesh  · 技术社区  · 8 年前

    第一次选择日期时,日期输入字段无效。
    它显示所需的错误消息,因为字段具有空值( 检查控制台日志 )中。但字段在第二次更改时有效。

    注意:原因之一是日期输入字段在选择日期时失去焦点(单击事件)。但是,只有在单击事件发生后才填充日期。但验证器将在focus out事件上验证字段。

    我正在使用 Jquery Validation ,使用 bootstrap-datepicker 对于小部件。

    ^^为了获得更好的UX,请在整页上运行代码片段;) 或 jsfiddle

    从@sparky/@vignesh ans:是的,这是一个解决方法,我们可以使用change/hide/changedate(模块属性)事件处理程序。一旦设置了输入值,它就会被触发。 但问题是,每当我们选择年-月-日期时,每次单击选择器,都会从输入中移除焦点并触发FocusOut事件并显示错误消息,直到选择日期为止。

    它不像选择域那样平坦。在选项字段中,在从字段小部件中选择选项之前,不会触发FocusOut事件。像这样,我们如何在不看到错误消息的情况下移动年/月/日选项?是的。

    查询: &安培 HTML格式

        $(function() {
          $("#editEventForm").validate({
            rules: {
              full_name: {
                required: true,
              },
              event_date: {
                required: true,
              },
            },
            messages: {
              full_name: "Please enter your full name!",
              event_date: "Please enter valid date!",
            },
            highlight: function(element, errorClass) {
              var e = $(element);
              e.closest('.has-feedback').removeClass('has-success').addClass('has-error');
            },
            unhighlight: function(element, errorClass) {
              var e = $(element);
              e.closest('.has-feedback').removeClass('has-error').addClass('has-success');
            },
            onfocusout: function(element) {
              console.log("element value --> ", $(element).val());
              return $(element).valid();
            },
          });
          $('#eventDate').datepicker({
            autoclose: true,
          }).on('change', function() {
            $(this).valid(); // triggers a validation test
            // $(this) refers to $('#eventDate')
          });
    
        });
    .has-error :focus {
      border-color: #f84545 !important;
    }
    .error {
      color: #f84545;
    }
    <link id="bs-css" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
    <link id="bsdp-css" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.css" rel="stylesheet">
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.17.0/dist/jquery.validate.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.7.1/js/bootstrap-datepicker.min.js"></script>
    
    
    
    <form id="editEventForm">
      <div class="form-group">
        <div class="has-feedback">
          <label for="eventDate">Full Name * </label>
          <input class="form-control" id="fullName" name="full_name" type="text">
        </div>
        <div class="has-feedback">
          <label for="eventDate">Event Date * </label>
          <input class="form-control" id="eventDate" name="event_date" placeholder="MM/DD/YYYY" type="text">
        </div>
      </div>
      <input type="submit" value="ClickMe">
    </form>
    4 回复  |  直到 8 年前
        1
  •  2
  •   Vignesh Raja    8 年前

    TL;博士 :单击事件将焦点移动到单击的元素。因此,在选择器中单击日期时,将焦点从输入中移除,并 focusout 已触发事件。在设置输入值之前,选择器执行各种操作。因此,值在上保持为空 聚焦 是的。因此警报仍保留在ui中。

    解释 :点击/聚焦 date 字段, datepicker 打开。真正的问题发生在您单击 日期 日期选择器 是的。单击它后,您可以看到日期字段立即松开焦点(闪烁的插入符号消失)。按照我们的配置,选择器立即关闭 autoclose:true 是的。下面是在DatePicker中编写的隐藏功能。

    hide: function() {
            return this.isInline || !this.picker.is(":visible") ? this : (this.focusDate = null,
            this.picker.hide().detach(),
            this._detachSecondaryEvents(),
            this.setViewMode(this.o.startView),
            this.o.forceParse && this.inputField.val() && this.setValue(),
            this._trigger("hide"),
            this)
    
    1. 把扒手藏起来。
    2. detach() 使关联的元素被移除,保持元素细节不变,以防再次插入元素。
    3. 从日期选择器中删除附加的次要事件。
    4. 将viewmode设置为已配置的模式(因为我们的问题中没有配置viewmode,所以它设置为默认模式)。
    5. 分析选定值并将分析结果设置为输入框。
    6. 运行在选项中配置的自定义回调(如果有)

    所以在设置输入中的值之前 onfocusout 事件被触发。由于当时没有值,所以显示错误。

    为了防止这种情况发生,添加 hide 选取器中的事件处理程序(如下所示),并从此处处理相同的验证。一旦设置了输入值,就会触发此自定义事件处理程序(如上所述)。

    $(function() {
      $("#editEventForm").validate({
        rules: {
          full_name: {
            required: true,
          },
          event_date: {
            required: true,
          },
        },
        messages: {
          full_name: "Please enter your full name!",
          event_date: "Please enter valid date!",
        },
        onfocusout: function(element) {
            $(element).valid();
        },
      });
      $('#eventDate').datepicker({
        autoclose: true,
        orientation: "bottom right"
      }).on("hide",function(){
          $("#editEventForm").data("validator").settings.ignore="";
          $(this).valid();
      }).on("focus",function(){
          $("#editEventForm").data("validator").settings.ignore="#eventDate, :hidden";
      });
    });
    <link id="bs-css" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
    <link id="bsdp-css" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.css" rel="stylesheet">
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.17.0/dist/jquery.validate.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.7.1/js/bootstrap-datepicker.min.js"></script>
    
    
    
    <form id="editEventForm">
      <div class="form-group">
        <div>
          <label for="eventDate">Full Name * </label>
          <input class="form-control" id="fullName" name="full_name" type="text">
        </div>
        <div>
          <label for="eventDate">Event Date * </label>
          <input class="form-control" id="eventDate" name="event_date" placeholder="MM/DD/YYYY" type="text">
        </div>
      </div>
      <input type="submit" value="ClickMe">
    </form>

    编辑 :如前所述,我们无法阻止 聚焦 射击事件。但这一要求可以通过变通方法来实现。

    集中注意力, ignore 验证和 隐藏 ,删除忽略的验证并验证。

    为了清楚起见,忽略通过

    $("#editEventForm").data("validator").settings.ignore="#eventDate, :hidden";`
    

    ( :hidden 是默认值,因此不要忽略它)。在验证期间,插件在内部使用jquery not 用于忽略元素的选择器。在隐藏日期选择器(通过选择date/clickoutside)时,从配置中删除元素并应用验证。

        2
  •  2
  •   ramganesh    8 年前

    简化@vignesh解决方案。

    我们可以跳过现场验证 onfocusout ,然后我们就开始了 hide 事件

    // here we can skip the validation
    onfocusout: function(element) {
      var elementId = element.getAttribute('id');
      if (elementId === "eventDate") {
        // datepicker widget - don't do validation on focusout event
        return false;
      }
      return $(element).valid();
    },
    
    
    // here we can do the validation
    $('#eventDate').datepicker({
      autoclose: true,
    }).on('hide', function() {
      // datepicker - on hide do the field validation
      $('#eventDate').valid();
    });
    

    Jsfiddle

        3
  •  1
  •   Sparky    8 年前

    问题不能是 closed as duplicate 因为赏金。

    jquery validate插件会自动触发一个验证测试,测试正常表单输入字段的focus out和key up,并且不能很好地使用日期选择器。

    无论何时选择日期,都必须以编程方式触发验证:

    $('#eventDate').datepicker({
        autoclose: true,
        // endDate: '+45d', // show current date - next 45 days
    }).on('change', function() {
        $(this).valid();  // triggers a validation test
        // $(this) refers to $('#eventDate')
    });
    
        4
  •  -2
  •   L0uis    8 年前

    您可以在日期选择器中设置首次加载时的日期。

    $('#eventDate').datepicker({
                    autoclose: true 
                }).datepicker("setDate", 'now');