问题
I have an HTML input element for positive integer numbers. I need to evaluate this input field and ensure that only proper values are inserted.
function exampleFunction(event, element) {
// If event is not backspace and Not a Number
if (event.which != 8) {
//If the event is Not a Number
if (isNaN(String.fromCharCode(event.which))) {
// Cancels the event
event.preventDefault();
}
//If the length reached the limit
else {
var value = document.getElementById(element.id).value;
var maxLength = document.getElementById(element.id).maxLength;
var valueLength = document.getElementById(element.id).value.length;
if (valueLength >= maxLength) {
// Cancels the event
event.preventDefault();
} else {
// Convert the value to a number and back to string. This means leading 0 will be gone.
document.getElementById(element.id).value = Number(value);
}
}
}
};
<input id="exampleInput" type="number" value="0" min="0" step="1" maxlength="5" onkeypress="exampleFunction(event, this)">
purposes:
- default value is 0
- only numbers shall be accepted
- no decimal value
.,
- no other characters
+-e
- no decimal value
- the input can come from:
- typing
- copy
- backspace and delete can also modify the value
- length of input shall also be limited for 5 character length
- leading 0 shall be eliminated after a proper new value
Problems:
- the default value is 0 and leading zeros are not immediately deleted, only after the second number is typed
- with ctrl+v
.,+-e
characters can be inserted
Question: Is any better solution for my purposes? If it is jQuery related, it is also acceptable.
Maybe I am not using the proper event. I tried also to handle the
input
event but it is not possible to evaluate the input text.
I am not sure if I make this too complicated, or the solution would be much more complex than I think.
回答1:
I suggest you to use .addEventListener()
instead of the inline event handler.
So to the same input
element, you can add more than one event. To do what you wish to do, there are three events implied:
keydown
to prevent the not allowed keyscontextmenu
for mouse pastinginput
to parseInt the value
The below snippet is restricting the input to nubers only. No dot, minus sign, e
or whatever except numbers are allowed.
Pasting can be done via [CTRL]+[v] or the mouse contextmenu
. In both cases, I assume the previous value of the input
should be squarely cleared.
I took the pasted negative numbers case in account using Math.abs().
// Get the element
let myInput = document.querySelector("#exampleInput")
// This event handler only allows numbers, backspace and [ctrl]+[v]
myInput.addEventListener("keydown", function(event) {
console.log("Key:", event.key)
// If this is to be a keyboard paste [CTRL]+[v],
// squarely clears the input value before the paste is done
if (event.ctrlKey && event.key === "v") {
console.log("keyboard paste")
this.value = ""
return;
}
// If the key is not backspace, but is NAN, it is not a number.
// In short, only a number OR a backspace is allowed at this point.
if (event.key !== "Backspace" && isNaN(event.key)) {
event.preventDefault();
console.log(" --------- Event prevented")
}
});
// This handler is for "mouse pastes"
// It squarely clears the input value before the paste is done
myInput.addEventListener("contextmenu", function(event) {
this.value = ""
})
// This handler fixes the value length and parses as a positive integer
myInput.addEventListener("input", function(event) {
console.log("Original value", this.value)
// Get the maxlength attribute value
var maxLength = parseInt(this.maxLength)
// ParseInt the value (will remove any leading zero) and ensure it is positive
// Then keep just the [maxlength] first characters.
var value = Math.abs(parseInt(this.value)).toString().slice(0, maxLength)
console.log("Fixed value", value)
this.value = value;
});
<input id="exampleInput" type="number" value="0" min="0" step="1" maxlength="5">
回答2:
Here we go with a JQuery solution
Features:
- Remove default "0" on focus.
- Set maximum length to (5)
- Allowed numeric content only and Backspace, Del, Home, End, Arrow-Left, Arrow-Right, ctrl+v, ctrl+c, ctrl+a buttons.
- Check if the copied text contains any numeric value and collect it and remove non-numeric values.
- Check if pasted text length + current value length are meeting maximum length
$(document).ready(function() {
//Remove default "0" ONLY! when focus at the input.
$("#exampleInput").on('focus', function() {
var oldval = $("#exampleInput").val();
if (oldval < 1) {
$("#exampleInput").val("");
}
});
/* SET CTRL+V , CTRL+C funciton */
var ctrlprs = false,
ctrlk = 17,
mccmd = 91,
vk = 86,
ak = 65,
ck = 67;
$(document).keydown(function(e) {
if (e.keyCode == ctrlk || e.keyCode == mccmd) ctrlprs = true;
}).keyup(function(e) {
if (e.keyCode == ctrlk || e.keyCode == mccmd) ctrlprs = false;
});
//Listen to the input in keydown
$("#exampleInput").on('keydown', function(e) {
var txt = $("#exampleInput").val();
//exceptions for [b-space,end,home,left,right,del]
var keys = [8, 35, 36, 37, 39, 46];
var rgx = $.inArray(e.which, keys) < 0;
var cnvrt = String.fromCharCode(e.which);
/* allow CTRL + "a or c or v" */
if (ctrlprs && ((e.keyCode == ck) || (e.keyCode == ak) || (e.keyCode == vk))) {
} else if ((txt.length == 5) || (cnvrt.match(/[^0-9]/)) || (e.shiftKey)) {
if ((rgx)) {
e.preventDefault();
/* prevent all text except numbers, and set max input value length to (5) */
}
}
});
/*Bind a paste function to check if clipboard data met with requirements or not.*/
$("#exampleInput").on('paste', function(e) {
var oldl = $("#exampleInput").val();
var oldval = e.originalEvent.clipboardData.getData('text');
if (oldval.match(/[0-9]{1,5}$\d/g)) {} else {
//remove all non-numeric text from clipboard text.
var newvar = oldval.replace(/\D/g, "");
setTimeout(function() {
//check if ( clipboard[Numeric only] + input value ) length equals or less than (5).
var totlen = oldl.length + newvar.length;
if (newvar.length > 0 && totlen <= 5) {
$("#exampleInput").val(oldl + newvar);
} else {
//if total length is more than (5) keep the input value before paste.
console.log("total length is : " totlen);
$("#exampleInput").val(oldl);
}
}, 1);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="exampleInput" type="number" value="0" min="0" step="1" maxlength="5">
来源:https://stackoverflow.com/questions/65970004/ensure-a-positive-integer-number-in-input