Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 input type=number change step behavior

If I use an input field of type="number" with step="100". I don't want odd numbers to be invalid. I just want increase or decrease to be with a value of 1000.

<input type="number" min="100" max="999999" step="100" /> 

If the user enters the value "199" and submits, he/she gets an error because the value isn't dividable by 100. But all I want with the step-value is to control the behavior of the spinner, e.g. if the user click up I want the value 199 to become 200 and if he/she clicks down I want it to become 100. Or ideally I would like the value to be increased or decreased with a value of 100.

How do I do this? I tried using the invalid event (with jQuery 1.7.2) like this:

$( "[type='number']" ).bind( 'invalid', function( e ) {     var el = $( this ),       val = el.val( ),       min = el.attr( 'min' ),       max = el.attr( 'max' );      if ( val >= min && val <= max ) {         return false;     } } ); 

But this results in the form not being submitted.

PS.: This is in Google Chrome 20.0.1132.57 on Fedora 16.

like image 789
mabs Avatar asked Jul 31 '12 11:07

mabs


People also ask

What does the step attribute do for a number input?

The step attribute specifies the interval between legal numbers in an <input> element. Example: if step="3" , legal numbers could be -3, 0, 3, 6, etc. Tip: The step attribute can be used together with the max and min attributes to create a range of legal values.


1 Answers

Well, first of all thank you for this very interesting question. I've learned a lot about HTML5 validation by searching a solution to your problem.

My research led me to find that HTML5 form validation API has an interesting set of properties that are read-only, but very useful to do what you want.

My approach to your problem was to first add the novalidate attribute to the form element, so that I can control when to trigger the validation, then read the validity object attached to the input, so I can know exactly what validation errors are there, and if the only error is stepMismatch (this is what triggers invalidity of numbers such as 199), I can bypass all the validation process. Else, I can show normal HTML validation behaviour with the reportValidity() method.

Here is the code I came up with that I hope does what you want :

var form = document.querySelector("form")       // Get the form  var input = document.querySelector("#myInput")  // Get the input to validate    form.addEventListener("submit", function(e) {  	e.preventDefault()  // Catch the submit    // Do the magic    if(onlyStepMatters(input.validity)){    	form.submit()    }else {    	form.reportValidity()    }  })    function onlyStepMatters(validityState) {    return !(      validityState.badInput || validityState.customError || validityState. patternMismatch || validityState.rangeOverflow || validityState.rangeUnderflow || validityState.tooLong || validityState.tooShort || validityState.typeMismatch || validityState.valueMissing      )          /* This is what the object looks like, notice I just skipped the stepMismatch */    /*    {      badInput,      customError,      patternMismatch,      rangeOverflow,      rangeUnderflow,      stepMismatch,      tooLong,      tooShort,      typeMismatch,      valid,      valueMissing,    }    */  }
<form novalidate>  <input type="number" id="myInput" min="0" max="1000" step = "100" placeholder="Enter a number" required/>  <button type="submit">Send</button>   </form>

I'm pretty sure this code could be refactored and become more concise based on the same logic, but I don't have enough time to think more about it.

Any constructive comment will be appreciated.

Hope this helps.

like image 141
Rafik Tighilt Avatar answered Sep 20 '22 11:09

Rafik Tighilt