Prevent loss of focus unless hovering over a certain element - javascript

I have a page with a textarea #content and an input textbox #name. Once the user has clicked on #content, I want to prevent him from loosing focus of that textarea, unless he is clicking on #name.
I've tried the following:
// Prevent loss of focus for textarea
$("#content").on("blur", function(event) {
$('#name').mouseover(function() {
return true;
});
event.preventDefault();
this.focus();
return false;
});
It works just fine to prevent loss of focus of an element. But my idea of checking if he's hovering #name and returning just doesn't work.

Stole the code from here to get the element that triggered the blur.
var clicky;
$(document).mousedown(function(e) {
// The latest element clicked
clicky = $(e.target);
});
$("#content").on("blur", function(event) {
if (clicky.attr('id') == 'name') {
return true;
}
event.preventDefault();
this.focus();
return false;
});
fiddle

Something like this, maybe?
$(document).ready(function(){
var id;
$('#content').on('blur',function(){
$(":input").focus(function(){
id = this.id;
if(id != 'username' && id != 'content'){ // sorry, changed your id from name to username.
$('#content').focus();
}
});
});
});
Working fiddle: http://jsfiddle.net/ugx3S/

Related

issues using e.target.tagName or .prop in ie8

I have following logic that works great in all browsers I tested, besides ie8
$('.has_tags li').click(function(e) {
if($(this).hasClass('tag_clicked') && e.target.tagName !== 'LABEL') {
$(this)
.removeClass('tag_clicked')
.children('input').prop('checked', false);
} else if (!$(this).hasClass('tag_clicked') && e.target.tagName !== 'LABEL') {
$(this)
.addClass('tag_clicked')
.children('input').prop('checked', true);
}
});
In a nutshell it checks if a list element is clicked, if it iss ads class to it that styles current list and checks associated input, however if label inside such list element is clicked, than it ignores it as click on label is equal to click on checkbox. However, ie8 handles it well when list element is clicked, but when label associated to it is clicked nothing happens. Here is jsfidle
I propose to add event on INPUT and triggers it when you click on LI
$('.has_tags li').on('click', function(e){
var $target = $(e.target);
var $input = $(this).find('input');
if($target.closest('input').length || $target.closest('label').length) return;
$input.prop('checked', !$input.prop('checked')).trigger('change');
});
$('.has_tags input').on('change.checkbox', function(e){
var $input = $(this).closest('li');
if(this.checked) {
$input.addClass('tag_clicked');
} else {
$input.removeClass('tag_clicked');
}
}).trigger('change.checkbox');
https://jsfiddle.net/aL5uuwng/1/

select previously focused input before blur

I have this auto suggest menu with my input fields and as there are multiple fields I need to select the field that was in focus just before the li was clicked and blurred the input, so it knows which input to select. is there a way to get the last input field focused before the blur? Thanks
function fill(thisValue) {
if(thisValue === undefined){
$('#suggestions').fadeOut();
} else {
$("input *//input in focus before blur//* .val(thisValue);
setTimeout("$('#suggestions').fadeOut();", 600);
$('.email').addClass('load');
}
}
Yes there is, but you'll need to store the last focused element when the LI is clicked, or more accurately before it's clicked, and blur is too late.
var lastFocused = null;
$('li').on({
mousedown: function() {
lastFocused = document.activeElement; //saves focused element
},
click: function() {
//do whatever you do on click
}
});
function fill(thisValue) {
if(thisValue == undefined && lastFocused) {
$('#suggestions').fadeOut();
} else {
lastFocused.value = thisValue;
setTimeout(function() {
$('#suggestions').fadeOut();
}, 600);
$('.email').addClass('load');
}
}
Here's a quick DEMONSTRATION to show that it works!
If you can avoid globals by using data() or something similar, that would be better, it's just to demonstrate how it's done.

Can I toggle popup after a click event with a mouseout event?

I'm using twitter bootstrap to display popovers with a click event. I'm requesting the info with the click event but I want to hide the popover after it looses focus so the user isn't required to click it again. Is this possible?
Basically I want to show the popover with a click event but then when the launch point looses focus from the mouse the popover is hidden.
Here is a link to the popover doc from twitter-bootstrap: http://twitter.github.com/bootstrap/javascript.html#popovers
This is what I'm currently doing:
jQuery:
$('.knownissue').on('click', function() {
var el = $(this);
if (el.data('showissue') == 'true') {
el.popover('toggle');
el.data('showissue', 'false');
return;
}
$.post('functions/get_known_issues.php', function(data) {
if (data.st) {
el.attr('data-content', data.issue);
el.popover('toggle');
el.data('showissue', 'true');
}
}, "json");
});
Any thoughts?
The following should work.
$('.knownissue').mouseleave(function() {
$(this).popover('hide');
});
Here is a custom jQuery event I call 'clickoutside'. It gets fired if and only if you click the mouse outside of the target element. It could easily be adapted for other event types (mousemove, keydown, etc). In your case, when fired it could close your modal.
(function ($) {
var count = 0;
$.fn.clickoutside = function (handler) {
// If the source element does not have an ID, give it one, so we can reference it
var self = $(this);
var id = self.attr('id');
if (id === '') {
id = 'clickoutside' + count++;
self.attr('id', id);
}
// Watch for the event everywhere
$('html').click(function (e) {
var source = $(e.target);
// ... but, stop it from propagating if it is inside the target
// element. The result being only events outside the target
// propagate to the top.
if (source.attr('id') == id || source.parents('#' + id).length > 0) {
return;
}
handler.call(this, e);
})
};
})(jQuery);
$('#targetElement').clickoutside(function(){
});
EDIT: Example JSFiddle.

Catch only keypresses that change input?

I want to do something when a keypress changes the input of a textbox. I figure the keypress event would be best for this, but how do I know if it caused a change? I need to filter out things like pressing the arrow keys, or modifiers... I don't think hardcoding all the values is the best approach.
So how should I do it?
In most browsers, you can use the HTML5 input event for text-type <input> elements:
$("#testbox").on("input", function() {
alert("Value changed!");
});
This doesn't work in IE < 9, but there is a workaround: the propertychange event.
$("#testbox").on("propertychange", function(e) {
if (e.originalEvent.propertyName == "value") {
alert("Value changed!");
}
});
IE 9 supports both, so in that browser it's better to prefer the standards-based input event. This conveniently fires first, so we can remove the handler for propertychange the first time input fires.
Putting it all together (jsFiddle):
var propertyChangeUnbound = false;
$("#testbox").on("propertychange", function(e) {
if (e.originalEvent.propertyName == "value") {
alert("Value changed!");
}
});
$("#testbox").on("input", function() {
if (!propertyChangeUnbound) {
$("#testbox").unbind("propertychange");
propertyChangeUnbound = true;
}
alert("Value changed!");
});
.change() is what you're after
$("#testbox").keyup(function() {
$(this).blur();
$(this).focus();
$(this).val($(this).val()); // fix for IE putting cursor at beginning of input on focus
}).change(function() {
alert("change fired");
});
This is how I would do it: http://jsfiddle.net/JesseAldridge/Pggpt/1/
$('#input1').keyup(function(){
if($('#input1').val() != $('#input1').attr('prev_val'))
$('#input2').val('change')
else
$('#input2').val('no change')
$('#input1').attr('prev_val', $('#input1').val())
})
I came up with this for autosaving a textarea. It uses a combination of the .keyUp() jQuery method to see if the content has changed. And then I update every 5 seconds because I don't want the form getting submitted every time it's changed!!!!
var savePost = false;
jQuery(document).ready(function() {
setInterval('autoSave()', 5000)
$('input, textarea').keyup(function(){
if (!savePost) {
savePost = true;
}
})
})
function autoSave() {
if (savePost) {
savePost = false;
$('#post_submit, #task_submit').click();
}
}
I know it will fire even if the content hasn't changed but it was easier that hardcoding which keys I didn't want it to work for.

Preventing blur when user clicks on specific div not working in Firefox

I am using jquery to keep the focus on a text box when you click on a specific div. It works well in Internet Explorer but not in Firefox. Any suggestions?
var clickedDiv = false;
$('input').blur(function() { if (clickedDiv) { $('input').focus(); } });
$('div').mousedown(function() { clickedDiv = true; })
.mouseup(function() { clickedDiv = false });
Point to note: the focus() method on a jquery object does not actually focus it: it just cases the focus handler to be invoked! to actually focus the item, you should do this:
var clickedDiv = false;
$('input').blur( function() {
if(clickeddiv) {
$('input').each(function(){this[0].focus()});
}
}
$('div').mousedown(function() { clickedDiv = true; })
.mouseup(function() { clickedDiv = false });
Note that I've used the focus() method on native DOM objects, not jquery objects.
This is a direct (brute force) change to your exact code. However, if I understand what you are trying to do correctly, you are trying to focus an input box when a particular div is clicked when that input is in focus.
Here's my take on how you would do it:
var inFocus = false;
$('#myinput').focus(function() { inFocus = true; })
.blur(function() { inFocus = false; });
$('#mydiv').mousedown(function() {
if( inFocus )
setTimeout( function(){ $('#myinput')[0].focus(); }, 100 );
}
Point to note: I've given a timeout to focussing the input in question, so that the input can actually go out of focus in the mean time. Otherwise we would be giving it focus just before it is about to lose it. As for the decision of 100 ms, its really a fluke here.
Cheers,
jrh
EDIT in response to #Jim's comment
The first method probably did not work because it was the wrong approach to start with.
As for the second question, we should use .focus() on the native DOM object and not on the jQuery wrapper around it because the native .focus() method causes the object to actually grab focus, while the jquery method just calls the event handler associated with the focus event.
So while the jquery method calls the focus event handler, the native method actually grants focus, hence causing the handler to be invoked. It is just unfortunate nomenclature that the name of this method overlaps.
I resolved it by simply replace on blur event by document.onclick and check clicked element if not input or div
var $con = null; //the input object
var $inp = null; // the div object
function bodyClick(eleId){
if (eleId == null || ($inp!= null && $con != null && eleId != $inp.attr('id') &&
eleId != $con.attr('id'))){
$con.hide();
}
}
function hideCon() {
if(clickedDiv){
$con.hide();
}
}
function getEl(){
var ev = arguments[0] || window.event,
origEl = ev.target || ev.srcElement;
eleId = origEl.id;
bodyClick(eleId);
}
document.onclick = getEl;
hope u find it useful

Categories