How to preventDefault() textInput event? - javascript

I have a textarea on my page. If user on Windows (not sure about Mac behavior though) will open built-in Emoji menu (Win + .) in that textarea and click on any emoji, the textInput event will be fired. I need to, somehow, prevent default behavior for this event, which is inserting an emoji to the input, and resolve emoji insertion on my side. However, event.preventDefault() doesn't work in this case. Any ideas?

I do not think you can handle the emoji interface using preventDefault.
We cannot detect the combination of event.key==="Meta" and "."
Here is how to handle it after the fact:
const re = /\p{Emoji}|\p{Emoji_Presentation}|\p{Extended_Pictographic}/ug; // can be extended
document.getElementById('myField').addEventListener('input', function(e) {
const val = this.value;
this.value = val.replace(re,"");
})
<textarea id="myField"></textarea>
the script above is from combining the information from the answers below
How to detect emoji using javascript
What is the difference between {Emoji_Presentation} and {Extended_Pictographic}?

Related

Keyboard and mouse events # Accessbility

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.

javascript function "document.getElementById()" does the work as expected

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.

React On Screen Keyboard does not Trigger Change Event

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

How to bypass Quick Search Firefox feature and capture forward slash keypress

I'm capturing the key press value of '191' for the forward slash (/) for a feature on my site. Works fine on every browser except Firefox due to its Quick Search feature. The '191' still registers and the action is executed (focus on an input field, popup help text), but the focus goes to the Quick Search.
I read in another StackOverflow question saying that Firefox captures the forward slash as character code '0', but that didn't do anything.
Is there a way I can ignore the Firefox Quick Search and get control of the forward slash back? Using JavaScript and jQuery.
I agree it's important to question whether you should be using that shortcut. However, if you decide to (as others have- that's the search shortcut in gmail as well), you just need to capture the document keydown event (not keypress or keyup) and then prevent the default action, which will intercept in time to stop the default firefox behavior. Also, be sure to check that the user isn't already typing in a text field. Here's a quick example:
$(document).keydown(function(e) {
var _target = $(e.target);
var _focused = $(document.activeElement);
var _inputting = _focused.get(0).tagName.toLowerCase()==="textarea" || _focused.get(0).tagName.toLowerCase()==="input";
// / (forward slash) key = search
if (!_inputting && e.keyCode===191) {
e.preventDefault();
$("#search-input").focus();
return;
}
});

Crossbrowser equivalent of explicitOriginalTarget event parameter

Does anyone know of crossbrowser equivalent of explicitOriginalTarget event parameter? This parameter is Mozilla specific and it gives me the element that caused the blur. Let's say i have a text input and a link on my page. Text input has the focus. If I click on the link, text input's blur event gives me the link element in Firefox via explicitOriginalTarget parameter.
I am extending Autocompleter.Base's onBlur method to not hide the search results when search field loses focus to given elements. By default, onBlur method hides if search-field loses focus to any element.
Autocompleter.Base.prototype.onBlur = Autocompleter.Base.prototype.onBlur.wrap(
function(origfunc, ev) {
var newTargetElement = (ev.explicitOriginalTarget.nodeType == 3 ? ev.explicitOriginalTarget.parentNode: ev.explicitOriginalTarget); // FIX: This works only in firefox because of event's explicitOriginalTarget property
var callOriginalFunction = true;
for (i = 0; i < obj.options.validEventElements.length; i++) {
if ($(obj.options.validEventElements[i])) {
if (newTargetElement.descendantOf($(obj.options.validEventElements[i])) == true || newTargetElement == $(obj.options.validEventElements[i])) {
callOriginalFunction = false;
break;
}
}
}
if (callOriginalFunction) {
return origFunc(ev);
}
}
);
new Ajax.Autocompleter("search-field", "search-results", 'getresults.php', { validEventElements: ['search-field','result-count'] });
Thanks.
There is no equivalent to explicitOriginalTarget in any of the other than Gecko-based browsers. In Gecko this is an internal property and it is not supposed to be used by an application developer (maybe by XBL binding writers).
2015 update... you can use event.relatedTarget on Chrome. Such a basic thing, hopefully the other browsers will follow...
The rough equivalent for Mozilla's .explicitOriginalTarget in IE is document.activeElement. I say rough equivalent because it will sometimes return a slightly different level in the DOM node tree depending on your circumstance, but it's still a useful tool. Unfortunately I'm still looking for a Google Chrome equivalent.
IE srcElement does not contain the same element as FF explicitOriginalTarget. It's easy to see this: if you have a button field with onClick action and a text field with onChange action, change the text field and move the cursor directly to the button and click it. At that point the IE srcElement will be the text field, but the explicitOriginalTarget will be the button field. For IE, you can get the x,y coordinates of the mouse click from the event.x and event.y properties.
Unfortunately, the Chrome browser provides neither the explicitOriginalTarget nor the mouse coordinates for the click. You are left to your own devices to figure out where the onChange event was fired from. To do this, judicious use of mousemove and mouseout events can provide mouse tracking which can then be inspected in the onChange handler.
Looks like it is more designed for extension writers than for Web design...
I would watch the blur/focus events on both targets (or potential targets) and share their information.
The exact implementation might depend on the purpose, actually.
For IE you can use srcElement, and forced it.
if( !selectTag.explicitOriginalTarget )
selectTag.explicitOriginalTarget = selectTag.srcElement;
In case of form submit events, you can use the submitter property in all modern browser (as of 2022).
let form = document.querySelector("form");
form.addEventListener("submit", (event) => {
let submitter = event.submitter; //either a form input or a submit button
});

Categories