example
It appears that entering text into <input type="number"/> does not trigger a change event. I would like a change event so that I can warn the user to fix their input. How can I get a change event for this, and get the current value so that I can verify the bad input?
I've been testing in Chrome.
$('input').on('change', function() {
alert('change');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
put letters in me and press tab: <input type="number"/>
Try using the other keyboard events then. For example, I just added
$("input").on('keyup', function() {
alert('keyup' + $(this).val());
})
To your JSFiddle example, and the alert appears after pressing a within the number textbox.
Note: Checking $(this).val() will not return you invalid characters (at least in Chrome). It strips invalid values before returning the result (e.g., 1a becomes blank). This is also why the change event appears to not be fired when its value hasn't actually changed because the input is all invalid. To catch invalid characters, you must instead check the event's keyCode:
$("input").on('keyup', function(e) {
if (e.keyCode < 48 || e.keyCode > 57) {
// not 0-9 (note: ignores -)
alert('error!');
}
});
After messing around a bit more, I noticed that Chrome and IE10 behave similarly, but IE10 seems to have a bug in its stripping:
If you start the number input with a non-number, then IE10 (possibly 9 as well) will consider the rest of the input to be a valid number regardless of what characters follow (e.g., 1a2 is just as valid as 12 in the eyes of IE). However, in Chrome, if you enter a non-number, then it will immediately ignore the input and declare it to be invalid; in IE10, if you start with a non-number, then the behavior is the same.
One big difference in behavior is that IE10 will clear an invalid number field after blur, but, again, they only consider it invalid if the field starts with a non-number (e.g., a1). - can precede numbers, but not more than one of them.
In both browsers, if the number is considered invalid, then this.value (and consequently $(this).val()) will return blank. In IE10, you can be get the raw, invalid value if the number starts with a number (0-9). Both browsers will only fire change events when they consider the input to have actually changed and--in IE10's case--that means if the user enters abcd and then blurs the input, then IE10 will clear the field and fire a change event if it had a valid value before being changed. In Chrome, the change occurs whether the input is valid or not; if it's invalid then it is changed to a blank value.
What this means is that you can handle valid and invalid number input, but you cannot dependably get the actual value that the user has typed into the textbox.
HTML
put letters in me and press tab:
<br />
<input type="number"/>
<br />
<p id="event" />
<p id="text" />
JavaScript
function checkValid(e) {
var $this = $(this);
$("#event").text(e.type);
$("#text").html("this.value: " +
this.value +
"<br />$(this).val(): " +
$this.val() + "<br />$(this).is(:valid): " +
$this.is(":valid") +
"<br />$.isNumeric(this.value): " +
$.isNumeric(this.value)); // <- helps check
}
$('input[type="number"]').on('change', checkValid).on("keyup", checkValid);
You can check to see if it is a valid number by checking $.isNumeric. The :valid and :invalid pseudo classes do not work in IE10 with number except when the field is marked as required (not at all in IE9), but they both work in Chrome without marking it as required.
As pickypg has noted, if a user types 'abcd' into an <input type='number'> element, you cannot get the value 'abcd' via $(this).val(). (Caveat: I've only tested in Chrome.)
However, you can determine whether the HTML5 input validity constraints are satisfied (valid) or not by calling myDOMelement.checkValidity(), or looking at the individual properties of the myDOMelement.validity object. This at least lets you distinguish between a blank field (valid) and one containing 'abcd' (not valid). Check here for more on HTML5 validity.
What is rather confusing, at least in Chrome, is that if an <input type='number'> element is initially blank and then you type in 'abcd', the 'change' event is not fired on blur. Likewise when you delete 'abcd' from the field so the field becomes blank.
A workaround is testing for changes in the HTML5 validity on blur. Here's a jsFiddle to illustrate the technique. Note that you still cannot tell if the user has changed 'abcd' to 'efgh', since those are both not valid.
The event change is triggered on losing focus and it is working as it is supposed to be, you may need to use keyup.
Live Demo
$('input').on('keyup', function() {
alert('change');
});
Related
Does the beforeinput event provide a convenient way to preview the result of a proposed modification so that it can be blocked if necessary for validation purposes?
I'm not looking for alternative ways to do input validation; I'm already well-aware of methods involving the keypress and input events, as well as HTML5 validation, etc.. Right now, I'm specifically looking into the beforeinput event to see what it offers.
So far, this is the best I've come up with:
document.getElementById("phone").addEventListener("beforeinput", function(e) {
if(!/^(\d{0,7}|\d{3}-\d{0,4}|)$/.test(e.target.value + (e.data ?? ""))) {
e.preventDefault();
}
return;
});
<input id="phone">
The text field in the above snippet should accept a simple 7-digit phone number with optional dash after the 3rd digit.
Notice that I'm appending the event's data property to the input's current value to create a preview of the modified value. This works fine if you only enter input sequentially. But if, for example, you type in all 7 digits and then arrow back to just after the 3rd and try to insert the dash, you can't do it, because the validation assumes you're at the end where a dash would be invalid. Other problems arise if you try to replace or delete a selection.
An accurate preview will be required to solve these problems. Is there a simple way to get one from the beforeinput event?
You'd have to get the selectionStart and selectionEnd to figure out how many characters were removed / replaced / etc, but yeah, pretty simple:
document.getElementById("phone").addEventListener("beforeinput", function(e) {
const nextVal =
e.target.value.substring(0, e.target.selectionStart) +
(e.data ?? '') +
e.target.value.substring(e.target.selectionEnd)
;
console.log(nextVal)
if(!/^(\d{0,7}|\d{3}-?\d{0,4}|)$/.test(nextVal)) {
e.preventDefault();
}
return;
});
<input id="phone">
I discovered a strange behavior of input text/hidden elements and I would like to know why this happens.
I have an input text box that has a value, let's say "test". I delete the input element value and I change the type of this element into "hidden". If now I switch it back to "text" the original value is there! If you don't fully delete the value of the text element but change it your changes are preserved. Why if you clear the element value this change is not preserved?
I created a fiddle that can show you what I mean.
function toggler() {
var iobj = document.getElementById('test');
if (iobj.type == 'text') {
iobj.type = 'hidden';
} else {
iobj.type = 'text';
}
}
<button name="toggle" type="button" onclick="toggler()">Toggle</button><br /><br />
<input type="text" name="test" id="test" value="sample" />
This has something to do with how different browsers handle defaultValue property of the inputs, whenever their type is changed. In this case, when the input type is changed and the .value is empty, Firefox uses the last non-empty value as .defaultValue property of the input. When the type is changed into text, Firefox uses the .defaultValue property for setting current .value property of the input. Chrome doesn't do this, i.e. it uses the last value, empty or non-empty, as the .defaultValue.
Here is a demo on jsfiddle. Comparing the logged values on Firefox and Chrome console, should demonstrate the different behaviors.
I should also mention that according to my experience/knowledge, Firefox is more standards-compliant than other browsers.
That being said, changing type of an input has never been a good idea. Form elements are very different and browsers handle the case in different ways.
I have a simple input like the following:
<input type="text" id="foo">
I tried using change() in order to detect when at least 1 character has been keyed in. The problem is, the event doesn't fire off until the input text box has lost focus.
Is there another event I can bind to and be able to trigger some code when at least 1 character has been typed?
You can use jQuery's keydown(). You can also try keypress(), which fires when the key is down, or keyup(), which is when the key is lifted up.
These all fire after a single key, not upon losing focus.
Therefore, you can try:
$("#test").keydown(function() {
$("#console").prepend(
(($(this).val().length) ?
"Not Empty" :
"Empty")
+ "<br />"
);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="test" />
<div id="console"></div>
You might give input a try.
$('#foo').on('input', function(){
if (this.value.trim().length) {
console.log('we got a char');
}
});
Input is filtered to be thing that change the actual input of the element. So you don't have to worry about random keys like function keys and stuff, enter press, etc.
The code I'm running has no issues in Firefox, or Chrome. A user is typing into one textbox, tabs to the next and can continue typing into that.
When I run the webpage on IE11, a user tabs to the next textbox and can't type anything in. The textbox has to be double-clicked before the user can insert anything.
I've googled this and it seems that sometimes IE will give problems when using some older jQuery (i.e. it prefers 'prop' to 'attr'). In the code below is jQuery's readonly keyword being used in a way that IE11 will no longer recognise/accept?
I assume the issue is with readonly, as the removeClass('ignore') is working as expected.
//when focus is on textbox 1
$("#Field1").focus(function() {
//remove readonly property from textbox 1
$('#Field1').prop('readonly', false).removeClass('ignore');
//add readonly property to all other textboxes
$('#Field2, #Field3, #Field4')
.prop('readonly', 'readonly').addClass('ignore').val('');
});
I'm using jQuery 2.1.3
Use a boolean for the property value, not a string
$('#Field2, #Field3, #Field4')
.prop('readonly', true).addClass('ignore').val('');
Try changing:
$('#Field1').attr('readonly', false).removeClass('ignore');
To:
$('#Field1').removeAttr('readonly').removeClass('ignore');
readonly is a boolean attribute and as per the HTML standard:
The presence of a
boolean attribute on an element represents the true value, and the
absence of the attribute represents the false value.
If the attribute is present, its value must either be the empty string
or a value that is an ASCII case-insensitive match for the attribute's
canonical name, with no leading or trailing whitespace.
So in this case setting to false has no effect and you want to remove the attribute entirely.
I have used Focusin() function in jquery side with Id.
When I click on textbox then we remove readony attribute as below:
HTML:
<input type="text" id="txtCustomerSearch" readonly class="customer-search" placeholder="Search customer:" maxlength="100" autocomplete="off">
Jquery:
$("#txtCustomerSearch").focusin(function () {
$(this).removeAttr('readonly');
});
it will working in IE11 and other browser.
This jsfiddle demonstrates the following issue.
The simplest example is:
<input id="number" type="number" value="1">
console.log(document.getElementById('number').value);
This logs 1 as expected. THIS however:
<input id="number" type="number" value="1A">
console.log(document.getElementById('number').value);
Just logs an empty string '', because of the non-numeric character in the value. Some devices+browsers (e.g. Chrome) allow you to enter non-numeric characters in these inputs.
This is annoying because I want the type="number" input for devices that support it (e.g. iPhone, iPad number keyboard). However I want to use javascript to stop dirty input from being entered - which requires fetching the value on keyup - then regex replacing the non-numeric chars.
It appears jQuery's .val() method gives the same result.
This is what I was looking for:
$('input[type=number]').keypress(function(e) {
if (!String.fromCharCode(e.keyCode).match(/[0-9\.]/)) {
return false;
}
});
I understand preventing user input can be annoying and this still allows invalid input such as 1.2.3
However in this situation it is exactly what I needed. Hopefully it will be of use to someone else. Thanks to #int32_t for the suggestion.
You're not supposed to use <input type=number> for things that are not numbers (in very mathematical senseāit won't work for phone numbers or zip codes either) and clearing of the value is deliberate.
You can test whether device supports type=number and attach your fallback only if it doesn't:
var input = document.createElement('input');
input.setAttribute('type','number');
if (input.type != 'number') { // JS property won't reflect DOM attribute
polyfill_number();
}
Alternatively (especially if your number is a zip code, serial number, etc.) you can use:
<input type=text pattern="[0-9]*">
and this will change the keyboard too.