fire .change with keyup and keydown - javascript

I have the following which works as long as I use the mouse to select an option from the selectbox, or use keyboard arrow keys to select the option, but when using the keyboard, the change event does not fire until I press enter on the keyboard.
How would I detect a change using the keyboard arrow keys without having to press enter?
$('#select_box').change(function() {
some_function($(this).val());
});

You'll probably want to avoid calling your function multiple times unnecessarily, which will happen if you are not careful with multiple events. You can avoid this by checking if the value of the field has actually changed before calling it. One way of doing this, shown below, is to store a property on the field with the previous value and then using that to check if the field's value has changed before calling your function:
var previousValuePropertyKey = 'previousValue';
$('#select_box').bind('keyup change', function(event) {
var previousValue = $(this).prop(previousValuePropertyKey);
var currentValue = $(this).val();
$(this).prop(previousValuePropertyKey, currentValue );
if(previousValue != currentValue ){
alert(currentValue);//TODO remove alert
//Yourfunction(..);
}
});
Here's a fiddle for an example.

TRY
$('#select_box').bind('keyup change',function() {
some_function($(this).val());
});
Reference

$('#select_box').change(function() {
alert($(this).val());
});
$('#select_box').keyup(function() {
alert($(this).val());
});

Related

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 focus without entering key event shortcut

Using keymaster library for defining and dispatching keyboard shortcuts, I defined shortcut key / to focus input element.
key('/', function() {
$(".topbar input").focus();
});
The issue is that when the / key is pressed, the input is focused with / entered value. I want to get rid of that.
Try this.
key('/', function(event) {
$(".topbar input").focus();
event.preventDefault();
});
It gets focused because you tell it to do so.
Remove this line:
$(".topbar input").focus();
Or give it a function so that you can do stuff when it gets focused
$(".topbar input").focus(function(){
});

jQuery bind to keyup only, not focus

This seems like a simple thing but google hasn't turned up anything for me:
How can I bind to a text / value change event only, excluding an input gaining focus? Ie, given the following:
$(function(){
$('input#target').on('keyup', function(){
alert('Typed something in the input.');
});
});
...the alert would be triggered when the user tabs in and out of an element, whether they actually input text or not. How can you allow a user to keyboard navigate through the form without triggering the event unless they input/change the text in the text field?
Note: I'm showing a simplified version of a script, the reason for not using the change event is that in my real code I have a delay timer so that the event happens after the user stops typing for a second, without them having to change focus to trigger the event.
Store the value, and on any key event check if it's changed, like so:
$(function(){
$('input#target').on('keyup', function(){
if ($(this).data('val')!=this.value) {
alert('Typed something in the input.');
}
$(this).data('val', this.value);
});
});​
FIDDLE
Simply use the .change event.
Update: If you want live change notifications then do you have to go through the keyup event, which means that you need to program your handler to ignore those keys that will not result in the value being modified.
You can implement this with a whitelist of key codes that are ignored, but it could get ugly: pressing Del results in the value being changed, unless the cursor is positioned at the end of the input in which case it does not, unless there happens to be a selected range in the input in which case it does.
Another way which I personally find more sane if not as "pure" is to program your handler to remember the old value of the element and only react if it has changed.
$(function() {
// for each input element we are interested in
$("input").each(function () {
// set a property on the element to remember the old value,
// which is initially unknown
this.oldValue = null;
}).focus(function() {
// this condition is true just once, at the time we
// initialize oldValue to start tracking changes
if (this.oldValue === null) {
this.oldValue = this.value;
}
}).keyup(function() {
// if no change, nothing to do
if (this.oldValue == this.value) {
return;
}
// update the cached old value and do your stuff
this.oldValue = this.value;
alert("value changed on " + this.className);
});
});​
If you do not want to set properties directly on the DOM element (really, there's nothing wrong with it) then you could substitute $(this).data("oldValue") for this.oldValue whenever it appears. This will technically have the drawback of making the code slower, but I don't believe anyone will notice.
See it in action.
This will do it, set a custom attribute and check against that:
$('input').focus(function(){
$(this).attr('originalvalue',$(this).val());
});
$('input').on('keyup',function(){
if($(this).val()===$(this).attr('originalvalue')) return;
alert('he must\'ve typed something.');
});
Be wary of events firing multiple times.
Here is another version that plainly tests if the input field is empty.
If the input is empty then the action is not performed.
$(function(){
$(selector).on('keyup', function(){
if ($(this).val()!='') {
alert('char was entered');
}
})
});

Any event triggered on autocomplete?

I have a pretty simple form. When the user types in an input field, I want to update what they've typed somewhere else on the page. This all works fine. I've bound the update to the keyup, change and click events.
The only problem is if you select an input from the browser's autocomplete box, it does not update. Is there any event that triggers when you select from autocomplete (it's apparently neither change nor click). Note that if you select from the autocomplete box and the blur the input field, the update will be triggered. I would like for it to be triggered as soon as the autocomplete .
See: http://jsfiddle.net/pYKKp/ (hopefully you have filled out a lot of forms in the past with an input named "email").
HTML:
<input name="email" />
<div id="whatever"><whatever></div>
CSS:
div {
float: right;
}
Script:
$("input").on('keyup change click', function () {
var v = $(this).val();
if (v) {
$("#whatever").text(v);
}
else {
$("#whatever").text('<whatever>');
}
});
I recommending using monitorEvents. It's a function provide by the javascript console in both web inspector and firebug that prints out all events that are generated by an element. Here's an example of how you'd use it:
monitorEvents($("input")[0]);
In your case, both Firefox and Opera generate an input event when the user selects an item from the autocomplete drop down. In IE7-8 a change event is produced after the user changes focus. The latest Chrome does generate a similar event.
A detailed browser compatibility chart can be found here:
https://developer.mozilla.org/en-US/docs/Web/Events/input
Here is an awesome solution.
$('html').bind('input', function() {
alert('test');
});
I tested with Chrome and Firefox and it will also work for other browsers.
I have tried a lot of events with many elements but only this is triggered when you select from autocomplete.
Hope it will save some one's time.
Add "blur". works in all browsers!
$("input").on('blur keyup change click', function () {
As Xavi explained, there's no a solution 100% cross-browser for that, so I created a trick on my own for that (5 steps to go on):
1. I need a couple of new arrays:
window.timeouts = new Array();
window.memo_values = new Array();
2. on focus on the input text I want to trigger (in your case "email", in my example "name") I set an Interval, for example using jQuery (not needed thought):
jQuery('#name').focus(function ()
{
var id = jQuery(this).attr('id');
window.timeouts[id] = setInterval('onChangeValue.call(document.getElementById("'+ id +'"), doSomething)', 500);
});
3. on blur I remove the interval: (always using jQuery not needed thought), and I verify if the value changed
jQuery('#name').blur(function ()
{
var id = jQuery(this).attr('id');
onChangeValue.call(document.getElementById(id), doSomething);
clearInterval(window.timeouts[id]);
delete window.timeouts[id];
});
4. Now, the main function which check changes is the following
function onChangeValue(callback)
{
if (window.memo_values[this.id] != this.value)
{
window.memo_values[this.id] = this.value;
if (callback instanceof Function)
{
callback.call(this);
}
else
{
eval( callback );
}
}
}
Important note: you can use "this" inside the above function, referring to your triggered input HTML element. An id must be specified in order to that function to work, and you can pass a function, or a function name or a string of command as a callback.
5. Finally you can do something when the input value is changed, even when a value is selected from a autocomplete dropdown list
function doSomething()
{
alert('got you! '+this.value);
}
Important note: again you use "this" inside the above function referring to the your triggered input HTML element.
WORKING FIDDLE!!!
I know it sounds complicated, but it isn't.
I prepared a working fiddle for you, the input to change is named "name" so if you ever entered your name in an online form you might have an autocomplete dropdown list of your browser to test.
Detecting autocomplete on form input with jQuery OR JAVASCRIPT
Using: Event input. To select (input or textarea) value suggestions
FOR EXAMPLE FOR JQUERY:
$(input).on('input', function() {
alert("Number selected ");
});
FOR EXAMPLE FOR JAVASCRIPT:
<input type="text" onInput="affiche(document.getElementById('something').text)" name="Somthing" />
This start ajax query ...
The only sure way is to use an interval.
Luca's answer is too complicated for me, so I created my own short version which hopefully will help someone (maybe even me from the future):
$input.on( 'focus', function(){
var intervalDuration = 1000, // ms
interval = setInterval( function(){
// do your tests here
// ..................
// when element loses focus, we stop checking:
if( ! $input.is( ':focus' ) ) clearInterval( interval );
}, intervalDuration );
} );
Tested on Chrome, Mozilla and even IE.
I've realised via monitorEvents that at least in Chrome the keyup event is fired before the autocomplete input event. On a normal keyboard input the sequence is keydown input keyup, so after the input.
What i did is then:
let myFun = ()=>{ ..do Something };
input.addEventListener('change', myFun );
//fallback in case change is not fired on autocomplete
let _k = null;
input.addEventListener( 'keydown', (e)=>_k=e.type );
input.addEventListener( 'keyup', (e)=>_k=e.type );
input.addEventListener( 'input', (e)=>{ if(_k === 'keyup') myFun();})
Needs to be checked with other browser, but that might be a way without intervals.
I don't think you need an event for this: this happens only once, and there is no good browser-wide support for this, as shown by #xavi 's answer.
Just add a function after loading the body that checks the fields once for any changes in the default value, or if it's just a matter of copying a certain value to another place, just copy it to make sure it is initialized properly.

Detect all changes to a <input type="text"> (immediately) using JQuery

There are many ways the value of a <input type="text"> can change, including:
keypresses
copy/paste
modified with JavaScript
auto-completed by browser or a toolbar
I want my JavaScript function to be called (with the current input value) any time it changes. And I want it to be called right away, not just when the input loses focus.
I'm looking for the cleanest and most robust way to do this across all browsers (using jQuery preferably).
This jQuery code uses .bind() to catch immediate changes to any element, and should work across all browsers:
$('.myElements').each(function() {
var elem = $(this);
// Save current value of element
elem.data('oldVal', elem.val());
// Look for changes in the value
elem.bind("propertychange change click keyup input paste", function(event){
// If value has changed...
if (elem.data('oldVal') != elem.val()) {
// Updated stored value
elem.data('oldVal', elem.val());
// Do action
....
}
});
});
However, note that .bind() was deprecated in jQuery version 3.0. Anyone using jQuery version 1.7 or newer should use .on() instead.
A real-time solution for jQuery >= 1.7 is on
$("#input-id").on("change keyup paste", function(){
dosomething();
})
if you also want to detect "click" event, just:
$("#input-id").on("change keyup paste click", function(){
dosomething();
})
if you're using jQuery <= 1.6, just use bind or live instead of on.
Unfortunately, I think setInterval wins the prize:
<input type=text id=input_id />
<script>
setInterval(function() { ObserveInputValue($('#input_id').val()); }, 100);
</script>
It's the cleanest solution, at only 1 line of code. It's also the most robust, since you don't have to worry about all the different events/ways an input can get a value.
The downsides of using 'setInterval' don't seem to apply in this case:
The 100ms latency? For many applications, 100ms is fast enough.
Added load on the browser? In general, adding lots of heavy-weight setIntervals on your page is bad. But in this particular case, the added page load is undetectable.
It doesn't scale to many inputs? Most pages don't have more than a handful of inputs, which you can sniff all in the same setInterval.
Binding to the input event seems to work fine in most sane browsers. IE9 supports it too, but the implementation is buggy (the event is not fired when deleting characters).
With jQuery version 1.7+ the on method is useful to bind to the event like this:
$(".inputElement").on("input", null, null, callbackFunction);
Unfortunately there is no event or set of events that matches your criteria. Keypresses and copy/paste can both be handled with the keyup event. Changes through JS are trickier. If you have control over the code that sets the textbox, your best bet is to modify it to either call your function directly or trigger a user event on the textbox:
// Compare the textbox's current and last value. Report a change to the console.
function watchTextbox() {
var txtInput = $('#txtInput');
var lastValue = txtInput.data('lastValue');
var currentValue = txtInput.val();
if (lastValue != currentValue) {
console.log('Value changed from ' + lastValue + ' to ' + currentValue);
txtInput.data('lastValue', currentValue);
}
}
// Record the initial value of the textbox.
$('#txtInput').data('lastValue', $('#txtInput').val());
// Bind to the keypress and user-defined set event.
$('#txtInput').bind('keypress set', null, watchTextbox);
// Example of JS code triggering the user event
$('#btnSetText').click(function (ev) {
$('#txtInput').val('abc def').trigger('set');
});
If you don't have control over that code, you could use setInterval() to 'watch' the textbox for changes:
// Check the textbox every 100 milliseconds. This seems to be pretty responsive.
setInterval(watchTextbox, 100);
This sort of active monitoring won't catch updates 'immediately', but it seems to be fast enough that there is no perceptible lag. As DrLouie pointed out in comments, this solution probably doesn't scale well if you need to watch lots of inputs. You can always adjust the 2nd parameter to setInterval() to check more or less frequently.
Here is a solution that doesn't make use of jQuery (Its really quite obsolete and not necessary these days)
Using the event "input" you can look for any kind of change:
Deleting, Backspacing, Pasting, Typing, anything that will change the inputs value.
The input event is directly related to the text input. ANY time the text is changed in ANY fashion, input is dispatched.
document.querySelector("#testInput").addEventListener("input", test);
function test(e) {
var a = document.getElementById('output');
a.innerText += "Detected an Update!\n";
}
<input id="testInput">
<br>
<a id="output"></a>
Here is a slightly different solution if you didn't fancy any of the other answers:
var field_selectors = ["#a", "#b"];
setInterval(function() {
$.each(field_selectors, function() {
var input = $(this);
var old = input.attr("data-old-value");
var current = input.val();
if (old !== current) {
if (typeof old != 'undefined') {
... your code ...
}
input.attr("data-old-value", current);
}
}
}, 500);
Consider that you cannot rely on click and keyup to capture context menu paste.
Add this code somewhere, this will do the trick.
var originalVal = $.fn.val;
$.fn.val = function(){
var result =originalVal.apply(this,arguments);
if(arguments.length>0)
$(this).change(); // OR with custom event $(this).trigger('value-changed');
return result;
};
Found this solution at val() doesn't trigger change() in jQuery
I have created a sample. May it will work for you.
var typingTimer;
var doneTypingInterval = 10;
var finaldoneTypingInterval = 500;
var oldData = $("p.content").html();
$('#tyingBox').keydown(function () {
clearTimeout(typingTimer);
if ($('#tyingBox').val) {
typingTimer = setTimeout(function () {
$("p.content").html('Typing...');
}, doneTypingInterval);
}
});
$('#tyingBox').keyup(function () {
clearTimeout(typingTimer);
typingTimer = setTimeout(function () {
$("p.content").html(oldData);
}, finaldoneTypingInterval);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<textarea id="tyingBox" tabindex="1" placeholder="Enter Message"></textarea>
<p class="content">Text will be replace here and after Stop typing it will get back</p>
http://jsfiddle.net/utbh575s/
We actually don't need to setup loops for detecting javaScript changes.
We already setting up many event listeners to the element we want to detect. just triggering any un harmful event will make the job.
$("input[name='test-element']").on("propertychange change click keyup input paste blur", function(){
console.log("yeh thats worked!");
});
$("input[name='test-element']").val("test").trigger("blur");
and ofc this is only available if you have the full control on javascript changes on your project.
Although this question was posted 10 years ago, I believe that it still needs some improvements. So here is my solution.
$(document).on('propertychange change click keyup input paste', 'selector', function (e) {
// Do something here
});
The only problem with this solution is, it won't trigger if the value changes from javascript like $('selector').val('some value'). You can fire any event to your selector when you change the value from javascript.
$(selector).val('some value');
// fire event
$(selector).trigger('change');
Or in a single line
$(selector).val('some value').trigger('change');
Well, best way is to cover those three bases you listed by yourself. A simple :onblur, :onkeyup, etc won't work for what you want, so just combine them.
KeyUp should cover the first two, and if Javascript is modifying the input box, well I sure hope it's your own javascript, so just add a callback in the function that modifies it.
Here's a working example that I'm using to implement an autocomplete variation the populates a jqueryui selector (list), but I don't want it to function exactly like the jqueryui autocomplete which does a drop-down menu.
$("#tagFilter").on("change keyup paste", function() {
var filterText = $("#tagFilter").val();
$("#tags").empty();
$.getJSON("http://localhost/cgi-bin/tags.php?term=" + filterText,
function(data) {
var i;
for (i = 0; i < data.length; i++) {
var tag = data[i].value;
$("#tags").append("<li class=\"tag\">" + tag + "</li>");
}
});
});
Can't you just use <span contenteditable="true" spellcheck="false"> element in place of <input type="text">?
<span> (with contenteditable="true" spellcheck="false" as attributes) distincts by <input> mainly because:
It's not styled like an <input>.
It doesn't have a value property, but the text is rendered as innerText and makes part of its inner body.
It's multiline whereas <input> isn't although you set the attribute multiline="true".
To accomplish the appearance you can, of course, style it in CSS, whereas writing the value as innerText you can get for it an event:
Here's a fiddle.
Unfortunately there's something that doesn't actually work in IE and Edge, which I'm unable to find.
you can simply identify all changers in the form, like this
//when form change, show aleart
$("#FormId").change(function () {
aleart('Done some change on form');
});
You can bind the 'input' event to <input type="text">. This will trigger every time the input changes such as copy, paste, keypress, and so on.
$("#input-id").on("input", function(){
// Your action
})

Categories