Reputation: 59491
For <input type="number">
element, maxlength
is not working. How can I restrict the maxlength
for that number element?
Upvotes: 447
Views: 1120946
Reputation: 3617
You can combine all of these like this:
<input name="myinput_drs"
oninput="maxLengthCheck(this)"
type = "number"
maxlength = "3"
min = "1"
max = "999" />
<script>
function maxLengthCheck(object)
{
if (object.value.length > object.maxLength)
object.value = object.value.slice(0, object.maxLength)
}
</script>
Note: The above code is an old version and has got a few updates. For a bulletproof version, covering ALL edge cases, see the code snippet below.
Update 1: You might also want to prevent any non-numeric characters to be entered, because object.length
would be an empty string for the number inputs, and therefore its length would be 0
. Thus the maxLengthCheck
function won't work.
Solution:
See this or this for examples.
Demo: See the full version of the code here:
http://jsfiddle.net/DRSDavidSoft/zb4ft1qq/1/
Update 2: Here's the update code: https://jsfiddle.net/DRSDavidSoft/zb4ft1qq/2/
Update 3: Please note that allowing more than a decimal point to be entered can mess up with the numeral value.
Update 4 (by RWC): I took the liberty of posting an update to this code. The code is basically correct, but there are a few edge cases that are not covered. The edge cases that are not well covered:
See the code snippet:
function maxLengthCheck(object) {
if (object.value.length > object.max.length) {
object.value = object.value.slice(0, object.max.length);
}
}
function isNumeric(evt) {
var theEvent = evt || window.event;
var key = theEvent.keyCode || theEvent.which;
key = String.fromCharCode(key);
var regex = /^\d+$/;
if (!regex.test(key)) {
theEvent.returnValue = false;
if (theEvent.preventDefault) theEvent.preventDefault();
}
}
function validateInputOnBlur(input) {
if (input.value === "") return; // Allow empty values
let min = parseInt(input.min, 10) || 0;
let max = parseInt(input.max, 10) || 999;
if (parseInt(input.value, 10) < min) {
input.value = min; // Enforce min value
} else if (parseInt(input.value, 10) > max) {
input.value = max; // Enforce max value
} else {
// Remove leading zeros unless the number is exactly "0"
input.value = String(parseInt(input.value, 10));
}
}
document.addEventListener("DOMContentLoaded", function () {
const firstInput = document.querySelector(
'input:not([type="hidden"]):not([disabled]):not([readonly])'
);
if (firstInput) firstInput.focus();
document.querySelectorAll('input[type="number"]').forEach(input => {
input.addEventListener("blur", function () {
validateInputOnBlur(this);
});
});
});
<label for="numberInput" >Insert a number (5-555)</label>
<input id="numberInput"
onkeypress="return isNumeric(event)"
oninput="maxLengthCheck(this)"
type = "number"
min = "5"
max = "555" /><br/>
<br/>
<label for="textInput" >Insert text</label>
<input id="textInput"/>
Now ALL edge cases are covered! And one more thing; Never ever trust input from the frontend. Always check the input on the backend.
All credits to David Refoua.
Upvotes: 91
Reputation: 2430
I solved this problem with jquery as follows. Works for all elements with class "max-length".
<input type="number" class="max-length" maxlength="3" />
<script type="text/javascript">
$(function () {
$(".max-length").on("keypress", function (e) {
if ($(this).val().length == $(this).attr("maxlength")) return false;
});
});
</script>
Upvotes: 0
Reputation: 1278
Non-optimal solutions
Rellying on min
and max
As some people have pointed out, you can use max
and min
attributes to set the range of allowed values, but this won't prevent the user from typing longer text like maxlength
attribute does.
keydown
, keyup
and other non-input
event listeners
It is important to say that not all users work with a desktop keyboard so keydown
or keyup
events are not the best approch to accomplish this for all kind of input methods such as mobile keyboards
slice
, substring
and other String
methods
This methods work well only if the user is typing at the end of the input, but if it is typing anywhere else, the character input won't be prevented. It will be added and the last character of the input will be removed instead
Solution for all situations
If you really want to prevent the character from being added to the input, when the desired length is reached (or any other condition is met), you can handle it using the beforeinput
event listener which is supported for all major browsers: https://caniuse.com/?search=beforeinput.
It is called just before the input
event listener which means the input value hasn't changed already, so you can store it an set to the input after.
const input = document.querySelector("input");
input.addEventListener("beforeinput", () => {
const valueBeforeInput = event.target.value;
event.target.addEventListener("input", () => {
if (event.target.value.length > 10) {
event.target.value = valueBeforeInput;
}
}, {once: true});
});
<input type=number />
If you want to support browsers before 2017 (2020 and 2021 for Edge and Firefox respectively) don't use the beforeinput
event listener and use the code below instead.
const input = document.querySelector("input");
let valueBeforeInput = input.value;
input.addEventListener("input", () => {
if (event.target.value.length > 10) {
event.target.value = valueBeforeInput;
}
valueBeforeInput = event.target.value;
});
<input type=number />
Upvotes: 3
Reputation: 10844
Since I was look to validate and only allow integers I took one the existing answers and improve it
The idea is to validate from 1 to 12, if the input is lower than 1 it will be set to 1, if the input is higher than 12 it will be set to 12. Decimal simbols are not allowed.
<input id="horaReserva" type="number" min="1" max="12" onkeypress="return isIntegerInput(event)" oninput="maxLengthCheck(this)">
function maxLengthCheck(object) {
if (object.value.trim() == "") {
}
else if (parseInt(object.value) > parseInt(object.max)) {
object.value = object.max ;
}
else if (parseInt(object.value) < parseInt(object.min)) {
object.value = object.min ;
}
}
function isIntegerInput (evt) {
var theEvent = evt || window.event;
var key = theEvent.keyCode || theEvent.which;
key = String.fromCharCode (key);
var regex = /[0-9]/;
if ( !regex.test(key) ) {
theEvent.returnValue = false;
if(theEvent.preventDefault) {
theEvent.preventDefault();
}
}
}
Upvotes: 1
Reputation: 715
<input type="number" maxlength="6" oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);">
This worked for me with no issues
Upvotes: 7
Reputation: 1487
Here's the simplest solution to use the maxlength
:
<form>
<input class="form-control" id="code_pin" oninput="if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);" type="number" maxlength="4">
</form>
Upvotes: -2
Reputation: 477
If anyone is struggling with this in React the easiest solution that i found to this is using the onChange function like this:
const [amount, setAmount] = useState("");
return(
<input onChange={(e) => {
setAmount(e.target.value);
if (e.target.value.length > 4) {
setAmount(e.target.value.slice(0, 4));
}
}} value={amount}/>)
So what this basically does is it takes the value of the input and if the input value length is bigger than 4 it slices all the numbers after it so you only get the first 4 numbers (of course you can change the amount of numbers you can type by changing all 4's in the code). I hope this helps to anyone who is struggling with this issue. Also if you wanna learn what the slice method does you can check it out here
Upvotes: 0
Reputation: 6095
Simple solution which will work on,
Input scroll events
Copy paste via keyboard
Copy paste via mouse
Input type etc cases
<input id="maxLengthCheck"
name="maxLengthCheck"
type="number"
step="1"
min="0"
oninput="this.value = this.value > 5 ? 5 : Math.abs(this.value)" />
See there is condition on this.value > 5, just update 5 with your max limit.
Explanation:
If our input number is more then our limit update input value this.value with proper number Math.abs(this.value)
Else just make it to your max limit which is again 5.
Upvotes: 16
Reputation: 69
I use a simple solution for all inputs (with jQuery):
$(document).on('input', ':input[type="number"][maxlength]', function () {
if (this.value.length > this.maxLength) {
this.value = this.value.slice(0, this.maxLength);
}
});
The code select all input type="number" element where maxlength has defined.
Upvotes: 0
Reputation: 16217
Ugh. It's like someone gave up half way through implementing it and thought no one would notice.
For whatever reason, the answers above don't use the min
and max
attributes. This jQuery finishes it up:
$('input[type="number"]').on('input change keyup paste', function () {
if (this.min) this.value = Math.max(parseInt(this.min), parseInt(this.value) || 0);
if (this.max) this.value = Math.min(parseInt(this.max), parseInt(this.value) || 0);
});
It would probably also work as a named function "oninput" w/o jQuery if your one of those "jQuery-is-the-devil" types.
Upvotes: 5
Reputation: 528
This might help someone.
With a little of javascript you can search for all datetime-local inputs, search if the year the user is trying to input, greater that 100 years in the future:
$('input[type=datetime-local]').each(function( index ) {
$(this).change(function() {
var today = new Date();
var date = new Date(this.value);
var yearFuture = new Date();
yearFuture.setFullYear(yearFuture.getFullYear()+100);
if(date.getFullYear() > yearFuture.getFullYear()) {
this.value = today.getFullYear() + this.value.slice(4);
}
})
});
Upvotes: -1
Reputation:
Lets say you wanted the maximum allowed value to be 1000 - either typed or with the spinner.
You restrict the spinner values using:
type="number" min="0" max="1000"
and restrict what is typed by the keyboard with javascript:
onkeyup="if(parseInt(this.value)>1000){ this.value =1000; return false; }
"
<input type="number" min="0" max="1000" onkeyup="if(parseInt(this.value)>1000){ this.value =1000; return false; }">
Upvotes: 26
Reputation: 521
a simple way to set maxlength for number inputs is:
<input type="number" onkeypress="return this.value.length < 4;" oninput="if(this.value.length>=4) { this.value = this.value.slice(0,4); }" />
Upvotes: 7
Reputation: 176
<input type="number" onchange="this.value=Math.max(Math.min(this.value, 100), -100);" />
or if you want to be able enter nothing
<input type="number" onchange="this.value=this.value ? Math.max(Math.min(this.value,100),-100) : null" />
Upvotes: 3
Reputation: 682
HTML Input
<input class="minutesInput" type="number" min="10" max="120" value="" />
jQuery
$(".minutesInput").on('keyup keypress blur change', function(e) {
if($(this).val() > 120){
$(this).val('120');
return false;
}
});
Upvotes: 5
Reputation: 664
//For Angular I have attached following snippet.
<div ng-app="">
<form>
Enter number: <input type="number" ng-model="number" onKeyPress="if(this.value.length==7) return false;" min="0">
</form>
<h1>You entered: {{number}}</h1>
</div>
If you use "onkeypress" event then you will not get any user limitations as such while developing ( unit test it). And if you have requirement that do not allow user to enter after particular limit, take a look of this code and try once.
Upvotes: 17
Reputation: 397
Another option is to just add a listener for anything with the maxlength attribute and add the slice value to that. Assuming the user doesn't want to use a function inside every event related to the input. Here's a code snippet. Ignore the CSS and HTML code, the JavaScript is what matters.
// Reusable Function to Enforce MaxLength
function enforce_maxlength(event) {
var t = event.target;
if (t.hasAttribute('maxlength')) {
t.value = t.value.slice(0, t.getAttribute('maxlength'));
}
}
// Global Listener for anything with an maxlength attribute.
// I put the listener on the body, put it on whatever.
document.body.addEventListener('input', enforce_maxlength);
label { margin: 10px; font-size: 16px; display: block }
input { margin: 0 10px 10px; padding: 5px; font-size: 24px; width: 100px }
span { margin: 0 10px 10px; display: block; font-size: 12px; color: #666 }
<label for="test_input">Text Input</label>
<input id="test_input" type="text" maxlength="5"/>
<span>set to 5 maxlength</span>
<br>
<label for="test_input">Number Input</label>
<input id="test_input" type="number" min="0" max="99" maxlength="2"/>
<span>set to 2 maxlength, min 0 and max 99</span>
Upvotes: 16
Reputation: 1286
As I found out you cannot use any of onkeydown
, onkeypress
or onkeyup
events for a complete solution including mobile browsers. By the way onkeypress
is deprecated and not present anymore in chrome/opera for android (see: UI Events
W3C Working Draft, 04 August 2016).
I figured out a solution using the oninput
event only.
You may have to do additional number checking as required such as negative/positive sign or decimal and thousand separators and the like but as a start the following should suffice:
function checkMaxLength(event) {
// Prepare to restore the previous value.
if (this.oldValue === undefined) {
this.oldValue = this.defaultValue;
}
if (this.value.length > this.maxLength) {
// Set back to the previous value.
this.value = oldVal;
}
else {
// Store the previous value.
this.oldValue = this.value;
// Make additional checks for +/- or ./, etc.
// Also consider to combine 'maxlength'
// with 'min' and 'max' to prevent wrong submits.
}
}
I would also recommend to combine maxlength
with min
and max
to prevent wrong submits as stated above several times.
Upvotes: 2
Reputation: 30001
And you can add a max
attribute that will specify the highest possible number that you may insert
<input type="number" max="999" />
if you add both a max
and a min
value you can specify the range of allowed values:
<input type="number" min="1" max="999" />
The above will still not stop a user from manually entering a value outside of the specified range. Instead he will be displayed a popup telling him to enter a value within this range upon submitting the form as shown in this screenshot:
Upvotes: 413
Reputation: 7616
Max length will not work with <input type="number"
the best way i know is to use oninput
event to limit the maxlength. Please see the below code for simple implementation.
<input name="somename"
oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
type = "number"
maxlength = "6"
/>
Upvotes: 13
Reputation: 6949
it's very simple, with some javascript you can simulate a maxlength
, check it out:
//maxlength="2"
<input type="number" onKeyDown="if(this.value.length==2) return false;" />
Upvotes: 33
Reputation: 344567
You can specify the min
and max
attributes, which will allow input only within a specific range.
<!-- equivalent to maxlength=4 -->
<input type="number" min="-9999" max="9999">
This only works for the spinner control buttons, however. Although the user may be able to type a number greater than the allowed max
, the form will not submit.
Screenshot taken from Chrome 15
You can use the HTML5 oninput
event in JavaScript to limit the number of characters:
myInput.oninput = function () {
if (this.value.length > 4) {
this.value = this.value.slice(0,4);
}
}
Upvotes: 132
Reputation: 1946
You can specify it as text, but add pettern, that match numbers only:
<input type="text" pattern="\d*" maxlength="2">
It works perfect and also on mobile ( tested on iOS 8 and Android ) pops out the number keyboard.
Upvotes: 23
Reputation: 4437
I know there's an answer already, but if you want your input to behave exactly like the maxlength
attribute or as close as you can, use the following code:
(function($) {
methods = {
/*
* addMax will take the applied element and add a javascript behavior
* that will set the max length
*/
addMax: function() {
// set variables
var
maxlAttr = $(this).attr("maxlength"),
maxAttR = $(this).attr("max"),
x = 0,
max = "";
// If the element has maxlength apply the code.
if (typeof maxlAttr !== typeof undefined && maxlAttr !== false) {
// create a max equivelant
if (typeof maxlAttr !== typeof undefined && maxlAttr !== false){
while (x < maxlAttr) {
max += "9";
x++;
}
maxAttR = max;
}
// Permissible Keys that can be used while the input has reached maxlength
var keys = [
8, // backspace
9, // tab
13, // enter
46, // delete
37, 39, 38, 40 // arrow keys<^>v
]
// Apply changes to element
$(this)
.attr("max", maxAttR) //add existing max or new max
.keydown(function(event) {
// restrict key press on length reached unless key being used is in keys array or there is highlighted text
if ($(this).val().length == maxlAttr && $.inArray(event.which, keys) == -1 && methods.isTextSelected() == false) return false;
});;
}
},
/*
* isTextSelected returns true if there is a selection on the page.
* This is so that if the user selects text and then presses a number
* it will behave as normal by replacing the selection with the value
* of the key pressed.
*/
isTextSelected: function() {
// set text variable
text = "";
if (window.getSelection) {
text = window.getSelection().toString();
} else if (document.selection && document.selection.type != "Control") {
text = document.selection.createRange().text;
}
return (text.length > 0);
}
};
$.maxlengthNumber = function(){
// Get all number inputs that have maxlength
methods.addMax.call($("input[type=number]"));
}
})($)
// Apply it:
$.maxlengthNumber();
Upvotes: 0
Reputation: 19097
As stated by others, min/max is not the same as maxlength because people could still enter a float that would be larger than the maximum string length that you intended. To truly emulate the maxlength attribute, you can do something like this in a pinch (this is equivalent to maxlength="16"):
<input type="number" oninput="if(value.length>16)value=value.slice(0,16)">
Upvotes: 10
Reputation: 461
I had this problem before and I solved it using a combination of html5 number type and jQuery.
<input maxlength="2" min="0" max="59" name="minutes" value="0" type="number"/>
script:
$("input[name='minutes']").on('keyup keypress blur change', function(e) {
//return false if not 0-9
if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
return false;
}else{
//limit length but allow backspace so that you can still delete the numbers.
if( $(this).val().length >= parseInt($(this).attr('maxlength')) && (e.which != 8 && e.which != 0)){
return false;
}
}
});
I don't know if the events are a bit overkill but it solved my problem. JSfiddle
Upvotes: 7
Reputation: 2517
You can try this as well for numeric input with length restriction
<input type="tel" maxlength="3" />
Upvotes: 4
Reputation: 401
Or if your max value is for example 99 and minimum 0, you can add this to input element (your value will be rewrited by your max value etc.)
<input type="number" min="0" max="99"
onKeyUp="if(this.value>99){this.value='99';}else if(this.value<0){this.value='0';}"
id="yourid">
Then (if you want), you could check if is input really number
Upvotes: 40
Reputation: 61
Maycow Moura's answer was a good start. However, his solution means that when you enter the second digit all editing of the field stops. So you cannot change values or delete any characters.
The following code stops at 2, but allows editing to continue;
//MaxLength 2
onKeyDown="if(this.value.length==2) this.value = this.value.slice(0, - 1);"
Upvotes: 6
Reputation: 4499
If you are looking for a Mobile Web solution in which you wish your user to see a number pad rather than a full text keyboard. Use type="tel". It will work with maxlength which saves you from creating extra javascript.
Max and Min will still allow the user to Type in numbers in excess of max and min, which is not optimal.
Upvotes: 92