jQuery: focusout to exclude some elements - javascript

focusout on input field will trigger every time the specific input looses its focus.
But, I want to exclude some specific a tag from triggering that focusout function
Example:
<input type="text" id="name_input">
<a id="apply_name">SAVE</a>
Then the focusout function:
$("#name_input").focusout(function(e) {
//do something here
});
Clicking on "#apply_name" also triggers focusout function of an input. How can I exclude that specific element ID from triggering it.
Note: I tried some tricks already posted on StackOverflow and none of them seams to work...

Another way of doing this is checking what your target id is
var evt;
document.onmousemove = function (e) {
e = e || window.event;
evt = e;
}
$("#name_input").focusout(function (e) {
if (evt.target.id == "apply_name") {
//apply_name clicked
} else {
//focus out and applyname not clicked
}
});
DEMO

You can use "blur" - event.
$("#name_input").on("blur", function(e) {
//your code
});

Solution from How to exclude Id from focusout
Added .hasClass which I also needed:
$('#id').focusout (function (e) {
if (e.relatedTarget && $(e.relatedTarget).hasClass('dontFocusOut')) {
return;
}
//do your thing
});

Related

<input type="date"> event listener: How to distinguish mouse select vs. keyboard input

I use the native HTML date pickers. I want to achieve that the parent form is submitted when a date is selected by the datepickers browsers provide.
If the date is input by keyboard, I only want to submit if the enter key is pressed or on focusout.
Now my problem is that I cannot distinguish between date picker input and keyboard input, at least in Firefox. Some examples:
$(this).on('input', function(event) {
console.log(event.type);
}
This always logs 'input', no matter what I do - I would have expected that to be either "click" or "keydown" or something alike.
The on('click') handler only fires when I click on the input field, not when I click something in the date picker...
Can someone push me in the right direction?
Thanks alot
Philipp
I did a workaround which is close to what I want:
$('#eooMainForm input[type="date"]')
.each(function() {
$(this).data('serialized', $(this).serialize());
$(this).on('focusout', function() {
if($(this).serialize() != $(this).data('serialized')) {
$("#eooMainForm").form('submit');
}
});
$(this).on('keypress', function(event) {
$(this).data('byKeyPress', 1);
});
$(this).on('click', function(event) {
$(this).data('byKeyPress', 0);
});
$(this).on('change', function(event) {
//if change was done by date picker click
if($(this).data('byKeyPress') != 1 && $(this).serialize() != $(this).data('serialized')) {
$("#eooMainForm").form('submit');
}
});
});
So a keypress event listener sets the "flag" "byKeyPress" to 1, while a click events listener sets it to zero. This way, I can determine in the change event listener what caused the change.
The only situation where this does not work is when a user starts typing the date but then selects it by clicking the datepicker. I can live with that.
You'll need to attach an event which supports both event types. Using JQuery: $('a.save').bind('mousedown keypress', submitData(event, this));
Then create a JS condition:
function submitData(event, id)
{
if(event.type == 'mousedown')
{
// do something
return;
}
if(event.type == 'keypress')
{
// do something else
return;
}
}
You can find all the list of event in this image.
$('input').on('blur', function(event) {
alert(event.type);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" />
You can apply all event like the above example. Above example applied blur event on input.

jQuery Keydown/Keyup only works every second time

I have keyup/down events binded to the document. The Keydown will only fires every second time, without me knowing why. I tried many suggestions given on similar SO-Questions, but none of them works.
My Javascript:
$(document).on('keyup', function() {
$('div').removeClass('bar');
});
$(document).on('keydown', function(e) {
if(e.altKey) {
$('div').addClass('bar'); // only every second hit will add the class
}
});
This should point out the issue:
http://jsfiddle.net/6yxt53m9/1/
You need to add return false; to the key press functions:
$(document).on('keyup', function() {
$('div').removeClass('bar');
return false;
});
$(document).on('keydown', function(e) {
if(e.altKey) {
$('div').addClass('bar');
}
return false;
});
Updated fiddle.
use
$(document).on('keyup', function(e) {
$('div').removeClass('bar');
e.preventDefault();
});
e.preventDefault(); will reset the input
Try this.
$(document).on('keydown', function(e) {
e.preventDefault();
if(e.altKey) {
$('div').addClass('bar'); // only every second hit will add the class
}
});
The reason is alt key occurs focus moving to button of "customize and control google chorome"

JavaScript prevent touch move on body element, enable on other elements

but very simply, I'd like to prevent the touchmove event on the body element but leave it enabled for another element. I can disable fine... but I'm not sure how to re-enable it somewhere else!
I imagine that the below theoretically works because return true is the opposite of preventDefault, but it doesn't work for me. Might be 'cause $altNav element is in $bod?
JS:
$bod.bind('touchmove', function(event){
event.preventDefault();
});
$altNav.bind('touchmove', function(event){
return true;
});
I'm not sure what lib you're actually using, but I'll asume jQuery (I'll also post the same code in browser-native-js if you're using something other than jQ)
$bod.delegate('*', 'touchstart',function(e)
{
if ($(this) !== $altNav)
{
e.preventDefault();
//and /or
return false;
}
//current event target is $altNav, handle accordingly
});
That should take care of everything. The callback here deals with all touchmove events, and invokes the preventDefault method every time the event was triggered on an element other than $altNav.
In std browser-js, this code looks something like:
document.body.addEventListener('touchmove',function(e)
{
e = e || window.event;
var target = e.target || e.srcElement;
//in case $altNav is a class:
if (!target.className.match(/\baltNav\b/))
{
e.returnValue = false;
e.cancelBubble = true;
if (e.preventDefault)
{
e.preventDefault();
e.stopPropagation();
}
return false;//or return e, doesn't matter
}
//target is a reference to an $altNav element here, e is the event object, go mad
},false);
Now, if $altNav is an element with a particular id, just replace the target.className.match() thing with target.id === 'altNav' and so on...
Good luck, hope this helps
Use a custom CSS class and test for it in the document handler, eg:
<div>
This div and its parents cannot be scrolled.
<div class="touch-moveable">
This div and its children can.
</div>
</div>
then:
jQuery( document ).on( 'touchmove', function( ev )
{
if (!jQuery( ev.target ).parents().hasClass( 'touch-moveable' ))
{
ev.preventDefault();
}
});
http://tinyurl.com/mo6vwrq
you can add a argument,like this
$bod.bind('touchmove', function(event,enable){
if(enable){
event.preventDefault();
}
});

Why does jQuery's one fire immediately when it's added to an element?

Here's a fiddle illustrating the problem. I am adding a jQuery one binding on the click of one element to the 'html' element. I am not expecting the 'one' event handler to fire until the next click, but it fires on the click that adds the binding. This seems to not be a problem if it is a more specific element that the 'one' event handler is added to, but it happens when I use 'html' or 'body' as the element, which is what I want to do.
This doesn't make sense to me, I'd think the first click would add the one for the next click and it wouldn't fire on the click on the link.
By the way, my actual problem could probably be solved in a better way, but I came across this and was curious why it didn't work as I expected.
Code:
html:
<div id='hello'>hello</div>
<a class="title" href="#">this example</a> is a test​
js:
$(function() {
$('a.title').click(function() {
var htmlClickBind = function (e) {
console.log('clicked on html, e.target = ' + e.target);
console.log(e.target == '');
if (!$(e.target).is('a') ) {
console.log('cleared click event');
}
else {
$('html').one('click', htmlClickBind);
}
};
$('html').one('click', htmlClickBind);
});
});​
The click event on the a.target element bubbles up to the html element, where your (just-added) handler sees it.
To prevent this, use event.stopPropgation in your a.target click handler (or return false, which does stopPropagation and preventDefault).
Updated code (see the comments): Live copy
$(function() {
// Accept the event arg ----v
$('a.title').click(function(e) {
// Stop propagation
e.stopPropagation();
var htmlClickBind = function (e) {
console.log('clicked on html, e.target = ' + e.target);
console.log(e.target == '');
if (!$(e.target).is('a') ) {
console.log('cleared click event');
}
else {
$('html').one('click', htmlClickBind);
}
};
$('html').one('click', htmlClickBind);
});
});​

Simulate an "ontype" event

I want to simulate the Google Search effect that even with the search box not focused, the user can start typing and the input box will capture all keyboard strokes.
I have looked for an ontype event, but haven't found anything. I know that the event object in callbacks for events like click has keyboard information, but I don't think this is what I'm after.
This does the job:
$(document).on('keydown', function() {
$('input').focus();
});
HTML:
<input type="text" id="txtSearch" />
Javascript:
var googleLikeKeyCapture = {
inputField : null,
documentKeydown: function(event) {
var inputField = googleLikeKeyCapture.inputField;
if(event.target != inputField.get(0)) {
event.target = inputField.get(0);
inputField.focus();
}
},
init: function() {
googleLikeKeyCapture.inputField = $('#txtSearch');
$(document).bind('keydown', googleLikeKeyCapture.documentKeydown);
googleLikeKeyCapture.inputField
.focus(function() {
$(document).unbind('keydown');
})
.blur(function() {
$(document).bind('keydown', googleLikeKeyCapture.documentKeydown);
});
googleLikeKeyCapture.init = function() {};
}
};
$(googleLikeKeyCapture.init);
Also you can find jsFiddle example here
EDIT :
And now it's a jQuery plugin. :) If keydown occures in a textarea or input field it doesn't capture keys, anything else goes to designated input field. If your selector matches more than one element it only uses the first element.
Usage: $('#txtSearch').captureKeys();
The event you are after is onkeypress.
Try this jQuery Text Change Event plugin:
http://www.zurb.com/playground/jquery-text-change-custom-event

Categories