KeyPress events across multiple browsers/devices

Key events doesn't works as expected in safari and mobile browsers. So have some tips here...

One day I had to work on a feature called DateTimeSelector and it needs to be Mobile optimised. You may think whats the challenging part here, I would say the whole feature was challenging for me because the key events plays the major role & it doesn't work on major browsers as expected.

So today am going to explain how I struggled to work on keypress events in multiple browsers and devices.

Feature:

Need to select a Date Range, MM/DD/YYYY HH:mm:ss to MM/DD/YYYY HH:mm:ss

Requirements:

Let me explain the requirements of the feature first,

  1. Need to allow only numbers in input field
  2. Set the format for DateTime say MM/DD/YYYY HH:mm:ss
  3. Need to set days limit (DD) based on the MM value. Eg: If we type '03' for MM, max days limit (DD) will be '31' (as 31 days for March)
  4. If we enter a value greater than threshold value, need to replace that value with threshold value. Eg: If we type '14' for MM, the value will become '12' (threshold for MM is '12')
  5. After typing MM, need to append '/' char and follow the same for DD, YYYY, HH, ...
  6. Set maxLength

Now you may got idea why the key events are more important to get work this feature. And am not going to explain the whole coding of this feature. I will just give some tips where I spent most of my time while working for this feature.

Tips:

Type="number"

To allow only numbers in input, add type="number"

<input type="number">

In Desktop Browsers

  • Safari allows char also (for older versions)
  • maxLength would not work
  • unable to detect cursor position

In Mobile Browsers

  • Opens numeric keypad
  • Cursor position is unable to detect

Type="text"

add input type="text" and allow input values based on regex else use event.preventDefault()

<input type="text">
const onKeyPress = ($event) => {
     if (!/^[0-9]$/.test($event.key)) {
        $event.preventDefault()
      }
}

In Desktop Browsers

  • working as expected

In Mobile Browsers

  • keypress event not even detected
  • maxlength not working properly

Type="tel"

<input type="tel">

In Desktop Browsers

  • working as expected

In Mobile Browsers

  • keypress event is detected
  • opens numeric pad
  • maxlength supported

Suggestion:

My suggestion is to use type="text" for desktop and type="tel" for mobile

Sample code for vue

<input
    :type="$isDesktop ? 'text' : 'tel"
    @keypress="onPress"
    :maxlength="10"
/>
methods: {
    onPress ($event) {
        if (!/^[0-9]$/.test($event.key)) {
            $event.preventDefault()
        }
    }
}