Select click event issue in IE7 (Jquery) - javascript

As IE 7 does not support the disabled attribute, I am using jQuery to add an event handler to the change event which checks if there is a disabled attribute on the select and setting the css color to grey on the disabled option.
However, as soon I click on the dropdown its closes my dropdown first then re-draw the new one with the grey color.
Here is my code:
(function($) {
$('select').change(function() {
if (this.options[this.selectedIndex].disabled) {
if (this.options.length == 0) {
this.selectedIndex = -1;
} else {
this.selectedIndex--;
}
//$(this).trigger('change');
}
});
$('select').each(function(it) {
if (this.options[this.selectedIndex].disabled) {
this.onchange();
}
});
$('select').click(function(e) {
//e.stopPropagation();
$(this).find('option[disabled]').css({
'color': '#cccccc'
});
});
})(jQuery);

Check out this example I've made for you:
http://jsfiddle.net/auNVE/
It should give you enough information for further development!
Good luck!
Edit
Update after having more information
http://jsfiddle.net/auNVE/1/
Edit
Now with mousedown instead of click
http://jsfiddle.net/auNVE/2/

Related

Can you stop the jQuery focusout from firing when losing focus?

I've got an input box that I want to have save its value when it loses focus.
Pretty straightforward stuff and I'm able to get that done via jQuery's focusout event.
The problem however, is that I want to NOT fire the focusout event when the user clicks on an "X" icon next to the input box (example shown below)
So when the user tabs out of this input box, or clicks outside of the box or they click the green checkbox it should fire the focusout event... but if they click the red "X", it should NOT fire the focusout.
Is this possible to do with JavaScript / jQuery?
EDIT:
Some of you have recommended using event.relatedTarget, but it seems like that's returning null. I'll include my code in question for clarity:
// This is the cancel button with the red X
$("body").on("click", "span[id*='Cancel']", function(e)
{
showLabel($(this));
});
// this is the code to trigger the blur / focusout event
// trouble is that the "e.relatedTarget" is null
$("body").on("focusout", "input, textarea", function (e) {
if($(e.relatedTarget).is("span[id*='Cancel']")){
return false;
}
$(this).siblings("span[id*='OK']").trigger("click");
return false;
});
Here's a screen grab of me debugging this in JS (you'll see that the $(e.relatedTarget) selector returns nothing):
You can cancel de event returning the focus to previous element.
$('#inputText').focusout(function(event) {
setTimeout(function(){
if (document.activeElement.id == "btnCancel") {
$(event.target).focus();
return false;
}
},1);
});
This jsFiddle shows how to do it: https://jsfiddle.net/mpervh3t/
Hope it helps
You must use relatedTarget like this :
$(document).ready(function(){
$(".btn").on("focusout",function(e){
if($(e.relatedTarget).hasClass("red")) {
alert("You clicked on X button");
}
else {
alert("Fire Focus out")
}
})
})
Final code :
<!DOCTYPE html>
<html>
<head>
<style>
.gr {
color: green;
}
.red {
color: red;
}
</style>
</head>
<body>
<input type="text" class="btn"><button class="gr">Ok</button><button class="red">X</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$(document).ready(function(){
$(".btn").on("focusout",function(e){
if($(e.relatedTarget).hasClass("red")) {
alert("You clicked on X button");
}
else {
alert("Fire Focus out")
}
})
})
</script>
</body>
</html>
As per my comment:
"I have had to do a similar type of thing with a blur event. Basically what I had to do was call a setTimeout on the blur to execute my function to save the data, and then on the click event of the X, cancel the timeout. That way, unless the X is clicked, the save function will fire. The delay can be pretty negligable, too."
I found the relevant code
var sliderTimeout = null;
$(".slider-trigger").on("blur", function () {
sliderTimeout = setTimeout(function () {
$(".slider").hide();
}, 100);
});
$(".ui-slider-handle").on("focus", function () {
clearTimeout(sliderTimeout);
});
Here is the full demo of the code in action. It does much more than demonstrate this, but if you examine the behavior of focusing/blur on the "margin" input, you will see that if you blur the margin input, the slider hides, but if you click on the slider, it cancels the hide and stays shown. It's the exact same concept, just a slightly different application.
Here, I did the thing.
https://jsfiddle.net/kowmLf2a/1/
In the blur event I target the related target. See if that related target is the item that I don't want to blur with. If it is then return false.
Code for reference:
$('#input').blur(function(event){
if($(event.relatedTarget).is('#bt2')){
return false;
}
alert($(this).val());
});

Avoid click triggering focusout

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

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.

how to apply function to each checkbox on page?

I am trying to apply a function to every checkbox on a page that shows/hides <div class="selectlist"> depending on if the checkbox is checked, this function makes all the <div class="selectlist"> on the page toggle
$("input[type=checkbox]").live('change', function() {
if ($(this).is(':checked') == false) {
$('#selectlist').hide();
} else {
$('#selectlist').show();
}
});
I tried the jquery each function like this but that doesnt seem to work
$.each($("input[type=checkbox]").live('change', function() {
if ($(this).is(':checked') == false) {
$('#selectlist').hide();
} else {
$('#selectlist').show();
}
}));
I know its possible to this by using a class instead of input[type=checkbox] but I want to avoid doing that
How can I make jquery change the behavior of the checkbox the user clicks?
If you're trying to bind an event handler to all elements verifying input[type=checkbox], simply do
$(document).on('change', "input[type=checkbox]", function() {
if (!this.checked) {
$('#selectlist').hide();
} else {
$('#selectlist').show();
}
});
No need to use each there : most jQuery functions work if the jQuery set contains more than one element.
Note that I use on there instead of live : after having been deprecated for a long time, live has been removed from recent versions of jQuery.
EDIT : discussion in comments below lead to this code :
$(document).on('change', "input[type=checkbox]", function() {
$(this).next().toggle(this.checked);
});
$(document).on('change', 'input[type=checkbox]', function() {
$('#selectlist').toggle(this.checked);
});
ID's are uniqe, and there is no "all the <div id="selectlist"> on the page toggle", there can be only one? Use a class instead, and show us what the markup looks like !

Categories

Resources