1

I've found a bunch of similar questions for this issue but none of their answers seems to work here. I have a Datepicker in a website where the input of a date is checked when the user is typing. It works well but I also want to have the date colored in realtime when the input is not valid. For that I need the id of the input field the Datepicker is associated with.

When using onClose function in Datepicker definiton, I get inst which is the instance of the current Datepicker object and by inst.id I get the field name. But this does not work in the parseDate function. I also can't pass on inst or make it global, because onClose is never executed before parseDate. I tried $(this).attr('id') as suggested somewhere but it returns undefined. My code (minimal example):

document.addEventListener("DOMContentLoaded", function () {
  $(function () {
    $(".dp").datepicker({
      showOn: "focus",
      showMonthAfterYear: false,
      dateFormat: "dd.mm.yy",
      onClose: function (dateText, inst) {
        console.log("field name : ", inst.id); //works, inst.id is 'startDate'.
        $("#" + inst.id + ".form-control.dp.hasDatepicker").css("color", "red"); //works, inst.id is 'startDate'.
      }
    });

    $.datepicker.parseDate = function (format, value, settings) {
      var field = $(this).attr("id"); //not working, field is null.
      $("#" + field + ".form-control.dp.hasDatepicker").css("color", "red"); //not working, field is null.
    };
  });
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<div class="row">
  <label class="col-sm-3 col-form-label">{{ __('Start') }}</label>
  <div class="col-sm-9">
    <div class="input-group-addon">
      <input type="text" class="form-control dp" id="startDate" name="start" value="">
      <span class="glyphicon glyphicon-th"></span>
    </div>
  </div>
</div>

12
  • Hi , can you make your code runnable ? Commented Jan 15, 2021 at 14:34
  • It's not necessary, the issue is obvious. Commented Jan 15, 2021 at 14:36
  • 1
    It is obvious to you... Which datepicker plugin are you using? Date picker list Commented Jan 15, 2021 at 14:53
  • 1
    @louys as per the tag mentioned by the user it should be jQuery-ui ... Just to help you Commented Jan 15, 2021 at 14:55
  • @LouysPatriceBessette Is there more than 1 Datepicker in jQuery? I am using api.jqueryui.com/datepicker ...and yes, the issue is well illustrated and does not need a runable version. Sorry there's no toy to play with, just a riddle to solve. Commented Jan 15, 2021 at 14:57

1 Answer 1

2

I would perform the date validity with a input event handler aside the date picker... Because that date check you wish to have is not a feature of datepicker.

So on input, evaluate the new Date value to add an .invalid class to the input like below:

$(document).ready(function () {
  $(".dp").datepicker({
    showOn: "focus",
    showMonthAfterYear: false,
    dateFormat: "dd.mm.yy"
  });

  $(".dp").on("input", function () {
  
    // Remove the class on each new input
    $(this).removeClass("invalid");

    let currentVal = $(this).val();
    console.log(currentVal);

    // Split the value
    let dateParts = currentVal.split(".");
    
    // If incomplete
    if (dateParts.length !== 3) {
      $(this).addClass("invalid");
      return;
    }

    // Create a date object to evaluate
    let validDate = new Date(`${dateParts[2]}-${dateParts[1]}-${dateParts[0]} 00:00:00`);
    console.log(validDate.toString());

    // If the date is "invalid" and does not have 4 digits for the year (because it could be valid anyway... But obviously wrong)
    if (validDate.toString() === "Invalid Date" || dateParts[2].length !== 4) {
      $(this).addClass("invalid");
    }
  });
});
.dp.invalid{
  color: red !important;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<div class="row">
  <label class="col-sm-3 col-form-label">{{ __('Start') }}</label>
  <div class="col-sm-9">
    <div class="input-group-addon">
      <input type="text" class="form-control dp" id="startDate" name="start" value="">
      <span class="glyphicon glyphicon-th"></span>
    </div>
  </div>
</div>

CodePen

Sign up to request clarification or add additional context in comments.

2 Comments

Okay, thanks, I get the idea. Out of curiosity: What is the difference between $(".dp").on("input", function(){ and $.datepicker.parseDate = function(format,value,settings){ ? And why do you prefer classes for coloring over my notation?
$(".dp").on("input", function(){ is an event handler. $.datepicker.parseDate = ... is assigning a function to the datepicker plugin... So it may overwrite an existing function and mess the picker. -- About the class .invalid, it's just easier to add or remove it than directly change the style attribute of the input. ALSO, you can now check is this class is present on submit... ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.