skip to Main Content

I am trying to write validation for the user changing the dates by using the up/down arrows on the date fields. The issue comes with how the element simply returns an empty string when it reaches an invalid date, there is no distinction on which value change (day, month, or year) caused the invalid value. Is there a way to know which value was modified?

I have written handlers for if the user would change the date/month into an invalid value (such as if they press the up arrow while being on the month value of 01/31/2023, it becomes 02/28/2023) by using the previous value, but the issue comes in the scenario for increasing the year value while being on 02/29 on a leap year and increasing the date both would cause an empty string, so using the previous value is not enough information to ascertain which value caused the error and thus which result I should expect (02/01/{same year} if the date was increased or 02/28/{non-leap year} if the year was increased/decreased).

I have been reading the documentation for , but I can’t find a way to check which value was changed. It would seem that it should be possible since the component itself knows which value to increase/decrease when the user changes it with the up/down arrow or by typing.

2

Answers


  1. event to detect when the up/down arrows

    const handleDateKeydown = (event) => {
      const { selectionStart, selectionEnd, value } = event.target;
      
      if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
        if (selectionStart < 5 && selectionEnd > 2) {
          // day value is selected
          // handle accordingly
        } else if (selectionStart < 8 && selectionEnd > 5) {
          // month value is selected
          // handle accordingly
        } else if (selectionStart < 11 && selectionEnd > 8) {
          // year value is selected
          // handle accordingly
        }
      }
    };
    

    listen for the change event

    let previousValue = '';
    
    const handleDateChange = (event) => {
      const currentValue = event.target.value;
      
      if (currentValue === '') {
        // handle invalid date
        return;
      }
      
      // determine which value was modified
      const currentValueParts = currentValue.split('-');
      const previousValueParts = previousValue.split('-');
      
      if (currentValueParts[0] !== previousValueParts[0]) {
        // year was modified
        // handle accordingly
      } else if (currentValueParts[1] !== previousValueParts[1]) {
        // month was modified
        // handle accordingly
      } else {
        // day was modified
        // handle accordingly
      }
      
      previousValue = currentValue;
    }
    
    Login or Signup to reply.
  2. Yes, you can use the onkeydown event to detect which value of the date is being changed by a keypress for an element of type date.

    Here’s an example of how to do it:

    html

    <input type="date" id="myDateInput" onkeydown="handleKeyDown(event)">
    

    In the above code, we have added an onkeydown attribute to the element and set it to call a function called handleKeyDown when a key is pressed.

    function handleKeyDown(event) {
      const input = event.target;
      const key = event.key;
    
      if (key === 'ArrowUp' || key === 'ArrowDown') {
        const parts = input.value.split('-');
        const year = parseInt(parts[0]);
        const month = parseInt(parts[1]) - 1;
        const day = parseInt(parts[2]);
    
        const date = new Date(year, month, day);
    
        if (input.selectionStart <= 4) {
          // Year value is being changed
          date.setFullYear(date.getFullYear() + (key === 'ArrowUp' ? 1 : -1));
        } else if (input.selectionStart >= 8) {
          // Day value is being changed
          date.setDate(date.getDate() + (key === 'ArrowUp' ? 1 : -1));
        } else {
          // Month value is being changed
          date.setMonth(date.getMonth() + (key === 'ArrowUp' ? 1 : -1));
        }
    
        input.value = date.toISOString().slice(0, 10);
        event.preventDefault();
      }
    }
    

    In the handleKeyDown function, we first get a reference to the input element and the key that was pressed. We then split the input value into its year, month, and day components using the dash (-) separator.

    Next, we create a new Date object using the year, month, and day components. We then use the selectionStart property of the input element to determine which part of the date is being changed.

    If the selection start position is less than or equal to 4, then we know that the year value is being changed. If the selection start position is greater than or equal to 8, then we know that the day value is being changed. Otherwise, the month value is being changed.

    Finally, we update the date object based on the key that was pressed, update the input value with the new date value, and prevent the default action of the keypress event to avoid any unwanted behavior.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search