skip to Main Content

I have a start date/time and end date/time field on a form, using type="datetime-local"

I’d like the End Date/Time MIN value to be set to the start Date/Time value.

I can set the min date value with the following script, but the time portion does not work. Looking at the page code once the first value is set, I do see the full value being set (For example: min="2024-11-13T18:55"). However, the date picker is not limiting the time.

           
                          
let fDate = document.querySelector('#start');
let tDate = document.querySelector('#end');

fDate.addEventListener('change', function() {
  tDate.min = this.value;
});
                            $(document).ready(function(){
  $('.first').keyup(function(){
    var a = $(this).val();
    $('.second').attr('min',a);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<form>
<label>Start Date</label><br>
<input type="datetime-local" class="" name="startDate" id="start" value="">
<br>
<label>End Date</label><br>
<input type="datetime-local" class="" name="issueDate" id="end" value="">
</form>

2

Answers


  1. that’s the way it is:
    native date picker does not limit the time.

    You can use form validation (with required) to detect this error:

    const myForm = document.querySelector('#my-form');
    
    myForm.start_date.addEventListener('change', e =>
      {
      myForm.end_date.min = myForm.start_date.value;
      });
    
    myForm.addEventListener('submit', e =>
      {
      e.preventDefault();  // just for test, avoid page reload.
      })
    label { 
      display   : block;
      margin    : 1rem;
      font-size : .8rem;
      }
    label > input {
      display   : block;
      font-size : 1rem;
      }
    <form id="my-form">
      <label>
        Start Date
        <input type="datetime-local" name="start_date" required>
      </label> 
      <label>
        End Date
        <input type="datetime-local" name="end_date" required>
      </label> 
      <button>submit</button>
    </form>

    You may also use a custom date picker (search on gitHub).

    Login or Signup to reply.
  2. Details are commented in example.

    // Reference the <form>
    const ui = document.forms.schedule;
    // Reference all form fields under <form> (ex. all <input>s)
    const io = ui.elements;
    // Collect both <input name="dateTime"> into an array
    const dT = Array.from(io.dateTime);
    
    /**
     * https://stackoverflow.com/a/61082536/2813224
     *
     * Convert a given Date object/string into a Date string that is
     * formatted to match values from <input type="datetime-local">,
     * YYYY-MM-DDTHH:mm.
     * @param {object|string} date - A Date object or valid string
     * @return {string}              A string formatted as: 
     *                               YYYY-MM-DDTHH:mm
     */
    function getLocaleDT(date) {
      // If nothing is passed, then create a Date object for now.
      let d = !date ? new Date() : new Date(date);
      /*
        Get the diff between minutes (0 - 59) and TZ
        Set the diff as the current minutes in local TZ
      */
      d.setMinutes(d.getMinutes() - d.getTimezoneOffset());
      // Return YYYY-MM-DDTHH:mm string
      return d.toISOString().slice(0, 16);
    }
    
    /**
     * When event handler is triggered it will adjust 
     * <input id="deadLine"> value to the value of <input id="startDay"> 
     * if <input id="deadLine"> value is less than <input id="startDay">
     * @param {object} e - Event object
     */
    function dateTimeRange(e) {
      // Get the value of <input id="startDay"> (aka dT[0])
      let min = new Date(dT[0].value);
      // Get the value of <input id="deadLine"> (aka dT[1])
      let max = new Date(dT[1].value);
    
      // If the user unfocused from an <input> having the [name="dateTime"]...
      if (e.target.name === "dateTime") {
        // if d[0].value is greater tahn d[1].value...
        if (min > max) {
          // adjust the value of dT[1] to match the value of dT[0]
          max = min;
          dT[1].value = getLocaleDT(min);
        }
      }
    }
    
    /**
     * https://stackoverflow.com/a/1214753/2813224
     *
     * This eventListener is triggered when the DOM has finished loading.
     * It will get the current datetime and set d[0].value with it.
     * Then it sets d[1].value with d[0].value + 30 min.
     * @param {object} e - Event object
     */
    document.addEventListener("DOMContentLoaded", function(e) {
      let now = getLocaleDT();
      dT[0].value = now;
      now = new Date(now);
      const halfHour = new Date(now.getTime() + 30 * 60000);
      dT[1].value = getLocaleDT(halfHour);
    });
    
    // When the user unfocuses on <form>,  dateTimeRange(e) will be called.
    ui.addEventListener("change", dateTimeRange);
    :root {
      font: 3ch/1.2 "Segoe UI";
    }
    
    label {
      display: block;
      margin: 0.25rem 0;
    }
    /**
     * Inset shadow-box
     * https://codepen.io/vanss472/pen/QvGMaw?editors=0100
     */
    input {
      display: block;
      width: 12rem;
      margin: 0.25rem 0;
      padding: 0.6rem 0.1rem 0.7rem;
      border: 1px solid #d1d1d1;
      outline: none;
      font: inherit;
      color: #525865;
      box-shadow: inset 0px 1px 8px rgba(0, 0, 0, 0.2);
      transition: 0.2s ease-out;
    }
    
    input:hover {
      box-shadow: inset 1px 2px 8px rgba(0, 0, 0, 0.02);
    }
    
    input:focus {
      border: 1px solid #B8B6B6;
      color: #4b515d;
      box-shadow: inset 1px 2px 4px rgba(0, 0, 0, 0.01), 0px 0px 8px rgba(0, 0, 0, 0.2);
    }
    <!-- 
      Assign the same [name] to both <input>s so they can be easily
      collected into an array
        ex. <input name="dateTime">
    -->
    <form id="schedule">
      <label for="startDay">Start Date</label>
      <input id="startDay" name="dateTime" type="datetime-local">
      <label for="deadLine">End Date</label>
      <input id="deadLine" name="dateTime" type="datetime-local">
    </form>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search