control the execution of events in JavaScript - javascript

I'm using "onkeydown" event to implement an OTP verification layout , so when I try to delete the event first focuses on the previous element before deleting the current element , how di I get the event to execute the default action first the move along
inputField[index].onkeydown = function (e) {
if (e.keyCode == "8") {
array[index].blur();
array[index - 1].focus();
}
}

Related

React event propagating in the else case

let's say I have a function that gets executed on key press that looks like something like this. I want to have special case for when Enter is pressed otherwise I want even to propogate/bubble up to the browser. Therefore, if any other key is pressed this i.e up or down arrows they should work.
onAutosuggestInputKeyDown = event => {
if (event.key === 'Enter') {
this.onCustomSuggestionCreate(event)
} else {
// keep propgating the event
}
}
getAutosuggestInputProps = () => {
return {
inputProps: {
onBlur: this.onCustomSuggestionCreate,
onKeyDown: this.onAutosuggestInputKeyDown,
},
}
}
<ReactAutoSuggest textFieldProps={this.getAutosuggestInputProps()}/>
If I understand your situation correctly, then even propagation should occour by default (depending on the type of element that fired the event).
You would however, likely want to use stopPropagation() in the case of the enter key being pressed to prevent the propagation of that event, which would be achieved by the following update to your onAutosuggestInputKeyDown method:
onAutosuggestInputKeyDown = event => {
if (event.key === 'Enter') {
// Prevent this event from propagating if enter key pressed
event.stopPropagation()
this.onCustomSuggestionCreate(event)
}
// If stopPropagation() not called on event, the event will propagate
// if it has the ability to do so (ie from the element dispatching the
// event)
}

Catching TAB key press with keyup

I need to archieve 2 objectives but I archive one at time, never both of them.
First I have an input field that should fires an event when a key is pressed and I need to catch the field value. I use letters, number and the TAB key. So if I use keyup it fires at the first char. If I use keydown it takes 2 char to fire because when it fires the first time the char is not pressed yet. So when I press for the second time it fires with the first letter and so on.
Said that, it is clear that what I need is the keyup event that put the value in the field then the event is fired. But TAB has a special meaning in my case and it is not the default behavior and with TAB key I am unable to catch e.which, e.charCode nor e.keyCode! Only with keydown I am able to get those value!
Now I don´t have a clue what to do. How could I catch TAB key or make keydown catch the value of a field?
P.S keypress also working as keydown. Event is fired before I have the value in the field
EDIT 1:
Here is the code:
$('input[data-action="keyupNome"]').each(function () {
$(this).on("keypress", function(e) {
//Se o campo não estiver vazio
if($(this).val() != '') {
if(key != 9) // the tab key code
{
limpaCamposBusca('nome');
var width = $('#nomeBusca').width();
$('.nomeContainer').css('width', width);
$('.displayNomeTbl').css('width', width);
buscaEndereco('Controller/Dispatcher.php?classe=Buscas&acao=buscaEnderecoPorNome', 'nome');
}//if key == 9
else {
alert('here');
e.preventDefault();
}
}// val == ''
else {
clearFields();
clearBuscaCliente();
reactivateFields();
}
});
});
The trick is to use keydown and to combine actual value of the field with the char currently pressed OR to catch TAB in keydown and set an external variable to be used in keyup as in my example.
EDIT :
In fact, I realized that not preventing default behavior of TAB in keydown doesn't fire keyup. So, no variable is needed, but only preventing TAB on keydown. Anyhow, this version always work if the glitch you talked about exist in some circumstances.
(function() {
var tabKeyPressed = false;
$("#t").keydown(function(e) {
tabKeyPressed = e.keyCode == 9;
if (tabKeyPressed) {
e.preventDefault();
return;
}
});
$("#t").keyup(function(e) {
if (tabKeyPressed) {
$(this).val("TAB"); // Do stuff for TAB
e.preventDefault();
return;
}
//Do other stuff when not TAB
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="t" value="">

Javascript capturing keydown

I have a form with many fields and when the user does a "double Enter" in any of the fields doSomething() should happen.
The code below basically works ok, apart from the fact that doSomething() gets called as many times as there are characters in that field. It should only be called once, while if I put "ABC" in the field, doSomething() gets called 3X. It only needs to be called once after 2X Enter, regardless of what was entered in the field.
I (kind of) understand why it's happening (keydown was called 3 times) but have no idea how to fix it. Do I need to unbind something? Resetting the counter to 0 when e.keyCode isn't 13 doesn't seem to make a difference.
EDIT - http://jsfiddle.net/hzr8cezn/ - I'm using 2X SPACE bar character to test since Enter tries to submit the form on jsfiddle. Hit 2X space (in Chrome) and check your console
$("#dynamicFields").on('keydown', 'input', function(e) {
var counter = 0
var field = $(this)
field.keydown(function (e) {
if(e.keyCode == 13) {
counter++;
if(counter == 2) {
console.log('twice!')
doSomething()
}
}
else {
counter = 0
}
})
})
You are attaching to the "keydown" event twice, once using on() and the other using keydown(). You only need to do this once.
Since you are tracking the counter per element, you can use a data() call to track it on the element itself.
// init counter to 0
$("#dynamicFields input").data('counter',0);
// bind to keypress event
$("#dynamicFields").on('keydown', 'input', function(e) {
// the input field
var $field = $(this);
// enter key?
if ( e.keyCode == 13 ){
// how many times?
var counter = $field.data('counter');
// increment it
$field.data('counter',++counter);
// do the stuff
if ( counter >= 2 ){
alert('well, you did it.');
}
} else {
// reset
$field.data('counter',0);
}
})
See it working in this jsFiddle.

Multiple event listener in Javascript

How to add multiple event listeners in the same initialization?
For example:
<input type="text" id="text">
<button id="button_click">Search</button>
JavaScript:
var myElement = document.getElementById('button_click');
myElement.addEventListener('click', myFunc());
This is working correctly however I would like to have another event listener for this input filed in the same call if that is possible, so when user clicks enter or presses the button it triggers the same event listener.
Just one note. User needs to be focused on the input field to trigger an "enter" event.
Just bind your function to 2 listeners, each one of the wished element:
document.getElementById('button_click').addEventListener('click', myFunc);
document.getElementById('text').addEventListener('keyup', keyupFunc);
where the new function test if the user pressed enter and then execute the other function :
function keyupFunc(evt) {
if(evt.keyCode === 13) // keycode for return
myFunc();
}
Working jsFiddle : http://jsfiddle.net/cG7HW/
Try this:
function addMultipleEvents(elements, events){
var tokens = events.split(" ");
if(tokens.length == elements.length){
for(var i = 0; i< tokens.length; i++){
elements[i].addEventListener(tokens[i], (e.which == 13 || e.which == 48)?myFunc:); //not myFunc()
}
}
}
var textObj = document.getElementById("textId");
var btnObj = document.getElementById("btnId");
addMultipleEvents([textObj,btnObj], 'click keyup');
UPDATE:
function addMultipleEvents(elements, events) {
var tokens = events.split(" ");
if (tokens.length == elements.length) {
for (var i = 0; i < tokens.length; i++) {
elements[i].addEventListener(tokens[i], myFunc); //not myFunc()
}
}
}
var textObj = document.getElementById("textId");
var btnObj = document.getElementById("btnId");
addMultipleEvents([btnObj, textObj], 'click keyup');
function myFunc(e) {
if (e.which == 13 || e.which == 1) {
alert("hello");
}
}
Working Fiddle
I think the best way to do this is by using for loops.
const events = ["click", "mouseover"]
for (i in events) {
document.getElementById("button_click").addEventListener(events[i], () => myFunc())
}
The code above loops through every events inside an array and adds it to the button.
Yeah this is a good question and can apply to other scenarios. You have a form and a user will have input text field, a radio box, a select option. So now you want the submit button to go from disabled to enabled. You decide to add an event listener to check if fieldA and fieldB and fieldC is first to enable submit button.
If you use event listener on Keyup", and all your fields are valid, the submit button will become enabled only if the last field is a text field because the event will only be triggered when you let go the key. This means it will not trigger if the radio box or select option is selected with your mouse. We must not rely in the order the fields are filled for the logic to work. Again, If you use "click", it sucks, because user will have to click somewhere on page in order for the event listener to fire and run the logic. So i think we'll need an event lister on mouseup, keyup and change for this example below. I assume you made all your validations and variables for the form fields already. We need a function with parameters of multiple events names as a string, the element we want to target (document, or button or form), and a custom function that contains our logic.
// Create function that takes parameters of multiple event listeners, an element to target, and a function to execute logic
function enableTheSubmitButton(element, eventNamesString, customFunction) {
eventNamesString.split(' ').forEach(e => element.addEventListener(e, listener, false));
}
// Call the above function and loop through the three event names inside the string, then invoke each event name to your customFunction, you can add more events or change the event names maybe mousedown, keyup etc.
enableSubmitButton(document, 'keyup mouseup change', function(){
// The logic inside your customFunction
if (isNameValid && isLocationValid && isProjectValid){
publishButton.disabled = false;
} else {
publishButton.disabled = true;
// Do more stuff like: "Hey your fields are not valid."
}
});
// The isNameValid isLocationValid, isProjectValid are coming from your previous validation Javascript for perhaps a select field, radio buttons, and text fields. I am adding it as an example, they have to be equal to true.
// The publishButton is a variable to target the form submit button of which you want enabled or disabled based one weather the form fields are valid or not.
// For example: const publishButton = document.getElementById("publish");

ASP.NET Post-Back and window.onload

I got a function which checks if some input fields are changed:
var somethingchanged = false;
$(".container-box fieldset input").change(function() {
somethingchanged = true;
});
And a function which waits on window.onload and fires this:
window.onbeforeunload = function(e) {
if (somethingchanged) {
var message = "Fields have been edited without saving - continue?";
if (typeof e == "undefined") {
e = window.event;
}
if (e) {
e.returnValue = message;
}
return message;
}
}
But if I edit some of the fields and hit the save button, the event triggers, because there is a post-back and the fields have been edited. Is there anyway around this, so the event does not fire upon clicking the save button?
Thanks
When I do this pattern I have a showDirtyPrompt on the page. Then whenever an action occurs which I don't want to go through the dirty check I just set the variable to false. You can do this on the client side click event of the button.
The nice thing about this is that there might be other cases where you don't want to prompt, the user you might have other buttons which do other post backs for example. This way your dirty check function doesn't have to check several buttons, you flip the responsability around.
<input type="button" onclick="javascript:showDirtyPrompt=false;".../>
function unloadHandler()
{
if (showDirtyPrompt)
{
//have your regular logic run here
}
showDirtyPrompt=true;
}
Yes. Check to see that the button clicked is not the save button. So it could be something like
if ($this.id.not("savebuttonID")) {
trigger stuff
}

Categories