I've got a simple Listbox on a HTML form and this very basic jQuery code
//Toggle visibility of selected item
$("#selCategory").change(function() {
$(".prashQs").addClass("hide");
var cat = $("#selCategory :selected").attr("id");
cat = cat.substr(1);
$("#d" + cat).removeClass("hide");
});
The change event fires fine when the current item is selected using the Mouse, but when I scroll through the items using the keyboard the event is not fired and my code never executes.
Is there a reason for this behavior? And what's the workaround?
The onchange event isn't generally fired until the element loses focus. You'll also want to use onkeypress. Maybe something like:
var changeHandler = function() {
$(".prashQs").addClass("hide");
var cat = $("#selCategory :selected").attr("id");
cat = cat.substr(1);
$("#d" + cat).removeClass("hide");
}
$("#selCategory").change(changeHandler).keypress(changeHandler);
You'll want both onchange and onkeypress to account for both mouse and keyboard interaction respectively.
Sometimes the change behavior can differ per browser, as a workaround you could do something like this:
//Toggle visibility of selected item
$("#selCategory").change(function() {
$(".prashQs").addClass("hide");
var cat = $("#selCategory :selected").attr("id");
cat = cat.substr(1);
$("#d" + cat).removeClass("hide");
}).keypress(function() { $(this).change(); });
You can chain whatever events you want and manually fire the change event.
IE:
var changeMethod = function() { $(this).change(); };
....keypress(changeMethod).click(changeMethod).xxx(changeMethod);
The behavior you describe, the change event triggering by keyboard scrolling in a select element, is actually an Internet Explorer bug. The DOM Level 2 Event specification defines the change event as this:
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.
If you really want this behavior, I think you should look at keyboard events.
$("#selCategory").keypress(function (e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 38 || keyCode == 40) { // if up or down key is pressed
$(this).change(); // trigger the change event
}
});
Check a example here...
I had this problem with IE under JQuery 1.4.1 - change events on combo boxes were not firing if the keyboard was used to make the change.
Seems to have been fixed in JQuery 1.4.2.
$('#item').live('change keypress', function() { /* code */ });
Related
I want to fire an event in a textarea immediately after paste some text inside the textarea. I can do that when Shift+Ins is used; however, I cannot do it when right mouse button and then paste (from the drop down menu) is chosen. Keyup fires after Shift+Ins. None of the rest fires when Paste is chosen after right mouse button clicking... What do I have to do?
<textarea name="message" id="message"></textarea>
$("#message").on('keyup contextmenu', function(event) {
alert("ok");
});
http://jsfiddle.net/f29vuwoL/7/
Thank you
Most browsers support the input event, which is fired when something is pasted or otherwise added, regardless of how:
$("#message").on('keyup contextmenu input', function(event) {
alert("ok");
});
Updated Fiddle
Note that using input is the most general method, firing when the control gets input regardless of how, and so if you hook multiple events (as above), you'll get multiple calls for the same input. For instance, if you hook both keyup and input, on browsers that support input, you'll get two calls. Similarly for paste and input when the user pastes, on browsers that support both.
If you need to support browsers that don't have either input or paste, I'm afraid the unfortunate answer is that you need to poll. Still, polling every (say) 250ms isn't asking the browser to do that much work, and you can feature-detect whether it's necessary:
var message = $("#message");
var events = null;
var previous;
if ('oninput' in message[0]) {
// Browser supports input event
events = "input";
} else if ('onpaste' in message[0]) {
// Browser supports paste event
events = "paste keyup contextmenu";
}
if (!events) {
// Ugh, poll and fire our own
events = "pseudoinput";
previous = message.val();
setInterval(function() {
var current = message.val();
if (current != previous) {
previous = current;
message.trigger(events);
}
}, 250);
}
console.log("Using: " + events);
message.on(events, function(e) {
console.log("Got event: " + e.type);
});
Updated Fiddle
You should use input event callback. See the demo here
You can use the dedicated paste event:
$("#message").on('paste', function(event) {
alert("ok");
});
Updated jsFiddle
However you might want to check browser support - I don't think jQuery normalizes this event.
If you need IE support, it might be a little more difficult, but it depends on your requirements - does it absolutely need to be a paste action? If not, TJ Crowder's answer is the way to go.
The on input is useful if you want to detect when the contents of a textarea, input:text, input:password or input:search element have changed, because the onchange event on these elements fires when the element loses focus, not immediately after the modification.The oninput event is supported in Internet Explorer from version 9.
$("#message").on('input propertychange', function() {
console.log($(this).val());
});
Fiddle
I have a clearable input like this:
+-----------------+
| x |
+-----------------+
The clear icon is a span with a font glyph in the :before:
<wrapper>
<input>
<icon span>
</wrapper>
Validation of inputs is done on blur (which re-renders the input View for validation message and icon changes - this keeps the architecture simple). The issue I am experiencing is that by clicking the icon the input triggers a blur and then the icon click.
Can you think of a way to either:
a) Avoid triggering a blur -- I can only think of ditching font glyph and using a background image, but I am already using other glyphs for required, invalid etc in that position so it is undesired
b) Detecting that the blur was caused by the icon and not something else
Thanks.
Edit: Here is one idea, a bit lame using a setTimeout though: http://jsfiddle.net/ferahl/td5VR/
Consider using mousedown and mouseup events to set/remove a flag.
http://jsfiddle.net/td5VR/4/
var wasClicked = false;
$('input').blur(function(){
$(".results").text(wasClicked ? "was clicked": "wasn't clicked");
});
$('.something').mousedown(function(){
wasClicked = true;
}).mouseup(function() {
wasClicked = false;
});
Though you still need to disable keyboard navigation to the link by setting tabindex="-1".
Here's a few ideas of what might be happening and some approaches to try:
This is a guess, but perhaps what you're experiencing is something called event bubbling. Take a look at this page to learn more about it. You can prevent event bubbling in your click handler like this:
IconElement.onclick = function(event) {
event = event || window.event // cross-browser event
if (event.stopPropagation) {
// W3C standard variant
event.stopPropagation()
} else {
// IE variant
event.cancelBubble = true
}
}
(If you're using jQuery, you don't need to worry about the "IE variant")
You could also try adding return false; or event.preventDefault() and see if that works.
And one more approach is to check event.target in your blur handler:
InputElement.onblur = function(event) {
event = event || window.event // cross-browser event
var IconElement = [do something to get the element];
if (event.target == IconElement) {
// Ignore this blur event, or maybe even call "this.focus()"
}
}
Here is the final very simple solution inspired by #Yury's answer:
$('.clearable-icon').mousedown(function() {
// This happens before blur, so return false and stop propagation.
return false;
});
I have a few input fields one on top of each other, I want to be able to check if a user used the tab key or clicked to focus on the current input field.
Checking on the .live('click', function() { is easy but i don't know how to check if they used tab to focus on the current input field.
I’m sure there are many ways to do this, but one way is to listen for the keyup event and then find out what element is focused, if any:
$(document).on('keyup', function(e) {
if(e.keyCode == 9) {
var input = $(this).find('input:focus');
// input is the element that has focus after the tab key was pressed
}
});
This might not be a guarantee that the tab key was used to bring focus to the element, but it might be sufficient for what you need.
If you want to check the event type that the user used before an input field gained focus, try:
$(document).on('keyup', function(e) {
if(e.keyCode == 9) {
findFocus(e);
}
}).on('click', 'input', findFocus);
function findFocus(e) {
var input = $(document).find('input:focus');
if ( input.length ) {
alert('Input was focused using '+e.type);
}
}
Also note that I used the .on() event instead of .live(), since live is deprecated in 1.7.
Sounds like you want the "focus" event which will fire if the user clicks on OR tabs to the field
.on('focus', function() {});
also this answer notes that "live" is deprecated, use "on" instead
https://stackoverflow.com/a/4944344/703173
$('input').on('click', function() {
$(this).data('clicked', true);
}).on('focus', function() {
setTimeout(function(){
if($(this).data('clicked') == true){
// clicked to focus
}else{
// used tab key to focus
}
$(this).data('clicked', false);
}, 100);
});
I am using the JavaScript select event to detect when the user selects a range of characters within a textarea. However, the event does not seem to be invoked when the selection is cleared, either by clicking elsewhere in the textarea, or by moving the caret.
I have tested this in Chrome 12 and Firefox 4
There's onblur event which you can append after a selection has being made :)
var t = document.getElementsByTagName('textarea')[0];
t.onselect = function() {
alert('select');
if (typeof(t.onblur) !== 'function') {
t.onblur = function() {
alert('selection cleared');
t.onblur = null;
}
}
}
jsFiddle
My idea: create a function which will be executed after the text has been selected, and after it's being executed unset it ... since there's no text selection any more, and when the text has been selected again - the function will be defined again
How about a combination of click, blur, and keypress event bound to the element?
Here is a demo of JavaScript select/deselect event
i have a function that currently working on .keypress event when the user right something in the textbox it do some code, but i want the same event to be triggered also when the user clear the textbox .change doesn't help since it fires after the user change the focus to something else
Thanks
The keyup event will detect if the user has cleared the box as well (i.e. backspace raises the event but backspace does not raise the keypress event in IE)
$("#inputname").keyup(function() {
if (!this.value) {
alert('The box is empty');
}
});
jsFiddle
As Josh says, this gets fired for every character code that is pressed in the input. This is mostly just showing that you need to use the keyup event to trigger backspace, rather than the keypress event you are currently using.
The solution by Jonathon Bolster does not cover all cases. I adapted it to also cover modifications by cutting and pasting:
$("#inputname").on('change keyup copy paste cut', function() {
//!this.value ...
});
see http://jsfiddle.net/gonfidentschal/XxLq2/
Unfortunately it's not possible to catch the cases where the field's value is set using javascript. If you set the value yourself it's not an issue because you know when you do it... but when you're using a library such as AngularJS that updates the view when the state changes then it can be a bit more work. Or you have to use a timer to check the value.
Also see the answer for Detecting input change in jQuery? which suggests the 'input' event understood by modern browsers. So just:
$("#inputname").on('input', function() {
//!this.value ...
});
Another way that does this in a concise manner is listening for "input" event on textarea/input-type:text fields
/**
* Listens on textarea input.
* Considers: undo, cut, paste, backspc, keyboard input, etc
*/
$("#myContainer").on("input", "textarea", function() {
if (!this.value) {
}
});
You can check the value of the input field inside the on input' function() and combine it with an if/else statement and it will work very well as in the code below :
$( "#myinputid" ).on('input', function() {
if($(this).val() != "") {
//Do action here like in this example am hiding the previous table row
$(this).closest("tr").prev("tr").hide(); //hides previous row
}else{
$(this).closest("tr").prev("tr").show(); //shows previous row
}
});
Inside your .keypress or .keyup function, check to see if the value of the input is empty. For example:
$("#some-input").keyup(function(){
if($(this).val() == "") {
// input is cleared
}
});
<input type="text" id="some-input" />