jQuery trigger keyup on input gets old value - javascript

I try to manually trigger key-up event in qunit test but it fails since manually trigger key-up event will not change the input value.
http://jsfiddle.net/Re9bj/4/
$('input').on('keyup', function (event) {
$('div').html($('input').val());
});
var e = $.Event('keyup', {
keycode: 68
});
$('input').trigger(e); //this trigger will not change the input value
This trigger will work but the problem is that input value never change.

You can't add a character with a simple trigger. Trigger will only fire events, but not the default behavior. You need to simulate it.
To do that, you can use this code :
if(event.isTrigger && event.keycode) this.value += String.fromCharCode(event.keycode);
It will check if the event is triggered and then print the value.
Final code :
$('input').on('keyup', function (event) {
if(event.isTrigger && event.keycode) this.value += String.fromCharCode(event.keycode);
$('div').html($('input').val());
});
var e = $.Event('keyup', {
keycode: 68
});
$('input').trigger(e);
Fiddle : http://jsfiddle.net/Re9bj/9/

Related

jQuery trigger press enter not working

This is my script:
$('.target input').val('my value');
$('.target input').trigger(jQuery.Event('keypress', { keycode: 13 }));
The first line worked and the value set correctly, then I need to press the enter in input element, but the second line not worked. I mean the event not fired:
$('.target input').keyup(function(e){
if(e.keyCode == 13)
{
alert($(this).val());
}
});
when I press the enter manually the event fires but with javascript the event not fired. where is the problem?
You need to trigger keyup event in order to fire keyup event handler. Although the property keycode should be changed to keyCode since object property is case sensitive Javascript.
$('.target input').trigger(jQuery.Event('keyup', { keyCode: 13 }));
$('.target input').keyup(function(e) {
if (e.keyCode == 13) {
alert($(this).val());
}
});
$('.target input').val('my value');
$('.target input').trigger(jQuery.Event('keyup', {
keyCode: 13
}));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="target">
<input/>
</div>
FYI : You need to bind event handler before the event triggering with the code, otherwise it won't listen to the event triggered before the listener is attached.
Although object properties passing on jQuery.Event supports 1.6 onwards, so check your jQuery version.
As of jQuery 1.6, you can also pass an object to jQuery.Event() and its properties will be set on the newly created Event object.
var e = jQuery.Event("keydown");
e.which = 13;
$(".target input").trigger(e);
This should do the work for you,
var e = jQuery.Event("keypress");
e.which = 13; //choose the one you want
e.keyCode = 13;
$("#theInputToTest").trigger(e);
FIDDLE
Basically you need to trigger keyup event as I did in the fiddle.
HTML
<input type=text />
JS
$(":input").keyup(function(e){
if(e.which==13){
alert("Fired");
}
});
$(":input").val("TEST");
$(":input").trigger($.Event("keyup",{which:13}));

Triggered keypress events not being captured?

I'm capturing input from a barcode scanner (which acts like keyboard input) and it works great, but I don't have access to a barcode scanner at the moment and need to test my code, so I need to simulate the barcode scanner (keyboard) input.
I thought triggering keypress events for each character would work, but it doesn't. Here's my test code:
var barcodeScannerTimer;
var barcodeString = '';
// capture barcode scanner input
$('body').on('keypress', function (e) {
barcodeString = barcodeString + String.fromCharCode(e.charCode);
clearTimeout(barcodeScannerTimer);
barcodeScannerTimer = setTimeout(function () {
processBarcode();
}, 300);
});
function processBarcode() {
console.log('inside processBarcode with barcodeString "' + barcodeString + '"');
if (!isNaN(barcodeString) && barcodeString != '') { // #todo this check is lame. improve.
alert('ready to process barcode: ' + barcodeString);
} else {
alert('barcode is invalid: ' + barcodeString);
}
barcodeString = ''; // reset
}
window.simulateBarcodeScan = function() {
// simulate a barcode being scanned
var barcode = '9781623411435';
for (var i = 0; i < barcode.length; i++) {
var e = jQuery.Event("keypress");
e.which = barcode[i].charCodeAt(0);
$("body").focus().trigger(e);
}
}
JSFIDDLE
If you type in a number quickly (like 1234), you'll see the input is captured fine. However, click the button to run my test code, and the input is not captured. The event is triggered because an alert box pops up, but barcodeString is empty!
Why isn't this working? Should I be triggering some event other than keypress?
The handler is reading the charCode but you are only setting which on the event. Set charCode, or read from which. https://jsfiddle.net/mendesjuan/bzfeuezv/1/
barcodeString = barcodeString + String.fromCharCode(e.which);
Firing Synthetic events
This is a reminder that firing synthetic events is tricky business and typically requires you to have intimate knowledge of the handlers (which is bad) so that you don't have to construct a full event object. Also, beware that not all events triggered by jQuery will actually trigger the native events and cause its default action to apply.
Simply put, triggering keypress does not actually type a character into a text field or fires event handlers not set with jQuery.
document.querySelector('input').addEventListener('keypress', function() {
console.log('standard input key press handler');
});
var e = jQuery.Event("keypress");
e.which = "a".charCodeAt(0);
$('input').keypress(function(){
console.log('jQuery input key press handler');
}).trigger('keypress', e);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input value="yo" />

Avoid multiple event listeners from .focus

I currently have a textbox that I am invoking a keyboard stroke on focus:
$myTextBox.on('focus', function(e){
$(document).keydown(function(e){
if(e.which==13)
e.preventDefault()
});
$(document).keyup(function(e){
if(e.which ==13)
alert("hey");
});
});
If I click on this multiple times pressing 'enter' once will cause many alerts, how can I avoid this so that only it is only invoked once.
You're adding the event listener every time the field gets focus.
Just add the keydown, keyup listener on the document ready function...
$(function() {
$("#myTextBox").keydown(function(e){
if(e.which==13)
e.preventDefault()
});
$("#myTextBox").keyup(function(e){
if(e.which ==13)
alert("hey");
});
});​
http://jsfiddle.net/ShHkP/
Like others have said, you don't have to keep adding the event on focus. As well, you should just attach the event to the textbox itself because that is in fact what you're trying to do when you add the event on focus.
$myTextBox.on({
'keydown': keyDown,
'keyup': keyUp
});​
So that your application doesn't go into an enter-alert-ok loop, you have to turn off the keyup listener before the alert() call, and then turn it back on after hitting ok.
Here's a fiddle.
I see what you're trying to do (or not?). You could just attach the event to the form and exclude the textarea instead of adding it to the document everytime the input gets focused.
$('form').on('keydown', function( e ) {
// Prevent submit when pressing enter but exclude textareas
if ( e.which == 13 && e.target.nodeName != 'TEXTAREA' ) {
e.preventDefault();
}
}
var alreadyPressed = false;
$("textarea").keypress(function (e) {
if (e.which == 13) {
e.preventDefault();
alreadyPressed = true
}
});
$("textarea").keyup(function (e) {
if (e.which == 13 && !alreadyPressed) {
alert("hey");
alreadyPressed = false;
}
});
http://jsfiddle.net/DerekL/Dr6t2/

onchange event not fire when the change come from another function

I have an input text that get his value from a Javascript function (a timer with countdown).
I want to raise an event when the input text is 0 ,so I am using the change eventListener.
Unfortunately it doesn't seem to raise the event when the change is coming from javascript function.
How can I force the change event to work, even if the change is coming from Javascript and not from the user?
From the fine manual:
change
The change event occurs when a control loses the input focus and its value has been modified since gaining focus. This event is valid for INPUT, SELECT, and TEXTAREA. element.
When you modify the text input's value through code, the change event will not be fired because there is no focus change. You can trigger the event yourself though with createEvent and dispatchEvent, for example:
el = document.getElementById('x');
ev = document.createEvent('Event');
ev.initEvent('change', true, false);
el.dispatchEvent(ev);
And a live version: http://jsfiddle.net/ambiguous/nH8CH/
In the function that changes the value, manually fire a change event.
var e = document.createEvent('HTMLEvents');
e.initEvent('change', false, false);
some_input_element.dispatchEvent(e);
it's 2018 now and seems that initEvent() is deprecated:
https://developer.mozilla.org/en-US/docs/Web/API/Event/initEvent
i think you can trigger the event in a one-liner now:
element.dispatchEvent(new Event('change'));
A more reusable option :
function simulate_event(eventName, element) {
// You could set this into the prototype as a method.
var event;
if (document.createEvent) {
event = document.createEvent("HTMLEvents");
event.initEvent(eventName, true, true);
} else {
event = document.createEventObject();
event.eventType = eventName;
};
event.eventName = eventName;
if (document.createEvent) {
element.dispatchEvent(event);
} else {
element.fireEvent("on" + event.eventName, event);
}
};
Simply redefine the "value" property of the node, using getAttribute("value") and setAttribute("value", newValue), in the getters and setters, as well as dispatch the "change" event at the end of the setter. For example:
myNode.onchange = e => console.log("Changed!", e.target.value);
Object.defineProperty(myNode, "value", {
get: () => myNode.getAttribute("value"),
set(newValue) {
myNode.setAttribute("value", newValue);
myNode.dispatchEvent(new Event("change")); //or define the event earlier, not sure how much of a performance difference it makes though
}
})
var i = 0;
setTimeout(function changeIt() {
if(i++ < 10) {
myNode.value = i;
setTimeout(changeIt, 1000);
}
}, 1)
<input id="myNode">
Instead of using change, you can use keypress event instead.
This is because the change event is not meant to fire until it is not focused anymore - when you click out of the input tag.

Trigger a keypress/keydown/keyup event in JS/jQuery?

What is the best way to simulate a user entering text in a text input box in JS and/or jQuery?
I don't want to actually put text in the input box, I just want to trigger all the event handlers that would normally get triggered by a user typing info into a input box. This means focus, keydown, keypress, keyup, and blur. I think.
So how would one accomplish this?
You can trigger any of the events with a direct call to them, like this:
$(function() {
$('item').keydown();
$('item').keypress();
$('item').keyup();
$('item').blur();
});
Does that do what you're trying to do?
You should probably also trigger .focus() and potentially .change()
If you want to trigger the key-events with specific keys, you can do so like this:
$(function() {
var e = $.Event('keypress');
e.which = 65; // Character 'A'
$('item').trigger(e);
});
There is some interesting discussion of the keypress events here: jQuery Event Keypress: Which key was pressed?, specifically regarding cross-browser compatability with the .which property.
You could dispatching events like
el.dispatchEvent(new Event('focus'));
el.dispatchEvent(new KeyboardEvent('keypress',{'key':'a'}));
To trigger an enter keypress, I had to modify #ebynum response, specifically, using the keyCode property.
e = $.Event('keyup');
e.keyCode= 13; // enter
$('input').trigger(e);
Here's a vanilla js example to trigger any event:
function triggerEvent(el, type){
if ('createEvent' in document) {
// modern browsers, IE9+
var e = document.createEvent('HTMLEvents');
e.initEvent(type, false, true);
el.dispatchEvent(e);
} else {
// IE 8
var e = document.createEventObject();
e.eventType = type;
el.fireEvent('on'+e.eventType, e);
}
}
You can achieve this with: EventTarget.dispatchEvent(event) and by passing in a new KeyboardEvent as the event.
For example: element.dispatchEvent(new KeyboardEvent('keypress', {'key': 'a'}))
Working example:
// get the element in question
const input = document.getElementsByTagName("input")[0];
// focus on the input element
input.focus();
// add event listeners to the input element
input.addEventListener('keypress', (event) => {
console.log("You have pressed key: ", event.key);
});
input.addEventListener('keydown', (event) => {
console.log(`key: ${event.key} has been pressed down`);
});
input.addEventListener('keyup', (event) => {
console.log(`key: ${event.key} has been released`);
});
// dispatch keyboard events
input.dispatchEvent(new KeyboardEvent('keypress', {'key':'h'}));
input.dispatchEvent(new KeyboardEvent('keydown', {'key':'e'}));
input.dispatchEvent(new KeyboardEvent('keyup', {'key':'y'}));
<input type="text" placeholder="foo" />
MDN dispatchEvent
MDN KeyboardEvent
You're now able to do:
var e = $.Event("keydown", {keyCode: 64});
First of all, I need to say that sample from Sionnach733 worked flawlessly. Some users complain about absent of actual examples. Here is my two cents. I've been working on mouse click simulation when using this site: https://www.youtube.com/tv. You can open any video and try run this code. It performs switch to next video.
function triggerEvent(el, type, keyCode) {
if ('createEvent' in document) {
// modern browsers, IE9+
var e = document.createEvent('HTMLEvents');
e.keyCode = keyCode;
e.initEvent(type, false, true);
el.dispatchEvent(e);
} else {
// IE 8
var e = document.createEventObject();
e.keyCode = keyCode;
e.eventType = type;
el.fireEvent('on'+e.eventType, e);
}
}
var nextButton = document.getElementsByClassName('icon-player-next')[0];
triggerEvent(nextButton, 'keyup', 13); // simulate mouse/enter key press
For typescript cast to KeyboardEventInit and provide the correct keyCode integer
const event = new KeyboardEvent("keydown", {
keyCode: 38,
} as KeyboardEventInit);
I thought I would draw your attention that in the specific context where a listener was defined within a jQuery plugin, then the only thing that successfully simulated the keypress event for me, eventually caught by that listener, was to use setTimeout().
e.g.
setTimeout(function() { $("#txtName").keypress() } , 1000);
Any use of $("#txtName").keypress() was ignored, although placed at the end of the .ready() function. No particular DOM supplement was being created asynchronously anyway.

Categories