keypress handler canceling the event - javascript

I have the following code
jQuery('#parent').on('keypress', '.textbox', function(e) {
var btn = jQuery(this).closest('tr').find('.btn');
if (btn.length) {
btn.triggerHandler('click');
}
});
This code is a delegated keypress handler which is listening to the event of textboxes having class value ".textbox".
The handler finds the button with class ".btn" & calls its click handler which has an ajax call in it.
Problem is this seems to prevent the event from completing i.e if the value in box is "2" & I type in a "3",the handler executes but the value in the box remains to be "2" instead of a "23".
It works normal when I comment out the btn triggerHandler statement.
Ideas why this is happening?

Use keyup instead of keypress. As in your script you have triggered another event.
jQuery('#parent').on('keyup', '.textbox', function(e) {
var btn = jQuery(this).closest('tr').find('.btn');
if (btn.length) {
btn.triggerHandler('click');
}
});
keypress gets interrupted by triggerHandler and hence doesn't allow the default action of key press to occur. While keyup will perform default action first, then listen to handler.

I think you need to keyup function.
$(document).ready(function(){
$("input").keyup(function(){
var rs= $(this).val();
alert(rs);
$("input").css("background-color", "pink");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
Enter your value: <input type="text">

Try to use 'onchange' insted of 'keypress' or 'keyup'
$(document).ready(function(){
$("input").onchange(function(){
var rs= $(this).val();
alert(rs);
$("input").css("background-color", "pink");
});
});

Related

eventListener firing multiple times and increasing

On a click function I have the option of playing audio.
The click is only fired once (after I added .off(), which I seem to have to do for every click event because I think there's something I fundamentally don't get about how javascript works) but the function added to the "ended" listener shows it is firing the number of times the button has been clicked. I presume .play() is also being fired multiple times.
These need to be inside the click event to get the id so how do I stop these kinds of things from happening, here and elsewhere when using js? Adding event.stopPropagation(), event.bubbles = false and .off() everywhere seems unnecessary (and in this case doesn't make a difference anyway).
$('.button').off().on('click', function(event){
event.stopPropagation();
event.bubbles = false;
var id = $(this).attr('id')
if ($(this).hasClass('hasAudio')) {
document.getElementById('audio_'+id).play();
document.getElementById('audio_'+id).addEventListener("ended", function(){
console.log("ended");
});
}
});
Move the ended event outside the click event,you are registering the event each time you click on the button
$('.button').on('click', function(event){
var id = $(this).attr('id')
if ($(this).hasClass('hasAudio')) {
document.getElementById('audio_'+id).play();
}
});
$('[id^="audio_"]').on("ended", function(){
console.log("ended");
});
Each time you click on the button a new event listener will be added to the ended event. To prevent that you can try defining the callback function before hand. That will prevent your event listener to be added in the event loop over and over.
An anonymous function has no signature, hence when you define the event with it, it will think that this is supposed to be a new event listener and invokes it multiple times. Check the working snippets to see the difference. Type something in the input box to see what is happening.
If this is confusing then removeEventListener can be the next option.
function ended(event){
console.log("ended");
}
$('.button').off().on('click', function(event){
event.stopPropagation();
event.bubbles = false;
var id = $(this).attr('id')
if ($(this).hasClass('hasAudio')) {
document.getElementById('audio_'+id).play();
document.getElementById('audio_'+id).addEventListener("ended", ended);
}
});
var input = document.getElementById('some');
function callback(event) {
console.log("PRINT");
}
input.addEventListener("keyup", callback)
// input.removeEventListener("keyup", callback)
input.addEventListener("keyup", callback)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="some" value="" >
Anonymous function as callback
var input = document.getElementById('some');
input.addEventListener("keyup", function(event) {
console.log("PRINT");
})
// input.removeEventListener("keyup", callback)
input.addEventListener("keyup", function(event) {
console.log("PRINT");
})
<input id="some" value="">
This fails because, every time you click the function, you add a new event listener to the button.
document.getElementById('audio_'+id).addEventListener("ended", function(){
console.log("ended");
This is repeatedly adding the event listener to the button.If you need this inside the click event, check to see whether it exists already. If it does, don't add it again.
Use global flag which defines if you want to pause or play. and also use preventDefault (in case of any inline click event used).
You have to remove the registered event listener after your task is completed.
document.getElementById('audio_'+id).removeEventListener("ended", function(){
console.log("ended");
});
Or what you can do is that move the logic for registering event listener outside the click event listener. Like this the event will be registered only once.
document.getElementById('audio_'+id).addEventListener("ended", function(){
console.log("ended");
});
}
$('.button').off().on('click', function(event){
event.stopPropagation();
event.bubbles = false;
var id = $(this).attr('id')
if ($(this).hasClass('hasAudio')) {
document.getElementById('audio_'+id).play();
});

Lost "click" event during AJAX refresh

$(":input").on("change", function(e) {
console.log("change triggered");
$("#section").html("<button id='order'>Order</button>");
registerButtons();
});
function registerButtons() {
$("#order").on("click", function(e) {
console.log("click triggered");
alert("Hello World");
});
$("#order").on("mousedown mouseup", function(e) {
console.log(e.type + " triggered");
});
}
registerButtons();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" value="123"/>
<div id="section">
<button id="order">Order</button>
</div>
I have a web page with a button and some input fields.
On the button an click event is registered
On the input fields an change event is registered
The onChange will trigger an AJAX server call, and the result will replace parts of the web page - including the button. After AJAX result is processed, all listener are registered again.
Now the problem. A user changes the value of an input field, and clicks directly the button - but to slow (lets assume the user needs 500ms for the click), so the onChange event is fired and the page is "updated/replaced". Now the "old" button fires an onMouseDown and the "new" button fires an onMouseUp event - but no onClick.
My current workaround is, to register the two mouseDown/mouseUp events, get the timestamp of the mouse down, and if the mouse up comes in 2 seconds, do what should be done by the onClick.
It is no option to remove the button part from the AJAX response - in worst case the button could be removed and replaced by an user info.
My hope is, that there is a better solution... any ideas?
You can take advantage of the event delegation and set your listener on the container instead of the button.
You are adding a click listener to your old button and your adding a new button to the dom. So the click won't work.
The button wasn't working because for some reason it can't focus when you hover over it. So I added a getFocus method and now it should work.
$("input").on("change", function(e) {
console.log("change triggered");
$("#section").html("<button id='order'>Order</button>");
});
function registerButtons() {
$('#section').on("mouseup", '#order', function(e) {
alert('Clicked!');
});
}
registerButtons();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" value="123"/>
<div id="section">
<button id="order">Order</button>
</div>
I just found out that jQuery provides a sweet API that can be used for event delegation. This way we don't have to manually check for event target. Check it out http://api.jquery.com/on/
$("input").on("change", function(e) {
console.log("change triggered");
$("#section").html("<button id='order'>Order</button>");
});
function registerButtons() {
$("#section").on("click", '#order', function(e) {
console.log("click triggered");
alert("Hello World");
});
$("#section").on('mouseover','#order', function(e){
$(this).focus();
});
}
registerButtons();

On keypress does not fire on the first key press

I have this method:
$(".txtB").on("keypress", function(event) {
console.log($(this).val());
if (...)
event.preventDefault();
});
But it works only after the second key pressed not for the first one. After that is triggered on every key press.
Anyone have an idea what could be?
Thanks.
Later edit:
It might be related to the way i use the function?
in HTML: onkeyup = "caseValuePercentageTwoDecimalRestriction()"
in JS:
function caseValuePercentageTwoDecimalRestriction() {
$(".caseValuePrecentageRestriction").on("keypress", function (event) {
...
??
The error is calling caseValuePercentageTwoDecimalRestriction on keyup event which is fired after keypress event.
keyup is called when you release the key while keypress is called when you press the key.
You should bind you keypress event handler on a document.ready event like this:
$(document).ready(function() {
$(".caseValuePrecentageRestriction").on("keypress", function (event) {
// do whatever you need
});
});
$(".txtB").keyup(function (event) {
console.log($(this).val());
});
To answer your question, Keypress event happens before the input change. But Keyup happens after the change. That's the only difference.
For input fields there is one more property input propertychange which works on change of text by keyboard as well as of you copy from mouse. Try using it
$(".txtB").on("input propertychange", function(event) {
console.log($(this).val());
if (...)
event.preventDefault();
});
use keyup instead of key press - Try:
$(".txtB").keyup(function (event) {
console.log($(this).val());
});
Then maybe .keydown would work for you?
Here we go:
Your code have to be like this:
$("input").keypress(function(){
$("span").text(i += 1);
alert("Test key pres");
});
<input type="text">
<p>Keypresses: <span>0</span></p>
Hope it helps;)
This will work for you but this is not perfect solution, it is just a work around:
$(document).ready(function(){
$(".txtB").on("keypress", function (event) {
console.log($(this).val() + event.key);
});
});
Here is a jsbin
As other users has shared Keypress event triggers before the value of textbox changed. You should use other events if you want updated value of textbox.
keypress events are fired before the new character is added to the input.
So the first keypress event is fired before the first character is added, while the input is still empty.
If you check this JSFIDDLE you will see an alert box even before you see value in input.
For example if you type a initially you will see an empty alert box, then type a different character, at that point you will see it is alerting a
You need to use either keyup or keydown. You can aslo use event.preventDefault() with keyup & keydown
try to use change instead of keypress or keyup because it will call first :
$(".txtB").change(function(event){
console.log($(this).val());
});

jQuery .on() running before value given

Why does .on() not get the value of the form input field (#forgot) before the keypress has happened.
$(document).ready(function() {
$(document).on('keypress', '#pass', function() {
var value = $.trim($('#pass').val());
alert(value);
if (!value.length) {
alert("Show");
$('#forgot').show();
} else {
alert("Hide");
$('#forgot').hide();
}
});
});
When I type in the first character the alert shows no input. The second character leads to the value being only the first character. The .on() function seems to run before the key press is registered? How can I fix this or is there an alternative function?
keypress event triggered when you press a key. It will not wait for the value to come. Try with keyup. keyup gets triggered when you a key is released after pressing, till that time the value is proccessed. -
$(document).on('keyup', '#pass', function() {
keypress
The keypress event is sent to an element when the browser registers keyboard input. This is similar to the keydown event, except that modifier and non-printing keys such as Shift, Esc, and delete trigger keydown events but not keypress events. Other differences between the two events may arise depending on platform and browser.
keyup
The keyup event is sent to an element when the user releases a key on the keyboard. It can be attached to any element, but the event is only sent to the element that has the focus. Focusable elements can vary between browsers, but form elements can always get focus so are reasonable candidates for this event type.
Simply change keypress to keyup:
$(document).ready(function() {
$(document).on('keyup', '#pass', function() {
var value = $.trim($('#pass').val());
console.log(value);
if (!value.length) {
console.log("Show");
$('#forgot').show();
} else {
console.log("Hide");
$('#forgot').hide();
}
});
});
You need the keyup event instead of the keypress.
So replace:
$(document).on('keypress', '#pass', function() {
With
$(document).on('keyup', '#pass', function() {
keypress event is triggered when the key is pressed before the key is up). So it won't get the complete value.
Use keyup
JSFIDDLE DEMO
HTML
<input id="pass">
JQUERY
$(document).ready(function() {
$(document).on('keyup', '#pass', function() {
var value = $.trim($('#pass').val());
alert(value);
if (!value.length) {
alert("Show");
$('#forgot').show();
} else {
alert("Hide");
$('#forgot').hide();
}
});
});

Change event precedence with JQuery

I have the following html code:
<input type="text" id="theInput" value=""/>
Click me
I want to detect when the input changes and perform an operation in this case, but ONLY when the user has not clicked in the link. I have tried this:
$('#theLink').live('click', function(){
alert('click');
});
$('#theInput').live('change', function(){
alert('change');
});
However change is always executed before click when the value in the input changed, due to Javascript event precedence rules, and therefore only "change" message is displayed.
I would like it to display change only if the input value changed and the user exited the input clicking in any other place instead of the link. In that last case I would like to display click.
The example is here.
I use jQuery 1.6.4.
As far as I know, the click event fires after the blur and change events in every browser (have a look at this JSFiddle). The order of blur and change is different across browsers (source: Nicholas Zakas).
To solve your problem, you could listen to click events on the document and compare the event's target with #theLink. Any click event will bubble up to the document (unless it is prevented).
Try this:
var lastValue = '';
$(document).click(function(event) {
var newValue = $('#theInput').val();
if ($(event.target).is('#theLink')) {
// The link was clicked
} else if (newValue !== lastValue) {
// Something else was clicked & input has changed
} else {
// Something else was clicked but input didn't change
}
lastValue = newValue;
});
JSFiddle: http://jsfiddle.net/PPvG/TTwEG/
Both events will fire but in your example the alert in the onchange event handler fired when the onmousedown event occurs will stop the onmouseup event required for the onclick event to fire. Using console.log will show both events firing.
http://jsfiddle.net/hTqNr/4/
Ok, now i got it, you could do
$('#theLink').live('click', function(e){
alert('click');
});
$('#theInput').live('change', function(e){
//Check if the change events is triggerede by the link
if(e.originalEvent.explicitOriginalTarget.data === "Click me"){
//if this is the case trigger the click event of the link
$('#theLink').trigger("click");
}else{
//otherwise do what you would do in the change handler
alert('change');
}
});
Fiddle here http://jsfiddle.net/hTqNr/19/
why you dont pick the value of input box. you have to store initial value of input box on ready function
initialvalue= $('#theInput').val();
then compare the value
$('#theLink').live('click', function(){
var newvalue =$('#theInput').val();
if(newvalue!=initialvalue) {
//do something
}
});

Categories