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.
Related
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="">
I am trying to make a number keypad from 0 to 9 and when certain numbers get pressed in a certain order an event will happen.
So something like this
if ( button1 gets pressed then button2 then button3 )
alert('You did the code!')
}
else {
alert('You did not do the code')
}
No jQuery please
Thanks!
//sequence is 358
//SOLUTION
sequence = {
check : function(e){
sequence.value += this.textContent;
if (sequence.value == sequence.sequence)
{
alert(1);
sequence.value = "";
}
else
{
if (sequence.timer)
{
clearTimeout(sequence.timer);
}
sequence.timer = setTimeout("sequence.value=''", 1000);
}
},
value : "",
sequence : "358"
}
//THIS CODE ATTACHES CLICK HANDLERS TO THE BUTTON, NOT PART OF THE SOLUTION
Array.prototype.map.call(document.querySelectorAll("button"), function(element){
element.addEventListener("click", sequence.check, false);
});
//end
<button>7</button><button>8</button><button>9</button><br/>
<button>4</button><button>5</button><button>6</button><br/>
<button>1</button><button>2</button><button>3</button><br/>
<button>0</button>
How does this work. I don't want to pollute the global scope with values so I used an object to store the variables and the check method in.
The object is called sequence.
It has three properties
check, the method that checks the input when a button is clicked.
value, that holds the sequence value until the correct sequence is found.
sequence, the property that holds the correct value.
Each button on the page is assigned with a click handler. When clicked it fires sequence.check. Via the this keyword (referring to the button) we extract the number (via textContent). We add that number to the value string. Then we check if the value matches the sequence. If so execute some code (in this case an alert) and reset the value.
There is a timer set. If the user doesn't enter a new number within a second the timer will reset the value. setTimeout does this. The 1000 stands for 1000 milliseconds = 1 second.
I would achieve this by monitoring the keydown event, and if the key is a number, add in to an array. At the same time, check the array contents to see if they are in a certain defined order. If they are, fire whatever you need to do, if not, do nothing but add the key to the array. Once your sequence has been completed, clear the array to make way for a new sequence.
You could get complicated with things like, clearing the array after a certain interval of not completing the sequence etc.
Here is a simple system that does part of what you are looking for:
var buttons = document.querySelectorAll('button'),
i;
for (i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', function() {
var pressed = document.getElementById('pressed');
pressed.value += this.value + "|";
if (pressed.value === '1|2|3|') {
alert('You unlocked it!');
}
if (pressed.value.length >= 6) {
//Start over
pressed.value = "";
}
}, false);
}
<input id='pressed' type='text' />
<button value='1'>One</button>
<button value='2'>Two</button>
<button value='3'>Three</button>
I am learning JQuery by example. Please check this fiddle: http://jsfiddle.net/4tjof34d/2/
I have two problems:
1 : showText() gets called twice when a person hits enter and thus console.log(this.id+ " " +this.value); gets called twice, What do I add so that it only gets called once?
2: I get the id and value of the textbox, but I also want to know what was the old id and value so that I can do a comparison test. How do I do that?
eg:
var oldValue = ? // How do I do this?
var newValue = this.value;
Then I can do something like:
if(newValue != oldValue)
{
// Do .ajax() - update DB
}
for your first issue showText is called twice ie,on blur and on enter
change your blur function as follows
$('.input').blur(showText).keyup(function (e) {
if(e.which === 13) {
this.blur();
}
});
for second issue i will go with a global variable as flag
http://jsfiddle.net/x1ez7Lek/6/
I have a textboxwhere I can enter values directly from keyboard or from mouse click. If I click from mouse the value is increment by one from the previous value. Whereas from keyboard I can enter any value. My question is how do I detect the value of the textbox entered by any user.
suppose if any value is entered by keyboard I need to reset to zero.
Here is what I got so far
function AddTrackingItem()
{
var counter;
$("#Item_Count").keyup(function (event) {
if(event.which == 13)
counter = 0; // if value is enter from keyboard then reset value
else
{
counter = $("#Item_Count").val();
}
});
TIA
I am assuming the html looks something like this:
<input type="text" id="item_count" value="0" />
<input type="button" id="btn" value="Increment"/>
You'll need an event handler for clicks on the button (obviously), and an event handler for the change event on the input field. The click on the button will not trigger the change event, but changing the input field manually will. Therefore we can safely reset the counter to 0 if the user alters the field.
$('#btn').on( 'click', function() {
$('#item_count').val( function( i, oldval ) {
return (oldval*1) + 1;
} );
} );
$('#item_count').on( 'change', function() {
$('#item_count').val( '0' );
} );
Edit: There are only two ways of entering data. One is by keyboard. The other one is by the button. That means that if the change event isn't triggered by the button, 100% of the cases where the change event is triggered, it must be via the keyboard. You can alter the code a bit to include the .data(...) (docs) functionality of jQuery and do something like the following code. It will reset the input when it was altered, and subsequently the button was pressed.
$('#btn').on( 'click', function() {
$('#item_count').val( function( i, oldval ) {
if( $(this).data( 'fromKeyboard' ) == 1 ) {
$(this).data('fromKeyboard', 0 );
return 1;
}
return (oldval*1) + 1;
} );
} );
$('#item_count').on( 'change', function() {
$(this).data( 'fromKeyboard', 1 );
} );
Example on jsbin.
if you don't want user to manually enter value in the textbox, why not make it readonly?
Anyway, if you want to do what you insist to do. Here is how to do it.
$("#btn").click(function(){
var currentVal = $("#item_count").val();
var counter = parseInt(currentVal) + 1;
$("#item_count").val(counter);
});
$("#item_count").keyup(function (event) {
$("#item_count").val("0");
});
Notice that I don't have the listener for enter key event (13) because I change the value to 0 upon keyup. If you want to have the value change to 0 on enter key you can do what you have in your code. Remember to convert the string to int so you can add/increment the value. When you do a .val() it returns a string not int. Hope this helps. Let me know if you have any questions.
Hi could someone help me figure out how to stop a function running until a specific number of characters are pressed?
currently using the following function:
$('input#q').keyup
this works as soon as you press any key...
Something like this should start firing code after 3 letters have been added:
Live Example
JavaScript
$('input#q').keyup( function() {
if( this.value.length < 4 ) return;
/* code to run below */
$('#output').val(this.value);
});
HTML
<input id="q" />
<br /><br />
<input id="output"/>
you could do :
$('input#q').keyup(function(){
if($(this).val().length > 3)
{
//do something
}
});
You could store the characters in a string variable each time a key is pressed and then run a conditional statement to check the length of the variable. If it's equal to three, run whatever function
Well you'll probably need to take into account the way focus changes. Do you want to clear the counter when the field is newly focused or not? You should also decide whether you're counting characters actually added to the field, or instead if you want to could actual discrete key presses - a "shift" key press, for example, won't add any characters, but it's a key being pressed.
Anyway it'd probably be something like this:
$(function() {
var keyCount = 0;
$('#q').keyup(function() { // "keypress" to count characters
if (++keyCount === 3) {
// do the thing
}
})
.focus(function() {
keyCount = 0; // if this is what you want
});
});
If you're counting the "keypress" event instead of "keyup", you might want to count the actual length of the text field value rather than trying to count events.
How's about:
var c = 0;
('input#q').keyup( function() {
c++;
if (c >= 3) {
startGame();
}
} );