admin管理员组

文章数量:1323335

Date Input Field not valid, When first time selecting the date.
Its showing required error message, because of field have an empty value(check console log). But field will be valid on second change.

Notes: A cause is that date input field loses focus when picking the date (click event). But the date populates only later changed when the click event happens. But validator will validate field on focus out event.

I'm validating a form using Jquery Validation, using bootstrap-datepicker for Widget.

^^for Better UX Run code snippet on full-page ;) or jsfiddle

from @Sparky / @Vignesh ans: Yes, its a workaround for this, We can use change/hide/changeDate(module attribute) event handler. It gets triggered once the input values have been set. But the problem is whenever we pick from year->month->date each clicks in the picker, removes focus from input and focusout event fired and showing the error message until choosing the date.

It's not flat like choice field. in choice field there is no focusout event triggered until choosing the option from field widget. Like this, How can we move around the year/month/date options without seeing error message?.

jQuery: & 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=".0.3/css/bootstrap.min.css" rel="stylesheet">
<link id="bsdp-css" href=".8.0/css/bootstrap-datepicker.css" rel="stylesheet">

<script src=".1.1/jquery.min.js"></script>
<script src="/[email protected]/dist/jquery.validate.js"></script>
<script src=".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>

Date Input Field not valid, When first time selecting the date.
Its showing required error message, because of field have an empty value(check console log). But field will be valid on second change.

Notes: A cause is that date input field loses focus when picking the date (click event). But the date populates only later changed when the click event happens. But validator will validate field on focus out event.

I'm validating a form using Jquery Validation, using bootstrap-datepicker for Widget.

^^for Better UX Run code snippet on full-page ;) or jsfiddle

from @Sparky / @Vignesh ans: Yes, its a workaround for this, We can use change/hide/changeDate(module attribute) event handler. It gets triggered once the input values have been set. But the problem is whenever we pick from year->month->date each clicks in the picker, removes focus from input and focusout event fired and showing the error message until choosing the date.

It's not flat like choice field. in choice field there is no focusout event triggered until choosing the option from field widget. Like this, How can we move around the year/month/date options without seeing error message?.

jQuery: & 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./bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<link id="bsdp-css" href="https://cdnjs.cloudflare./ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.css" rel="stylesheet">

<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/jquery.validate.js"></script>
<script src="https://cdnjs.cloudflare./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>

Share Improve this question edited Jul 3, 2018 at 11:20 ramganesh asked Jun 29, 2018 at 16:00 ramganeshramganesh 8111 gold badge10 silver badges33 bronze badges 3
  • Duplicate of this: stackoverflow./q/22335120/594235 – Sparky Commented Jul 2, 2018 at 16:12
  • @Sparky Yes, already I have gone through. But how can we move around year/month/date options without triggering the error message? – ramganesh Commented Jul 3, 2018 at 12:06
  • 1 @ramganesh Updated my answer. Pls have a look at it. – Vignesh Raja Commented Jul 6, 2018 at 5:38
Add a ment  | 

4 Answers 4

Reset to default 3 +50

TL;DR : Click event moves the focus to the clicked element. Hence on clicking the date in the picker, removes focus from input and focusout event fired. Before setting the input value, the picker performs various operations. Hence value remains empty on focusout. Hence the alert remains in the UI.

Explanation : On clicking/focusing the date field, datepicker opens. The real problem occurs when you click on the date in the datepicker. Once it is clicked you can see the date field looses the focus (the blinking caret disappears) immediately. The picker closes immediately as we configured autoclose:true. The following is the hide functionality written inside the 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. Makes the picker to hide.
  2. detach() makes the associated elements to be removed, keeping the element details untouched incase the elements are reinserted again.
  3. Removes the attached Secondary events from the datepicker.
  4. Sets the viewmode to the configured one (as it is not configured in our problem, it sets to the default one).
  5. Parses the selected value and sets the parsed result to the input box.
  6. Runs the custom callback (if any), configured in the options

So before setting the value in the input the onfocusout event gets fired. And as there is no value present at that time, the error is shown.

To prevent this from happening, add a hide event handler in the picker (as below), and handle the same validation from there. This custom event handler gets triggered once the input values has been set (as explained above).

$(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./bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<link id="bsdp-css" href="https://cdnjs.cloudflare./ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.css" rel="stylesheet">

<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/jquery.validate.js"></script>
<script src="https://cdnjs.cloudflare./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>

Edit : As already told, we cannot prevent focusout event from firing. But the requirement can be achieved with a workaround.

On focus, ignore the validation and on hide, remove the ignored validation and validate.

To be clear, ignore the validation for the specified element via

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

(:hidden is the default value, so don't omit it). During validation, the plugin internally uses the jQuery not selector to ignore elements. On hiding the datepicker (either by selecting date/clickoutside), remove the element from the config and apply validation.

Question can not be closed as duplicate because of bounty.

The jQuery Validate plugin automatically triggers a validation test on focus out and key up of normal form input fields, and do not work well with the date picker.

You'll have to programmatically trigger validation whenever you pick a date:

$('#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')
});

Simplifying the @Vignesh workaround.

We can skip the field validation onfocusout, and we do the validaion on hide event

// 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

You can set a date at first load in the date picker.

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

本文标签: javascriptValidate date field on focusout with jqueryvalidationStack Overflow