I have created an on screen keyboard (osk) to be used in a kiosk style React app. The osk works as it should and inputs desired text etc. into the appropriate elements. My problem is that inputting text with the osk does not trigger a change event on the target so my onChange handler never gets called. I have attempted to trigger the change event after inserting my my text with the osk as shown below however, my existing onChange handler does not get called the way it does when entering text with the keyboard. What is the best 'React' way to handle this? PS- I am not using jQuery. Thanks!
//update element text from osk
this.props.target.value = (this.props.target.value + btnText);
//attempt to trigger change event
this.props.target.dispatchEvent(new Event('change'));
//input updated from osk
const ce = React.createElement;
ce("input", {
id: "PasswordText",
type: "password",
data: "text",
onClick: this.clickHandler,
defaultValue: this.props.accessPassword,
onChange:this.changeHandler})
//change handler
changeHandler(e) {
this.setState({
stateObject: e.target.value
});
}
The problem, as Mark point, is due to React not listening to those events (or not trusting them).
To trigger the input event, you have to edit the Extension:
Find the dir where the extension is stored on your system
Open script.js with your favorite editor
Find the virtualKeyboardChromeExtension_click function and add the following after the switch statement:
function virtualKeyboardChromeExtension_click(key, skip) {
[...]
switch (key) { // <- find the switch statement
[...]
} // <- after the close brace add the following 4 lines code:
var inputEvent = new Event('input', {bubbles:true});
if(typeof virtualKeyboardChromeExtensionClickedElem !== "undefined") {
virtualKeyboardChromeExtensionClickedElem.dispatchEvent(inputEvent);
}
// you are done
Save and reload the extension.
NOTE: If you are using chrome it will give you errors and warnings about modified and untrusted extension. But as you are developing a kiosk mode app I suppose you can switch to chromium, enter developer mode and use the Load unpacked extension button to load your modified extension
I had the same problem with a Virtual Keyboard extension for Chrome. Found out on an issue in react's repository that react hears the input event, not the actual change event.
In your case the solution would be to trigger this event, in my case I opted out of generic virtual keyboards and looked for a more react oriented solution (i.e. a virtual keyboard react's library)
A little late but I hope this helps some one else.
Cheers bro
Related
How to write conditions for an automatic mouse click in the UI when we press any key on the keyboard.
I'm Working on the Accessibility Part ->
My Scenario is we are having banner which is displayed when the page loads initially. for that until we close that banner the focus should be inside that banner.
I have tried the onKeyDown event. when we trigger the onKeyDown event by using e.preventDefault() the focus is hidden. I need to get that focus again when I click any key on the keyboard.
Thanks in Advance.
handleTab = (e) => {
let tabKey = false
if (e.keyCode === 9) {
e.preventDefault()
tabKey = true
}
if(tabKey) {
# here I need an automatic browser click event. so that when I hit the tab key it will go inside of that banner
}
onKeyDown = {this.handleTab()}
Try to use tabindex property to prevent tab navigation outside the banner.
<input type="text" tabIndex="-1"/>
I created small demo to test: https://codepen.io/mich_life/pen/vYRMpqe
This is what the MDN documentation has to say about keyCode:
Deprecated: This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.
key which is a textual representation of the pressed key should be used instead & has been supported since Internet Explorer 9.
Since you haven't specified, if the banner is inside or outside your component, I am going by outside.
handleTab=(evt)=> {
if(evt.key == 'Tab') {
evt.preventDefault();
document.getElementById('banner').focus();
}
}
If it's rendered inside your component, use a ref instead.
I am working on a browser recording test, in which I am entering a value into an Input field with an
auto search trigger functionality.
document.getElementById('InputFieldWIthSearchFunctionality').value = "Saurav";
But the search is not triggered if I set the value to the field as above.
Kindly help.
Just setting the value will not call the onchange and/or oninput event listeners of the input field. The auto search trigger is probably listening to this event.
You can dispatch both of these events manually to the input field:
const elem = document.getElementById("InputFieldWIthSearchFunctionality");
// create onchange event
const onchangeEvent = document.createEvent("HTMLElements");
onchangeEvent.initEvent("onchange", false, true);
// create oninput event
const oninputEvent = document.createEvent("HTMLElements");
oninputEvent.initEvent("oninput", false, true);
// dispatch events to the input field
elem.dispatchEvent(onchangeEvent);
elem.dispatchEvent(oninputEvent);
This definitely works in Chrome and all browsers using Chromium, I did not test any other browser, that would be up to you.
Information about manually dispatching events taken from this answer: https://stackoverflow.com/a/2856602/7846567
Think of it this way... by setting the value directly using JS, you are shortcutting the typical UI that a real user would use thus causing this issue. JS should be used sparingly (almost never) if you are trying to write tests that act like a user would and now you can see why.
In Java you would do this
driver.findElement(By.id("InputFieldWIthSearchFunctionality")).sendKeys("Saurav");
which would cause the search to fire in your case.
Html has many event types. I'm trying to simulate login with javascript code in a .hta . I try the following on a text input element:
user.focus();
user.value = 'JohnDoe';
user.blur();
button.click();
Yet the page responds as if I had clicked the button without entering a user name. I suspect that an event handler is registered on the element which isn't fired when I do this with a script. What van I do to establish the cause of the failure and amend it? How do I simulate the other event types on the element?
I found the answer here: How to trigger event in JavaScript?
Here's the recipe:
function fireevent(type, ele)
{
var event = win.document.createEvent("HTMLEvents");
event.initEvent(type, true, true);
ele.dispatchEvent(event);
}
Where win is the window in question. fireevent('change', user) fires a change event on the text input element user, and that was what I needed to do. Now it works :)
Beware though that createEvent is now deprecated. On IE10, which is the one I use with .hta, it works just fine.
I'm not developing in React.js, but I'm working on a chrome extension that needs to programatically fill form values for different kinds of sites.
The site uses React.js, and I'm filling the value in the usual way with:
element = document.querySelector("input[name=firstName]");
element.value = "something";
When the user clicks the submit button, he gets this error for that form element, even if the element has a value:
"This information is required."
It doesn't help if fire "change" event for that element.
evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
element.dispatchEvent(evt);
There is some method in the React.js framework I need to call to programatically change the value? Help from React.js experienced users is appreciated!
I found a solution. Call element.select(); before changing the value.
There exists a website implemented with ExtJS 3.1.
I want to pre-fill some fields automatically. The problem is, that some fields are not validated by ExtJS when automatically filling them.
I can trigger the validation by firing ExtJS's blur event:
field.fireEvent('blur', field);
However, I don't want to do this. I want that validation to be triggered by a normal event triggered via jQuery:
$field.blur();
What I am asking here is the following:
How to trigger the blur event of a textbox in the same way the browser does it, so that also ExtJS's event handlers run?
BTW: The reason why I don't want to manually fire the ExtJS event is simple: This solution seems to work for ExtJA 3.1 but no longer for 4.2 and I don't want to write special handling code for every version of ExtJS.
If you want to play around a little bit:
Here is the URL: https://www.pantaenius.com/en/service/login/request-a-quote.html?utm_source=http%3A%2F%2Fwww.pantaenius.com%2Fen%2Famerican-yacht-insurance.html&utm_medium=direct&domain_segment=33
Open it in Chrome, open Chrome's developer console and paste the following text:
delete console.log
var $city = jQuery('#ext-comp-1080');
var city = Ext.ComponentMgr.all.filterBy(function(x) { return x.isXType('combo') && x.id==='ext-comp-1080'; }).items[0];
var blurEventFireFn = city.events.blur.listeners[0].fireFn;
city.events.blur.listeners[0].fireFn = function(field) { console.log('ExtJS blur fired!'); blurEventFireFn(field); };
When you click in the City field and then in some other field, you will see the output ExtJS blur fired! in the console. You will see the same output when you execute city.fireEvent('blur', city);. However, you won't see that output when you execute $city.blur();, $city.trigger('blur'); or
var event = document.createEvent('HTMLEvents');
event.initEvent('blur', true, true);
$city.get(0).dispatchEvent(event);
Any ideas how to create this bridge between normal events and ExtJS events would be greatly appreciated.
Simulating the native event with your bit of code does work (in non-IE browsers):
var event = document.createEvent('HTMLEvents');
event.initEvent('blur', true, true);
$city.get(0).dispatchEvent(event);
However you should avoid the problem rather than giving it a weird cure, by using the validator of the field instead of a blur event listener. This way, the setValue method of the field will trigger its validation...
If you're really stuck with it, instead of adding a (probably fragile) layer of complexity by simulating events, I would just call the onBlur method of the fields directly. That's the handler that is added to the DOM by Ext. It is present in 3.x and 4.x, and it doesn't rely on specific browsers...