skip to Main Content

I have a regular input field with input HTML that allows users to enter a time range (minutes and seconds). From 5 seconds to 20 minutes.

However, there are error in the field that I would like to correct. As you can see, the field allows you to enter any number of zeros before the number. Please tell me how this situation can be handled so that the user can enter a maximum of two characters in the field? That is, the field would accept a value from the user in the format: 00 or 05 or 5 or 10. But do not allow 0000 or 00005 or 010.

    const limitValue = (min, max, val) => Math.min(max, Math.max(min, val));

export default function App() {
  const [value, setValue] = useState(10);
  const onInput = useCallback(
    (val, minutes) =>
      setValue((prev) =>
        limitValue(
          5,
          1200,
          minutes ? val * 60 + (prev % 60) : ~~(prev / 60) * 60 + val
        )
      ),
    []
  );
  return (
    <div>
      <span>
        <input
          type="number"
          min={0}
          max={20}
          value={~~(value / 60)}
          onInput={({ target: { value } }) => onInput(+value, true)}
        />
        m
      </span>
      <span>
        <input
          type="number"
          min={-1}
          max={60}
          value={value % 60}
          onInput={({ target: { value } }) => onInput(+value)}
        />
        s
      </span>
    </div>
  );
}

2

Answers


  1. This is probably a terrible way to fix the problem (why I have no idea why it would be bad)… All I know is it works and I haven’t noticed any real performance degredation by using it.
    Wrap the value prop in parenthesees and call the .toString() method on both of your value props like this
    value={(~~(value / 60)).toString()} and
    value={(value % 60).toString()} respectively.

    This works because we are changing it to a string value which changes how 05 and 5 are perceived and therefore must be parsed back into the respective value… Which ultimately has the input rerender with the value you want.

    Login or Signup to reply.
  2. You could change the value field of the first input as follows. Converting a number primitive to a string primitive will immediately chop off any leading zeros, and then you can pad back extra zeros.

    value={(~~(value / 60)).toString().padStart(2, 0)}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search