In a small edit form, I prepopulate the Input elements with text values. I then monitor the changes with each element's onChange event.
One strange phenomenon my QA colleague just discovered is that if you initially select all of the text (ie. Cmd-A or Ctrl-A) and then press Backspace or Delete, the onChange event is not fired.
This seems like a bug/defect in the browser or in React?
I'm going to combat it by adding an onKeyUp event handler for every Input element, looking for the Backspace (ASCII 8) or Delete (ASCII 46) codes.
Update:
It appears the root cause is my use of the defaultValue property, as in this example:
<Form.Control as='input'
defaultValue={location}
placeholder='Enter Location'
onChange={e => handleChange(e)}
/>
With this code, the onChange event will not fire if the steps above are followed. But if defaultValue is changed to value then everything works fine.
I updated my question that provides an explanation.
I'm not going to use the defaultValue of an Input element anymore!
Related
I'm trying to catch the value of an input element every time its value changed. change requires blurring the element so it is not good for my case. I came across this Javascript change event on input element fires on only losing focus question and the accepted answer solved my problem, partly. According to the fiddle the event I should be watching is
$('#name').bind('DOMAttrModified textInput input change keypress paste focus', function () {
.....
})
However it doesn't work so well with characters that require an input method to input. For example, to input Chinese character "長", I'd press "c","h","a","n",“g” and then "space", all these keystrokes are recorded and will fire the events unwantedly - I only want to catch "長" as the input value, and the trigger should only fire when this character appears in the input textbox.
I've tried different combinations of the events, but none of them works. Is there any way to work this around?
I've added an on 'change' event listener to a type=email input element. When I add a couple space characters into the email field, then lose focus on that element, the change event doesn't seem to be firing.
However, this exact scenario works just fine with type=text input elements.
What's going on?
$('input[type="email"]').change(e => {
console.log('Triggered!');
});
Browser: Chrome Version 63.0.3239.132 (Official Build) (64-bit)
I originally said that it looks like there is an automatic trim operation performed on email fields because the length of the value is coming back at 0 after typing some spaces and leaving the field, but upon returning to the field, the spaces remain in the element, so they aren't getting trimmed out.
I suspect that, because spaces are not valid for this input type, they are not considered part of the value, thus the value doesn't change when you enter them and the change event doesn't fire.
Type some spaces in the field and then hit TAB to leave the field, but then return to the field. The spaces will still be there.
$('input[type="email"]').on("blur", function(e){
console.log(this.value.length);
});
$('input[type="email"]').on("change", function(e){
console.log("Change fired!");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="email">
You can use something like that:
$('input[type="email"]').on('focusout', {
console.log('Triggered!');
var $trig = $(this);
$trig.attr('trimmed', $trig.val().toString().trim());
$trig.val( '').val($trig.attr('trimmed'));
});
But, as answered above, input[type="email"] does not count whitespaces. It is only works as fast hack;
I am facing the same problem with React, and I don't want to reflect the error on the onBlur event (as other solutions here). I don't think an error should be reflected in any input by the simple fact of removing the mouse from that input. For me that's not User friendly,... AT ALL.
Why?
Because the User might have decided to remove the mouse from that
Input only because he/she simply wants to copy something from somewhere else first,... and then past it there (and/or to past it somewhere else). So technically there is no mistake there yet.
Because I simply want to fill another input field of the form first.
Why? Becase that's precisely the field's value I already copied from
somewhere else, so that's the value I have stored in clipboard, and
it doesn't goes where my mouse landed by default. Or simply because
I just want to! I'm the User, so I can choose the order to
fill the form!
For me is more than enough with validating what the User has written and/or removed/deleted from the Inputs (onChange validation) AND also what the User finally decides to send (onSubmit validation). A proper combination of onChange and onSubmit validation is the perfect healthy balance between thoroughness and User friendly.
A Solomonic "solution":
I am using a custom validation hook. As I can not change the behavior of the input with a type email regarding the white spaces in an OnChange event,... then I decided to use a workaround, which is simply avoiding the typing of white spaces and that's it, as the onChange event won't trigger anyway.
const preventWhiteSpaceOnKeyDown = (e) => {
if (e.key === " ") {
e.preventDefault();
}
}
.
.
.
<input
type={"email"}
id='commentEmail'
name='commentEmail'
required={true}
autoFocus={true}
ref={emailInputRef}
value={emailState}
onChange={emailInputChangeHandler}
onKeyDown={preventWhiteSpaceOnKeyDown}
/>
This is not a "solution". There is no clean solution for this. But after this at least my input[type=email] element won't hold useless white spaces.
input[type="email"] does not fire change event, use blur event instead:
$('input[type="email"]').blur(function(){
console.log('blur event is fired.');
});
I'm working on a Chrome extension whose content script injects a bunch of elements in a webpage, including an input element of type text, on specified actions.
the problem is that while on a webpage like Facebook's home page, which listens for keyboard input (e.g., P), the extension's input element loses focus, which goes to Facebook's "what's on your mind?" section in case of the P.
I tried getting focus back to the input element programtically, and while that seems to be partially working, as it takes focus back from the "what's on your mind?" section immediately, it still doesn't write the 'P' into the text field.
is there anyway to workaround that?
update #0: the code that I tried for regaining focus was as simple as that:
searchBar.onblur = searchBar.focus;
update #1: my input element is inside a shadow DOM. apparently the element doesn't lose focus when it's not part of a shadow DOM. any idea on how to get that to work with the shadow DOM?
Check out this example. You can listen for keyboard events on the highest level (which is document), unless the site blocks propagation of the event.
document.addEventListener('keypress', function(e) {
console.log(e);
}, false);
document.getElementById('text3').addEventListener('keypress', function(e) {
console.log(e);
}, false);
<textarea id="text1"></textarea>
<textarea id="text2"></textarea>
<textarea id="text3"></textarea>
<textarea id="text4"></textarea>
I don't use Facebook; are you saying that when someone types a P, that causes the focus to move to "What's on your mind?" Because if the sequence of events is keypress --> Facebook takes focus --> you take focus back, the keypress didn't occur while your input field had focus, so the typed letter wouldn't show up.
You might have to put those letters into your input's value yourself by listening to keypresses, checking if they missed the input field, converting the keycode into the appropriate letter, and appending it to the input's value.
Thank you for taking the time for reading my question.
A "range" input element in HTML (Slider) fires an onchange -event, in which the content of a span element gets updated with the current value of the input element.
Somehow, the first change made to the input element doesn't fire the onchange event. When an 'onclick' event is used, it does fire.
Here's the code, HTML first:
<div>
<input id="main_options_plug1_lengthPE_input" type="range" step="10" value="0" max="200" min="0" onchange="setOpenEndPELength('plug1');"></input>
<span id="main_options_plug1_lengthPE_value"> … </span>
</div>
And now JavaScript:
function setOpenEndPELength(plug)
{
if (plug == "plug1" || plug == "plug2")
{
var slider = document.getElementById("main_options_" + plug + "_lengthPE_input");
var span = document.getElementById("main_options_" + plug + "_lengthPE_value");
span.innerHTML = slider.value + " mm";
}
}
I created a JSFiddle, so you can try it yourself.
I didn't find an answer to this question on stackoverflow so far, any questions i found were about onchange event don't firing at all. In this case, it's only the first change that doesn't work.
Hope someone knows the answer. Any help is greatly appreciated, thanks in advance.
If I understand the question correctly, the problem is that on Firefox, the onchange handler is not executed when you press down mouse button when the cursor is on the button of the slider and move the mouse. It is executed only after you release the mouse button after such a move.
This seems to be the correct behavior (though some other browsers don’t comply), since HTML5 CR says about the change event: “if the element does not have an activation behavior defined but uses a user interface that involves an explicit commit action, then any time the user commits a change to the element's value or list of selected files, the user agent must queue a task to fire a simple event that bubbles named change at the input element.”
That’s a bit complicated formulation, but it is followed by a clarifying example: “A third example of a user interface with a commit action would be a Range controls that use a slider. While the user is dragging the control's knob, input events would fire whenever the position changed, whereas the change event would only fire when the user let go of the knob, committing to a specific value.”
The conclusion is that in this case, you should use the oninput attribute instead of onchange. In practice, onmousemove works too, but oninput is better, since it can be expected to work with input methods that do not use a mouse (whatever they might be, e.g. control by voice).
On document ready try to trigger event manually caused first time change is not occurred.
So just add code as below:
$(“#main_options_plug1_lengthPE_input”).trigger(‘change’)
A little trick, if onchange doesn't fire the first time, add:
onclick="console.log(1)"
Some other action on the click, it still fire the onchange as second time but as first you have the click.
Lets suppose we have a html text input element and it has text "abc" and cursor is between "b" and "c". If we press backspace key then how can we get the value "ac"?
Please note that in case of special keys KeyPress event do not fire. The only events that fire are KeyDown and KeyUp and none of them has the value after the effect of special key is applied. The effect is visible after the eventhandlers of these events exit but since we have only these two events we have to somehow get the affected/latest value inside these events.
We can go to a complex way by manually applying the effect ourselves but its very very complicated given the facts that we have to find the cursor position, write different code for different special keys and bring browser compatibility. The browser, whichever it is, is already applying the effect once the eventhandlers exit but is there some way to get that latest value in those events without manually applying it or in some other event?
Please note that I am not searching for "how to find which key is pressed". I can find that by looking at the event object inside the KeyDown or KeyUp event handlers. I want to apply the effect of the special key without using a lot of manual code.
I have already looked at Capturing HTML Text Input Key press after key has been applied?. Its talking about a different thing than my question.
My ultimate task is to have a web page with only two controls: a textbox and a button. The button is initially disabled. User can type in textbox and on every key its checked that there is some text in the textbox, if there is then button is enabled, if not then button is disabled. The difficult part is to take into consideration special keys such as delete, enter, tab, backspace.
Note: I do not want to work on the blur eventhandler of the HTML text element because it affects the tab order.
Example using jQuery. The target value is stored on the title attribute, but you could make this an ajax request, or whatever logic you need. In the following case, typing 'abc' in the text box will make the go button enabled.
HTML:
<input type="text" title="abc" id="in">
<input type="button" id="go" value="Go" disabled="disabled">
Javascript:
$("#in").keyup(function() {
if($(this).val() == $(this).attr("title")) {
$("#go").removeAttr("disabled");
}
});
JSFiddle