Radio input checked with keyboard shortcut doesn't trigger event change - javascript

I have added a keyboard shortcut to my script so that when I press ctrl + 1 the first "source" radio input is checked :
if (e.key == "1" && e.ctrlKey) {
document.getElementsByName("source")[0].checked = true;
}
So far everythin is good. I have added an event listener so that when the state of my radio input are changed, then several things happen. But this event listener isn't triggered when I press ctrl+1 even thought the state of the radio input is changed (I can see the color of the input changing). If click manually on the radio input then the event listener is working:
var radiosource = document.getElementsByName("source");
for (var i = 0; i < radiosource.length; i++) {
radiosource[i].addEventListener('change', function (e) {
var input_changed_id = e.target.id;
if (input_changed_id.includes("en")) {
document.getElementById("fr_target").checked = true;
current_target = "fr";
}
if (input_changed_id.includes("fr")) {
document.getElementById("en_target").checked = true;
current_target = "en";
}
translate();
});
}
Here is the full script (cf lines 119 and lines 49 and 322)

It won't trigger if you change the checked value manually but your event will trigger if you simulate the click on the radio button using .click().
So just update your keyboard shortcut script to this:
if (e.key == "1" && e.ctrlKey) {
document.getElementsByName("source")[0].click();
}

Related

Select previous sibling of input by backspace in javascript

I have an input field with the name box. I can move forward after input by
box.addEventListener('input', function () {
if(!isNaN(parseInt(box.value))){
box.value = "";
}else if(box != null){
box.nextSibling.focus();
}
});
And it's working alright. I wish to move to the previous sibling of the input by backspace, and I am doing it by the previous sibling and kind of the same logic
box.addEventListener('keyup', function (e) {
if(e.key == 'Backspace' && box != null){
box.previousSibling.focus();
}
})
But doing this only works for the first backspace properly, for the rest of the inputs I need to backspace twice. I tried with the keydown event too and even that wasn't perfect.
The problem is that (in the browsers you and I are using) input events are processed before keyup events, so you press backspace on a non-empty box and a character is deleted, so input is processed then the next sibling is selected, then the keyup is processed and you move to the previous sibling, which looks like going nowhere.
You can fix this by storing the box where the value changed, then if that reference is not null on backspace keyup you can move to the previous sibling of the box where the keyup event fired, otherwise move to the previous sibling of the box where the input event fired.
const boxes = document.getElementById('boxes');
let inputInput = null;
for(let i = 0; i < 12; i++)
{
const box = document.createElement('input');
box.type="text"
box.addEventListener('input', function (e)
{
if(!isNaN(parseInt(box.value)))
{
box.value = "";
}
else if(box != null)
{
inputInput = box;
box.nextSibling.focus();
}
});
box.addEventListener('keyup', function (e)
{
if(e.key == 'Backspace' && box != null)
{
if(inputInput == null)
{
box.previousSibling.focus();
}
else
{
inputInput.previousSibling.focus();
inputInput = null;
}
}
});
boxes.appendChild(box);
}
<div id="boxes">
</div>
The problem with this solution is that event precedence is not part of the specification, so this is not necessarily cross browser compatible, i.e. in some browsers keyup might happen before input.

Use a preventdefault to get out of the loop after pressing Enter key

This is a complete revision of my initial question, all unnecessary resources and references were deleted
I am tying the same event listener to 2 different elements: a button and Enter key, and it looks like the following:
var funcelement = function(){
//function code
};
$('#buttonID').click(funcelement);
$('#inputID').keyup(function () {
if (event.which == 13) {
$('#buttonID').trigger('click');
}
})
What I am trying to do is to prevent propagation of the enter key press if focus is on the submit button(#buttonID) by using preventDefault().
So I tried various combinations to make it work. The following is the latest result on my attempts
$('#inputID').keyup(function () {
var hasfocus = $('#buttonID').is(':focus') || false;
if (event.which == 13) {
if (!hasfocus) {
event.preventDefault();
$('#buttonID').trigger('click');
//hasfocus = true;
}
else {
//event.preventDefault();
//$('#buttonID').trigger('click');
}
}
})
After I enter a text into an input box and press Enter key, a confirmation window with yes/cancel buttons pops up with focus on yes button. Once I press Enter again, another window confirming that changes were made pops up with Ok button focused on it. Once I press Enter again, everything I need is being made.
However, there is one problem: after the last step is done, I am going back to the if (!hasfocus) line.
How do I prevent that from happening? Once the stuff I need is done - I don't want to go into that line again.
You can pass a parameter to into the function and stop the propagation there like so:
var funcelement = function(event, wasTriggeredByEnterKey){
if (wasTriggeredByEnterKey && $('#buttonID').is(':focus')) {
event.stopPropagation;
}
//function code
};
$('#buttonID').click(funcelement);
$('#inputID').keyup(function () {
if (event.which == 13) {
$('#buttonID').trigger('click', [true]);
}
}
)
UPDATE
In order to answer your revised issue, you should use the "keydown" event rather than "keyup" when working with alerts. This is because alerts close with the "keydown" event but then you are still triggering the "keyup" event when you release the enter key. Simply change the one word like this:
$('#inputID').keydown(function () {
var hasfocus = $('#buttonID').is(':focus') || false;
if (event.which == 13) {
if (!hasfocus) {
event.preventDefault();
$('#buttonID').trigger('click');
//hasfocus = true;
}
else {
//event.preventDefault();
//$('#buttonID').trigger('click');
}
}
})

How do you simulate a drag event (mousemove with a button clicked)?

I want to be able to trigger the event and have it show that there was actually a button that was down at the time the event was fired.
$('table').on('mousemove', function(e) {
var is_dragging = e.buttons.length > 0;
// is_dragging should === true;
});
$('table').trigger('mousemove'); // is_dragging will be false
Try this out. Creating a custom event and attaching buttons property to it.
$('table').on('mousemove', function(e) {
var is_dragging = e.buttons.length > 0;
// is_dragging should === true;
});
var e = $.Event( 'mousemove' );
e.buttons = ['<set any key you need>'];
$('table').trigger(e);
So based on what i think you are trying to accomplish. You want to have an event handler for onmousemove where you are checking to see if a button is down (doesn't matter which button is down) however you want to manually trigger the event and have the condition is_dragging result in true.
If the event is manually triggered using $('table').trigger('mousemove');the event will not have a buttons property however it will have a .isTrigger property which will == 3.
Try this:
https://jsfiddle.net/SeanWessell/L2z0su3j/
$('table').on('mousemove', function(e) {
var is_dragging = e.buttons > 0 || e.buttons == undefined && e.isTrigger == 3;
// is_dragging should === true;
$('p').html(is_dragging.toString())
});
$('#trigger').click(function(){
$('table').trigger('mousemove');
})
::UPDATE::
look into ondragstart
http://www.w3schools.com/jsref/event_ondragstart.asp
=======
*.buttons is for what button you have clicked. At the time of mousemove you have not clicked a button.
Meaning your e.buttons === 0
Documentation on MouseEvent.button:
http://www.w3schools.com/jsref/event_button.asp
You can verify this by throwing a debugger in your function and inspecting your e variable
JSFiddle:
http://jsfiddle.net/qf3u8m61/

Prevent jumping to the second row after pressing Enter on a text area

I have a <textarea> that onkeypress ('Enter') sends a message in a live chat. The problem is that after pressing first time "Enter", the textarea field starts from the second input row.
How do I make the field reset or not taking "Enter" as a next row value?
Code:
<textarea disabled = "enabled"
onblur = "stopTyping();"
onfocus = "playTitleFlag=false;
window.title='';"
onkeypress = "tryToSend(event);"
id = "chatmsg"
rows = "1"
cols = "1"
class = "chatmsg"></textarea>
And the onkeypress function:
function tryToSend(event) {
var key = event.keyCode;
if (key == "13") {
sendMsg();
return;
}
var msg = document.getElementById("chatmsg").value;
if (trim(msg) != "") {
typing();
}
else {
stopTyping();
}
}
To cancel the default behaviour you should use return false;
see What's the effect of adding 'return false' to a click event listener?
To reset a textarea simply set its value to "". document.getElementById(f).value = "";
P.S
Note that event.keyCode return an integer

JSF: How to submit the form when the enter key is pressed?

It would appear to be a simple requirement, but I haven't found a simple solution yet:
In a JSF 1.2 / Richfaces 3.3 webapp, I have a form with input components of various types, followed by an <a4j:commandButton> and a <h:commandButton>. The former resets the form, the second performs some action with the data entered.
My goal is to have this action triggered when the user presses the enter key while entering data. How can I do that?
Edit: Generally, I have more than one <h:commandButton> per <form>. I'd like to designate a particular one as default action. Also, I'd like the solution to play nice with AJAX (which we use extensively).
Unless you are using MSIE browser and in reality you've only one input field without a button, it should just be the default behaviour. Otherwise probably some (autogenerated) JS code has messed it up.
If you don't have textareas in the form, an easy fix would be the following:
<h:form onkeypress="if (event.keyCode == 13) submit();">
Or if you have textareas and you don't want to repeat the same keypress functions over all non-textarea input elements, run the following script during window onload.
for (var i = 0; i < document.forms.length; i++) {
var inputs = document.forms[i].getElementsByTagName('input');
for (var j = 0; j < inputs.length; j++) {
inputs[j].onkeypress = function(e) {
e = e || window.event;
if (event.keyCode == 13) {
this.form.submit();
return false;
}
};
}
}
Building on BalusC's answer I came up with the following (tested on IE and FireFox):
<h:form id="form" onkeypress="ifEnterClick(event, #{rich:element('searchButton')});">
where ifEnterClick is defined by:
/**
* Handler for onkeypress that clicks {#code targetElement} if the
* enter key is pressed.
*/
function ifEnterClick(event, targetElement) {
event = event || window.event;
if (event.keyCode == 13) {
// normalize event target, so it looks the same for all browsers
if (!event.target) {
event.target = event.srcElement;
}
// don't do anything if the element handles the enter key on its own
if (event.target.nodeName == 'A') {
return;
}
if (event.target.nodeName == 'INPUT') {
if (event.target.type == 'button' || event.target.type == 'submit') {
if (strEndsWith(event.target.id, 'focusKeeper')) {
// inside some Richfaces component such as rich:listShuttle
} else {
return;
}
}
}
if (event.target.nodeName =='TEXTAREA') {
return;
}
// swallow event
if (event.preventDefault) {
// Firefox
event.stopPropagation();
event.preventDefault();
} else {
// IE
event.cancelBubble = true;
event.returnValue = false;
}
targetElement.click();
}
}
Edit: Since selecting a value from Firefox form auto completion using the enter key fires a keydown event, but no keypress event, using onkeypress is preferable to onkeydown.
Just put this code in your JS file:
$('input,textarea').live('keydown',function(e) { // submit forms on pressing enter while focus is on any input elmnt inside form
if (e.keyCode == 13) {
$(this).closest('form').submit();
}
});
In retrospect, solving this problem with the means HTML provides is far less brittle and easier to maintain, as the answers to the following related question show:
Multiple submit buttons on HTML form – designate one button as default
Use the PrimeFaces component:
<!-- Default button when pressing enter -->
<p:defaultCommand target="submit"/>
Use this in combination with a focus component and you will rock!
<!-- Focus on first field, or first field with error -->
<p:focus context="feesboek"/>

Categories

Resources