I'm trying to listen to keyboard events in contenteditable and apply the same events to an input element (or applying e.keyCode to an input). I've tried this. Element.dispatchEvent will only trigger event listeners but don't seem to change the input value.
But it doesnt update the input value. I don't want to rely on manually modifying the input.value because i need to account for things like backspace.
contentEditableDiv.addEventListener('keydown', e => {
inputElement.dispatchEvent(e);
});
Reason why i need this:
When user enters a hotkey, i show a context menu so the user can continue typing and i can filter the list, i want to throw all those events into an input so that i can use the input value to filter through my list.
try this
document.onkeypress = (e) => console.log(e)
Related
I have a form with multiple stacked <input type="text"> boxes, and I check for an "Enter" press on the form's keydown event, moving to the next input down if this happens, and returning false to prevent form submission. (Yes, that's the oldschool way... but I want to support legacy browsers).
form.onkeydown = checkEnter;
and
function checkEnter(e)
{
e = e||window.event;
var el, tag, typ, k = e.keyCode||e.which;
if ((k===13)&&(el = e.target||e.srcElement)&&(((tag = el.tagName)==="SELECT")||((tag==="INPUT")&&((typ = el.type)!=="submit")&&(typ!=="reset")&&(typ!=="button"))))
{
// focus next form element
// ...
return false;
}
}
The problem is that if I press down-arrow in an input and the autocomplete list opens, I can select a value from that list using the mouse as normal, but if I choose a value using the arrow keys instead and then press "Enter" to select that value, my event prevents this from happening in Firefox 61 and Edge 42 (but it does work as expected in Chrome 67). This makes autocomplete unusable without a mouse.
My question is: Can I block keydown events from triggering when the focus is inside the autocomplete history list, rather than inside the element itself? Or alternatively, can my event somehow detect that the autocomplete list is showing? I'd like "Enter" pressed while in the autocomplete list to perform its default behaviour, i.e. selecting the autocomplete entry.
Note that Chrome is possibly avoiding the issue because the value in the <input> changes as you navigate the autocomplete list.
Note that changing to using the keypress event (instead of keydown) makes no difference (at least in FF 61).
Turns out that what was interfering with autocomplete was not the
return false;
Rather, it was the part where I set focus to the next form element. This solved the specific problem I was having (note the change to keydown instead of keypress, it's necessary):
form.onkeypress = checkEnter;
and
function checkEnter(e)
{
e = e||window.event;
var el, tag, typ, nextEl, k = e.keyCode||e.which;
if ((k===13)&&(el = e.target||e.srcElement)&&(((tag = el.tagName)==="SELECT")||((tag==="INPUT")&&((typ = el.type)!=="submit")&&(typ!=="reset")&&(typ!=="button"))))
{
// nextEl = form element to switch focus to next
// ...
if (nextEl) setTimeout(function(){nextEl.focus()},0);
return false;
}
}
i.e. defer the focus change until after the keypress event has completed, using setTimeout().
So I answered my specific problem, of fixing autocomplete behavior in this case. But I still don't know the answer to the general question as I posed it, i.e.:
Can I block keydown events from triggering when the focus is inside
the autocomplete history list, rather than inside the element itself?
Or alternatively, can my event somehow detect that the autocomplete
list is showing?
For example, I have another page where I want an "Enter"-press in an <input> to perform a specific action, only not if it was pressed to select an autocomplete entry.
...So if anyone has a solution to the more general problem, please post it!
make any search in google and you end up with the search text box and various other HTML elements (for the various matches).
I noticed that, no matter which HTML element has the focus, if you type a letter/number it gets picked up by the search text box.
Can somebody explain to me how google achieves that ?
I'd like to do something similar on my site.
p.s.
I was thinking to listen to key events from document but I am not sure if that is a good idea...
You can try something like this.
The main ideea is to capture keyboard events closer to the root, window would be fine. Once you catched up one, you should focus your search input by adding the correct character typed before focusing. On input focus, don't forget to unbind the window keyup handler and bind it again on input blur. Some startup code to help you:
$(document).ready(function() {
var windowKeyupHandler = function(e) {
var code = e.which || e.keycode;
$('#typer').focus().val( $('#typer').val() + ' ' + String.fromCharCode(code).toLowerCase());
$(window).off('keyup.window');
};
$(window).on('keyup.window', windowKeyupHandler);
$('#typer').on('blur', function(e) {
$(window).on('keyup.window', windowKeyupHandler);
});
});
One way is listening to key down on window and channeling it to the input.
Other way would be to capture each key down (that its target is not the input, you can see it in the event object), and set focus to the input, then appending the key. This way only the first key down would need to be "caught", the other will be automatically typed in the input.
I've tried looking for a list of all the possible events that can be used in the a4j:support event attribute. I cant find any reference that lists them, maybe somebody can provide a link?
I'm aware of the obvious ones like onclick, onchange, etc.
The reason I ask this is that I currently have an input text field. It has the onkeyup event attached to it via the a4j:support tag. It should enable a text box when the event fires.
The event does not fire when a user right clicks their mouse and pastes content into the field.
Is there an alternative event I could use to ensure this case is managed?
<h:inputText id="someName" value="#{myBean.example.exampleName}" maxlength="25" style="width:280px">
<a4j:support event="onchange" reRender="exampleTab"
action="#{myBean.activateTabPanel}" ajaxSingle="true"
ignoreDupResponses="true" />
</h:inputText>
<rich:tabPanel id="exampleTab" switchType="server"
style="width:100%;height:448px;" styleClass="top_tab"
inactiveTabClass="inactive_tab" activeTabClass="active_tab"
selectedTab="#{myBean.exampleTabState.selectedTab}">
<!-- Various stuff in here --->
</rich>
## ************ Update ***********##
I actually went with a jQuery solution in the end. Was much cleaner. Code attached for anyone interested.
jQuery(document).ready(function() {
// Call contructor
var common = new Site.Common();
});
// Constructor
Site.Common = function() {
// Only attach event listener if the element exists on page
if ( jQuery('input[id$="suggest"]') ) {
jQuery('input[id$="suggest"]').bind('paste', Site.Common.handleMousePaste.bind(this));
}
};
// Trigger the keyup event when user uses mouse to paste content info a field('element')
Site.Common.handleMousePaste = function(event) {
// Need to split the id (JSF adds the form name in front of the input field!)
var idParts = event.target.id.split(':');
// Reformat the id we will pass to jQuery (It does not understand formName:fieldName, need to escape the ':')
if (idParts.length >= 2) {
var formattedID = "#" + idParts[0] + "\\:" + idParts[1];
}
else {
var formattedID = "#" + event.target.id;
}
// Need to put a tiny delay in so the element has time to get the pasted in content.
setTimeout(function() { jQuery(formattedID).keyup(); }, 10);
};
Thanks
you can detect the paste event in js and activate your function then.
attached is a link that deals with similar problem
link
in it change what happens after the paste is detected
if (event.ctrlKey && event.keyCode == 86) //Paste event
call your function
The keyboard events do not suppose to work when clicking on the mouse (pasting, clicking, etc).
As I understand you searching for a OnChange event but the OnChange is not good for you because
you need that the event will fire in any input that the input text get.
The solution is to use the new HTML5 OnInput Event. The OnInput event fire in any input e.g. past using
the mouse, typing, pasting using the keyboard, etc.
It also support all the new browsers, I test it on: IE9,IE10,IE11,Chrome,Firefox,Safari and Opera.
The list of possible values for the event attribute is not fixed, as explained in the documentation:
Name of JavaScript event property ( onclick, onchange, etc.) of parent component, for which we will build AJAX submission code
So basically, it means that you can set in the event attribute, any onXXX event that is available on the parent component.
Regarding your problem, you can eventually duplicate your <a4j:support event="onkeyup"> with a <a4j:support event="onchange">.
Note that if your request is just to enable a text box, maybe you can do that using JavaScript, and not with Ajax call (i.e. using <a4j:support>).
I want to ask a question about the JavaScript event. I have an <input type="text"> box and I have applied the autocomplete function on that box.
I know that when the user types the char like "sta" in the box and the JavaScript will call the keypress event, which also calls the autocomplete function.
However, I want to know what event of the JavaScript will be called what I use the mouse to click/click the keyboard "enter" to the wanted item from the autocomplete list.
The mouse clicking event is called onclick, the enter key event is called an onkeyup event. For the second one, you need to make sure the enter key was pressed, though:
someElement.onkeyup = function( e ){
var e = e || window.event;
if( e.keyCode == 13 ){
// enter was pressed!
}
};
However, I want to know what event of the JavaScript will be called what I use the mouse to click/click the keyboard "enter" to the wanted item from the autocomplete list.
It sounds like you are looking for an event which triggers after text of the text box changes. If that is the case, the event fired is onchange.
That will take care if user select autocomplete option either via mouse or hits the enter button.
How can I reliably detect all events that cause the the value of an HTML select to change, while that element still has the focus?
For regular mouse input, either the click or change event works fine. For keyboard input (and for mouse input using the scroll wheel), however, the change event doesn't fire until focus is lost. I get around this by using the keyup event for keyboard changes (and ignoring the mouse wheel problem) but find my code is littered with a lot of stuff like this:
$(".my-select").keyup(handleSelect).change(handleSelect);
function handleSelect() {
var $this = $(this);
// don't process keyup events that don't result in change
if ($this.data('old-val') == $this.val()) { return; }
$this.data('old-val', $this.val());
// ... other stuff ...
}
Is there a simpler pattern/recipe that solves this problem (jQuery or straight JavaScript)?
"change" doesn't fire until the element loses focus, by design. What you're doing may be the only way to solve this. You can also look at selectedIndex as well as value.
As Diodeus said, the change event is fired when the element loses focus. But you could check if the pressed key is the enter key and then call your function. And I think hardly anybody uses the mouse wheel to change the value of a select box...