简体   繁体   中英

Force the value incremented by "step" input number

I created an input of type number. Minimum value 1, maximum value 100. Step 5. However, I can enter values other than step for this input. Eg 7 instead of 5-10-15.

I would like the manually entered values to be automatically increased to the step value. The user enters 7 - after leaving the input it is 10. I am trying onfocusout but I have no idea how to do it.

 <input type="number" min="1" max="100" step="5" onfocusout="this.value = Math.round(step);">

Example. The user enters 13 - gets 15. He enters 27 - gets 30.

you can:

  • get the result of value divided by 5

  • round the result to near integer

  • and multiply it by 5 to get the nearest 5 value of the input entered by user

    this.value = Math.round(this.value / 5) * 5;

 <input type="number" min="1" max="100" step="5" onfocusout="var result = Math.round(this.value / 5) * 5; this.value = (result)? result: this.min;">

First, instead of listening for focusout events you should listen for change events, which are triggered whenever the user does anything that implies they are done entering a value. This will make the behavior more consistent across browsers and devices.

Second, you can round a value to the nearest multiple of X by doing Math.round(value / X) * X , and you can restrict a value within [A, B] using Math.min(Math.max(A, value), B) .

Finally, the min , max and step HTML attributes directly correspond to properties on the JavaScript HTMLInputElement object, which is the object bound to this inside the event listener.

Combinging all of this together, you get this.

 <input type="number" min="1" max="100" step="5" onchange="this.value = Math.min(Math.max(this.min, Math.round(this.value / this.step) * this.step), this.max)">

Note that in your code the min attribute is 1 which isn't a multiple of 5 , and that tells the browser to accept values in the sequence [1, 6, 11, 16, ...] which breaks our code. If you want multiples of 5, you'll need to make sure the min attribute is a multiple of 5 as well.

All of that JS code inside an HTML attribute is hard to read, so you might want to use a proper event listener at this point, which lets you divide the problem into smaller functions.

 function clamp(a, value, b) { return Math.min(Math.max(a, value), b); } function roundTo(multiple, value) { return Math.round(value / multiple) * multiple; } function roundToStepOnChange(event) { const roundedValue = roundTo(this.step, this.value); const clampedValue = clamp(this.min, roundedValue, this.max); this.value = clampedValue; } document.getElementById("myInput").addEventListener("change", roundToStepOnChange);
 <input id="myInput" type="number" min="5" max="100" step="5">

I set the min attribute to 5 in that example so you can see it running without any issues.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM