Avoid click triggering focusout - javascript

i am working on the tab button functionality for my form.
I am using a plugin to customize all the selects of my form but now i am stuck on a conflict.
This is the code i have written to display my dropdown menu list using the tab button on the selects
$styledSelect.focus(function(e) {
var dropdown = $(this).next('ul');
dropdown.show();
});
$styledSelect.focusout(function(e) {
var dropdown = $(this).next('ul');
dropdown.hide();
});
The problem is that any click event triggers a focusout so i can not really select any option of my select tag, because the dropdown gets hidden first.
You can see the problem here http://codepen.io/Mannaio/pen/tLaup
How can i solve this problem?

You can set up a click and focus handler and reuse the same logic for both.
function setFocus(e) {
e.stopPropagation();
$('div.select-styled.active').each(function() {
$(this).removeClass('active').next('ul.select-options').hide();
});
$(this).toggleClass('active').next('ul.select-options').toggle();
};
$styledSelect.click(setFocus);
$styledSelect.focus(setFocus);
Updated CodePen: http://codepen.io/anon/pen/kcpqd

Working off of Burntforest's answer (accounts for the dropdowns not closing when tabbing out):
function getFocus(e) {
e.stopPropagation();
hideAllLists();
$(this).toggleClass('active').next('ul.select-options').toggle();
};
function hideAllLists() {
$('div.select-styled.active').removeClass('active')
.next('ul.select-options').hide();
}
$styledSelect.click(getFocus);
$styledSelect.focus(getFocus);
$(document).keydown(function(e) {
if (e.keyCode === 9)
hideAllLists();
});
http://codepen.io/anon/pen/BqEkz

Related

Can't change radio button selection

I have some tables (more than one), when I select one table by clicking on it, I need that the first radio button is selected.
It works fine, but if I want to change the option of the radio button i cant. It keeps always the first one marked.
Here is a fiddle with the issue:
https://jsfiddle.net/jzbm4j60/
$('table').click(function(event) {
$('table').removeClass('focus');
event.stopPropagation();
$(this).addClass('focus');
var $firstRadio = $(this).find('input:radio[name=rdGoFerrys]:first');
var $secondRadio = $(this).find('input:radio[name=rdBackFerrys]:first');
if ($firstRadio.is(':checked') === false) {
$firstRadio.prop('checked', true);
}
if ($secondRadio.is(':checked') === false) {
$secondRadio.prop('checked', true);
}
});
The click event on your inputs is bubbling up the DOM and triggering the click event you have on your table. Stop that behavior by using:
$('input').click(function(e) {
e.stopPropagation()
})

Deselect a radio option

I'm using the bootstrap radio buttons and would like to allow deselection of a radio group. This can be done using an extra button (Fiddle). Instead of an extra button, however, I would like to deselect a selected radio option if the option is clicked when it's active.
I have tried this
$(".btn-group label").on("click", function(e) {
var clickedLabel = $(this);
if ($(clickedLabel).hasClass("active"))
{
// an active option was clicked => deselect it
$(clickedLabel).children("input:radio").prop("checked", false)
$(clickedLabel).removeClass("active");
}
}
)
but there seems to be a race condition: the event of clicking the label that I use seems to be used by bootstrap.js to set the clicked label option to "active". If I introduce a timeout, the class "active" is removed successfully:
$(".btn-group label").on("click", function(e) {
var clickedLabel = $(this);
if ($(clickedLabel).hasClass("active"))
{
setTimeout(function() {
// an active option was clicked => deselect it
$(clickedLabel).children("input:radio").prop("checked", false)
$(clickedLabel).removeClass("active");
}, 500)
}
}
)
How can I toggle a selected option successfully without using a timeout?? Thank you for help.
Instead of using two method's preventDefault & stopPropagation, use return false, will work same.
The difference is that return false; takes things a bit further in
that it also prevents that event from propagating (or "bubbling up")
the DOM. The you-may-not-know-this bit is that whenever an event
happens on an element, that event is triggered on every single parent
element as well.
$(".btn-group label").on("click", function(e) {
var clickedLabel = $(this);
if ($(clickedLabel).hasClass("active"))
{
// an active option was clicked => deselect it
$(clickedLabel).children("input:radio").prop("checked", false)
$(clickedLabel).removeClass("active");
return false;
}
});
After messing with your code in jsfiddle for a while I figured out that a combination of preventDefault() and stopPropagation() does the trick.
Here's a fiddle
and the code:
$(".btn-group label").on("click", function(e) {
var clickedLabel = $(this);
if ($(clickedLabel).hasClass("active"))
{
// an active option was clicked => deselect it
$(clickedLabel).children("input:radio").prop("checked", false)
$(clickedLabel).removeClass("active");
e.preventDefault();
e.stopPropagation();
}
}
);

Show a Div first and then Submit on second click of button in a form

I have a form with multiple divs with same names (full-width). They all are on the same level. One of them is hidden (with a class hide). What I want is that if I select Submit, it should not submit, first hide all the brother divs of the hidden div (in this case full-width) and unhide the one with the class hide.
Now when I press again, it should just submit the Form.
JSFiddle is here:- http://jsfiddle.net/xmqvx/2/
Your code had a couple issues:
You used event.preventDefault but passed event in as e - should be e.preventDefault
Your ID selector targeted an ID that didnt exist (changed to #submit-this)
The working code:
$("#submit-this").click(function (e) {
e.preventDefault();
if ($(".full-width").hasClass("hide")) {
$(".full-width").hide();
$(".full-width.hide").removeClass("hide").show();
} else {
alert("Submitting");
$("#this-form").submit();
}
});
http://jsfiddle.net/xmqvx/4/
You could also take advantage of JavaScript's closures like so, to avoid having your behavior be dependent on your UI:
$(document).ready(function () {
var alreadyClicked = false;
$("#submit-this").click(function (e) {
e.preventDefault();
if (alreadyClicked) {
$('#this-form').submit();
} else {
$('.full-width').hide();
$('.hide').show();
alreadyClicked = true;
}
});
});

Jquery - Differentiate between 'click' and 'focus' on same input when using both

I'm trying to trigger an event on an input if the input is clicked or if the input comes in to focus.
The issue i'm having is preventing the event from firing twice on the click as, obviously, clicking on the input also puts it in focus. I've put a very loose version of this on jfiddle to show you what I mean, code as below:
HTML:
<body>
<input type="textbox" name="tb1" class="input1"></input>
<label> box 1 </label>
<input type="textbox" name="tb2" class="input2"></input>
<label> box 2 </label>
</body>
JQuery
$(function () {
$('.input2').click(function() {
alert("click");
});
$('.input2').focus(function() {
alert("focus");
});
});
JSFiddle: http://jsfiddle.net/XALSn/2/
You'll see that when you tab to input2 you get one alert, but if you click you get two. Ideally for my scenario, it needs to be one alert and ignore the other. it also doesn't seem to actually focus.
Thanks in advance for any advice.
How about setting a flag on focus so we can fire on focus and ignore clicks but then listen for clicks on the focussed element too? Make sense? Take a look at the demo jsFiddle - If you focus or click on the unfocussed .index2 it triggers the focus event and ignores the click. Whilst in focus, clicking on it will trigger the click.
I have no idea why you would want this (I cant imagine anyone wanting to click on a focussed element for any reason (because the carat is already active in the field) but here you go:
$(function () {
$('.input2').on("click focus blur", function(e) {
e.stopPropagation();
if(e.type=="click"){
if($(this).data("justfocussed")){
$(this).data("justfocussed",false);
} else {
//I have been clicked on whilst in focus
console.log("click");
}
} else if(e.type=="focus"){
//I have been focussed on (either by clicking on whilst blurred or by tabbing to)
console.log("focus");
$(this).data("justfocussed",true);
} else {
//I no longer have focus
console.log("blur");
$(this).data("justfocussed",false);
}
});
});
http://jsfiddle.net/XALSn/12/
This probably won't be the best answer, but this is a way of doing it. I would suggest adding tab indexes to your inputs and firing the focus event when you blur from another input.
I've added that to this fiddle:
http://jsfiddle.net/XALSn/9/
$(function () {
$('.input2').click(function(e) {
alert("click");
e.preventDefault();
});
});
$('input').blur(function(){
$('input').focus(function() {
alert("focus");
});
});
You can use one thing I am using very often in JS
var doSomething = true;
$(function () {
$('.input2').click(function(e) {
if (doSomething) {
// do something :)
}
doSomething = false;
});
$('.input2').focus(function() {
if (doSomething) {
// do something :)
}
doSomething = false;
});
});
But You have to change value of doSomething on mouseout or foucs over etc. :)
$(function () {
var hasFocus = false;
$("body")
.off()
.on({
click : function()
{
if(!hasFocus)
{
hasFocus = true;
alert("click");
}
},
focus : function()
{
if(!hasFocus)
{
hasFocus = true;
alert("focus");
}
}
},".input2");
});
try setting a flag hasFocus and act accordingly
http://jsfiddle.net/AEVTQ/2/
just add e.preventDefault() on the click event
$(function () {
$('.input2').click(function(e) {
console.log("click");
e.preventDefault();
e.stopPropagation();
});
$('.input2').focus(function() {
console.log("focus");
});
});
If I understand your question right, the e.prevnetDefault() will prevent the browser from automatically focusing on click. Then you can do something different with the click than would with the focus

X-Editable: stop propagation on "click to edit"

I have an editable element inside a div which itself is clickable. Whenever I click the x-editable anchor element, the click bubbles up the DOM and triggers a click on the parent div. How can I prevent that? I know it's possible to stop this with jQuery's stopPropagation() but where would I call this method?
Here's the JSFiddle with the problem: http://jsfiddle.net/4RZvV/ . To replicate click on the editable values and you'll see that the containing div will catch a click event. This also happens when I click anywhere on the x-editable popup and I'd like to prevent that as well.
EDIT after lightswitch05 answer
I have multiple dynamic DIVs which should be selectable so I couldn't use a global variable. I added an attribute to the .editable-click anchors which get's changed instead.
editable-active is used to know if the popup is open or not
editable-activateable is used instead to know if that .editable-click anchor should be treated like it is
$(document).on('shown', "a.editable-click[editable-activateable]", function(e, reason) {
return $(this).attr("editable-active", true);
});
$(document).on('hidden', "a.editable-click[editable-activateable]", function(e, reason) {
return $(this).removeAttr("editable-active");
});
The check is pretty much like you've described it
$(document).on("click", ".version", function() {
$this = $(this)
// Check that the xeditable popup is not open
if($this.find("a[editable-active]").length === 0) { // means that editable popup is not open so we can do the stuff
// ... do stuff ...
}
})
For the click on the links, simply catch the click event and stop it:
$("a.editable-click").click(function(e){
e.stopPropagation();
});
The clicks within X-editable are a bit trickier. One way is to save a flag on weather the X-editable window is open or not, and only take action if X-editable is closed
var editableActive = false;
$("a.editable-click").on('shown', function(e, reason) {
editableActive = true;
});
$("a.editable-click").on('hidden', function(e, reason) {
editableActive = false;
});
$("div.version").click(function(e) {
var $this;
$this = $(this);
if(editableActive === false){
if ($this.hasClass("selected")) {
$(this).removeClass("selected");
} else {
$(this).addClass("selected");
}
}
});
Fixed Fiddle
It's not pretty, but we solved this problem with something like:
$('.some-class').click(function(event) {
if(event.target.tagName === "A" || event.target.tagName === "INPUT" || event.target.tagName === "BUTTON"){
return;
}
We're still looking for a solution that doesn't require a specific list of tagNames that are okay to click on.

Categories

Resources