skip to Main Content

I have a simple code that allows the user to enter minutes and seconds (website is written in react).

<div>
  <span>
    <input defaultValue="0" maxlength="2"/>
  </span>
<span>m</span>
<span>
    <input defaultValue="10" maxLength='2' />
  </span>
  <span>s</span>
</div>

But I would like to improve my functionality and that’s why I’m turning to you.

Currently the user can enter any number <= 99 (and in the seconds column he can enter 99) and any characters, but I would like the user to be able to enter a time of at least 5 seconds and at most 20 minutes.

Tell me how to limit the entered characters to numbers only and limit the maximum and minimum entered time.

4

Answers


  1. You can validate it using onChange handler of input.

       <input value={month} maxlength="2" onChange={(e) => {
             validationFunc(e.target.value)
             setMonth(e.target.value);
        }}/>
    

    You can validate input data in validtionFunc.
    Thank you.

    Login or Signup to reply.
  2. You have to use an <input type="number" /> with the appropriate min and max.

    In order to achieve the limitation of > 5" and < 20', you need a bit of state logic:

    const { useState, useCallback } = React
    const limitValue = (min, max, value) => Math.min(max, Math.max(min, value))
    const App = () => {
      const [seconds, setSeconds] = useState(10)
      const [minutes, setMinutes] = useState(0)
      const handleMinutes = useCallback(({ target: { value } }) => {
        setMinutes(limitValue(0, 20, +value))
        if (!+value) {
          setSeconds(5)
        }
        if (+value === 20) {
          setSeconds(0)
        }
      }, [])
      const handleSeconds = useCallback(({ target: { value } }) => {
        if (+value === 60) {
          setMinutes((prev) => limitValue(0, 20, prev + 1))
          setSeconds(0)
        } else if (+value === -1) {
          setMinutes((prev) => limitValue(0, 20, prev - 1))
          setSeconds(59)
        } else {
          setSeconds(limitValue(0, 59, +value))
        }
      }, [])
      return (
        <div>
          <span>
            <input
              type="number"
              min={0}
              max={20}
              value={minutes}
              onInput={handleMinutes}
            />
            m
          </span>
          <span>
            <input
              type="number"
              min={minutes ? -1 : 10}
              max={60}
              value={seconds}
              onInput={handleSeconds}
            />
            s
          </span>
        </div>
      )
    }
    ReactDOM.createRoot(root).render(<App />)
    <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
    <div id="root"></div>
    Login or Signup to reply.
  3. Not fully tested but you could try an approach like this.

    Once you have set the input fields with the appropriate type attribute, such as type='number' and ensure that the min and max attributes are set to your criteria ( max 20mins, min 5sec ) you can then use a delegated listener bound to a suitable parent (the document in this case but could/should be more focused) that monitors the input event.

    The event handler identifies all the input elements of relevance ( by name here ) and performs some basic operations on the values of each to create a total time value in seconds. If that time value is beyond your limits warn the user &/or set your own default value.

    document.addEventListener('input',e=>{
      if( ['minutes','seconds'].includes( e.target.name ) ){
        
        const mapcallback=(n)=>n.name=='minutes' ? n.value * 60 : n.value;
        const reducecallback=(a,b)=>a+parseInt(b);
        /*
          find the numeric input elements,
          convert minutes to seconds and
          create sum of both mins & secs values.
        */
        let total=[...document.querySelectorAll('input[type="number"]')]
            .map( mapcallback )
            .reduce( reducecallback, 0 );
        
        /* warn the user if selected values are out of range.*/
        if( total < 5 ){
          console.log('Must be at least 5s');
        }
        if( total > 1200 ){
          console.log('Can be no more than 1200s / 20mins');
          document.querySelector('[name="seconds"]').value=0;
        }
      }
    });
    <div>
      <label>
        <input name='minutes' type='number' min=0 max=20 value=0 maxlength=2 />
        <span>m</span>
      </label>
      
      <label>
        <input name='seconds' type='number' min=5 max=59 value=5 maxlength=2 />
        <span>s</span>
      </label>
    </div>
    Login or Signup to reply.
  4. To do that with only Javascript and show an alert on invalid input:

      <form>
        <label for="minutes">Minutes:</label>
        <input type="number" id="minutes" min="0" max="20" oninput="validateTime()" required>
        
        <label for="seconds">Seconds:</label>
        <input type="number" id="seconds" min="0" max="59" oninput="validateTime()" required>
      </form>
    
      <script>
        function validateTime() {
          var minutes = parseInt(document.getElementById('minutes').value, 10);
          var seconds = parseInt(document.getElementById('seconds').value, 10);
    
          if (isNaN(minutes) || isNaN(seconds)) {
            alert('Please enter valid numbers for minutes and seconds.');
            return;
          }
    
          if (minutes < 0 || minutes > 20 || seconds < 0 || seconds > 59) {
            alert('Please enter a valid time. Minutes should be between 0 and 20, and seconds between 0 and 59.');
            return;
          }
    
          // You can do something with the valid input here, or remove this alert.
          alert('Valid input: ' + minutes + ' minutes ' + seconds + ' seconds');
        }
      </script>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search