What I wanted to do is figure out whenever the user is engaged with an INPUT or TEXTAREA element and set a variable flag to true... and set that flag to false immediately after the user is no longer engaged with them (ie. they've clicked out of the INPUT/TEXTAREA elements).
I used jQuery's docuemnt.ready function to add the onclick attribute to my body element and assign it to my getActive() function.
The code for the getActive() function is as follows:
function getActive()
{
activeObj = document.activeElement;
var inFocus = false;
if (activeObj.tagName == "INPUT" || activeObj.tagName == "TEXTAREA")
{
inFocus = true;
}
}
I'd really like to keep by project withing the jQuery framework, but can't seem to find a way of accomplishing the same logic above using JUST jQuery syntax.
You want the focus and blur event handlers. For example...
var inFocus = false;
$('input, textarea').focus(function() {
inFocus = true;
});
$('input, textarea').blur(function() {
inFocus = false;
});
I'm pretty sure that a comma will get you input OR textarea, but you get the idea if that doesn't pan out
function getActive(){
return $(document.activeElement).is('input') || $(document.activeElement).is('textarea');
}
For the original question about figuring out if the currently focused element is any of those user input elements, below should work:
function isInputElementInFocus() {
return $(document.activeElement).is(":input");
}
Conceptually I don't like this approach for generic case where you are listening to global events (like key strocks) and trying to decide if these should be handled by your global handler or be ignored because it is meant for someone else. The reason I don't like it because it's not future safe and also who knows what else that someone can be besides input elements.
Another more robust but tricky to implement idea is to test if event is meant for an element that has tabIndex >= 0. The input elements have tabIndex === 0 set by default so it becomes more or less similar to above approach. You can easily check this by event.target.tabIndex >= 0 without need to rely on document.activeElement.
The gotchas here (if you want to be generic) is that you also need to make sure that event.target element is neither in another branch in DOM hierarchy nor there is someone else between event.currentTarget and event.target that has tabIndex >= 0. You get the idea: This can become murky but I just thought to jot it down if someone else is in need of generic solution.
You can do something like this :
var focusItem = null;
$('input, textarea').focus( function() {
focusItem = this;
});
Iis the .blur() event what you're looking for?
Related
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.
I want to set up an onBlur event for an input element that validates the value and, if invalid, "cancels" the blur and refocusses(or focus never loss) the current input.
i have this peace of code already
document.getElementById('my_input_id1').onblur = function() {
var self = this;
setTimeout(function() { self.focus(); }, 10);
}
Suppose my next focused element is'my_input_id2' which also has an "onblur" event.as focus is already moved to 'my_input_id2'.When i set focus back to 'my_input_id1' the second elment 'my_input_id2' "onblur event is fried.I want to cancel onblur event of second element.i have many other element with "onlur" for Validation.
Can i stop elemnt not to lost focus?
Is there another function that can do it without lost focus??
Should i use some other function that does not lose focus??
Is there another way to get out of this problem??
Many many thanks in advance.
Try it
$('#my_input_id1').on('blur',function(){
if(SOME CONDITION){
setTimeout(function(){
$('#my_input_id1').focus();
},100);
return false;
}
});
This is quite straight forward to do with JavaScript:
document.getElementById('id1').onblur = function(e) {
if(this.value.length == 0) {
this.focus();
e.preventDefault();
return false;
}
}
Essentially just refocusing the element based on a criteria, of course this can be anything you want it to be.
and here is the fiddle: http://jsfiddle.net/m4cZ2/1/
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;
});
Is it possible to bind javascript (jQuery is best) event to "change" form input value somehow?
I know about .change() method, but it does not trigger until you (the cursor) leave(s) the input field. I have also considered using .keyup() method but it reacts also on arrow keys and so on.
I need just trigger an action every time the text in the input changes, even if it's only one letter change.
There is a simple solution, which is the HTML5 input event. It's supported in current versions of all major browsers for <input type="text"> elements and there's a simple workaround for IE < 9. See the following answers for more details:
jQuery keyboard events
Catch only keypresses that change input?
Example (except IE < 9: see links above for workaround):
$("#your_id").on("input", function() {
alert("Change to " + this.value);
});
Yes, compare it to the value it was before it changed.
var previousValue = $("#elm").val();
$("#elm").keyup(function(e) {
var currentValue = $(this).val();
if(currentValue != previousValue) {
previousValue = currentValue;
alert("Value changed!");
}
});
Another option is to only trigger your changed function on certain keys. Use e.KeyCode to figure out what key was pressed.
You can also store the initial value in a data attribute and check it against the current value.
<input type="text" name="somename" id="id_someid" value="" data-initial="your initial value" />
$("#id_someid").keyup(function() {
return $(this).val() == $(this).data().initial;
});
Would return true if the initial value has not changed.
function checkChange($this){
var value = $this.val();
var sv=$this.data("stored");
if(value!=sv)
$this.trigger("simpleChange");
}
$(document).ready(function(){
$(this).data("stored",$(this).val());
$("input").bind("keyup",function(e){
checkChange($(this));
});
$("input").bind("simpleChange",function(e){
alert("the value is chaneged");
});
});
here is the fiddle http://jsfiddle.net/Q9PqT/1/
You can employ the use of data in jQuery and catch all of the events which then tests it against it's last value (untested):
$(document).ready(function() {
$("#fieldId").bind("keyup keydown keypress change blur", function() {
if ($(this).val() != jQuery.data(this, "lastvalue") {
alert("changed");
}
jQuery.data(this, "lastvalue", $(this).val());
});
});
This would work pretty good against a long list of items too. Using jQuery.data means you don't have to create a javascript variable to track the value. You could do $("#fieldId1, #fieldId2, #fieldId3, #fieldId14, etc") to track many fields.
UPDATE: Added blur to the bind list.
I had to use this kind of code for a scanner that pasted stuff into the field
$(document).ready(function() {
var tId,oldVal;
$("#fieldId").focus(function() {
oldVal = $("#fieldId").val();
tId=setInterval(function() {
var newVal = $("#fieldId").val();
if (oldVal!=newVal) oldVal=newVal;
someaction() },100);
});
$("#fieldId").blur(function(){ clearInterval(tId)});
});
Not tested...
I don't think there's a 'simple' solution. You'll probably need to use both the events onKeyUp and onChange so that you also catch when changes are made with the mouse. Every time your code is called you can store the value you've 'seen' on this.seenValue attached right to the field. This should make a little easier.
You can set events on a combination of key and mouse events, and onblur as well, to be sure. In that event, store the value of the input. In the next call, compare the current value with the lastly stored value. Only do your magic if it has actually changed.
To do this in a more or less clean way:
You can associate data with a DOM element (lookup api.jquery.com/jQuery.data ) So you can write a generic set of event handlers that are assigned to all elements in the form. Each event can pass the element it was triggered by to one generic function. That one function can add the old value to the data of the element. That way, you should be able to implement this as a generic piece of code that works on your whole form and every form you'll write from now on. :) And it will probably take no more than about 20 lines of code, I guess.
An example is in this fiddle: http://jsfiddle.net/zeEwX/
Since the user can go into the OS menu and select paste using their mouse, there is no safe event that will trigger this for you. The only way I found that always works is to have a setInterval that checks if the input value has changed:
var inp = $('#input'),
val = saved = inp.val(),
tid = setInterval(function() {
val = inp.val();
if ( saved != val ) {
console.log('#input has changed');
saved = val;
},50);
You can also set this up using a jQuery special event.
I've been trying experiments with the following, but so far to no avail:
sel = document.getElementById('myComboBox')
sel.selectedIndex = 1;
sel.options[1].selected = true;
sel[1].click();
Thanks for the help!
Wait why would you write:
sel.options[1].selected = true;
and then in the very next line write
sel[1].click();
?? The element is not an array and can't be treated as one.
The "click" event might not be the best thing to handle anyway. Probably the "change" event on the select element itself would be more reliable.