disable a link after it's selected - javascript

when i click on link it gets a class named selected after it gets this class it needs to be disabled until it loses the class "selected" but it can't affect other li without class or with class "none"
function abrePlanta(idPlanta, desc, image){
h = screen.height;
if ($('li').hasClass("selected")) {
return false;
}
$('#image_preview').html('<img src="../interface_test/images/loading.gif" />');
$('ul li.selected').removeClass('selected').addClass('none');
$(this).closest('li').addClass('selected').removeAttr("disabled");
if(h >= 960){
size = 100;
} else if(h < 960){
size = 90;
}
$.get('2.php', { id_planta: idPlanta, size: size }, function(img){
$('#image_preview').html(img);
});
$('#description').html(desc);
$("#imagezoom").attr("src", "../../images/plantas/sso/" + image);
return false;
}
<li></li>
and it doesn't work event.preventDefault
i'm using onclick with a function

hard to tell without seeing more of your code, but at a glance
Change:
if($(this).hasclass('selected')){
to
if($(this).hasClass('selected')){
capital C in hasClass
Also, based on your edit, right now you're checking all li elements in the document for the selected class with:
if ($('li').hasClass("selected")) {
return false;
}
You should just be checking the li thats wrapping the a thats clicked if I understand what you're asking. So do something like this instead(this assumes that idPlanta is a js reference to the link that is clicked which is what it looks like you're trying, but can't be certain because your code didn't compile in a js fiddle when I tried to build it),
if ($(idPLanta).parent().hasClass("selected")) {
return false;
}

Here is a JSFiddle that may help you figure some things out...
Your problem is where you declare the function:
test2
This will call the function (which returns true/false), but it doesn't do anything with it. To cancel the event bubbling, you need to return the results of the function:
test2
This will return the "false" from the function, which will cancel the natural click event.

if($(this).hasClass('selected')){
$(this).attr("disabled","disabled");
return false;
}
else {
return true;
}
$('ul li.selected').removeClass('selected').addClass('none');
$(this).closest('li').addClass('selected').removeAttr("disabled");
<li>test</li>
<li>test2</li>

Related

jQuery Collapsible tabindex

Using jquery.collapsible.js I notice that the tabindex does not change when expanded/closed. I nearly have a solution but would appreciate it if someone could improve on this piece of code as I am sure there is a better way to do this.
$('.collapsible').each(function() {
$('.collapsible').on('click',function(e) {
if($('div').hasClass('collapsible collapse-open')) {
$('.collapsible.collapse-open').attr("tabIndex", 0);
} else {
$('.collapsible.collapse-close').attr("tabIndex", -1);
}
});
});
The problem is the tabindex only changes on the second click and then the 0,-1 order is wrong.
If you're just looking for a better way, and your solution already works, you could simplify it with this. You don't need to loop through each .collapsible with the each function just to add the click event handler.
$(".collapsible").on('click', function (e) {
var self = $(this);
var tabIndex = self.hasClass("collapse-open") ? 0 : -1;
self.attr("tabIndex", tabIndex);
});
This will select any element with the class collapsible, bind the click event, and then check if that element has the collapse-open class to determine which tab index to apply.
Thanks to Ihan for the more efficient script. It is working now I just had to change the default class from 'collapse-open' to 'collapse-close'.
$(".collapsible").on('click', function (e) {
var self = $(this);
var tabIndex = self.hasClass("collapse-close") ? 0 : -1;
self.attr("tabIndex", tabIndex);
});

Double click fires event twice

I am working on a quiz project where a user selects a multiple choice answer (radio button) and then click a link to proceed to the next question. If a radio button has not been selected, the link cannot be clicked. Once a radio button is selected and a link clicked, the next question is pulled from a MySQL database using AJAX.
The issue I am having is that if a user double clicks the link, a question is skipped. So if you are on question 1 and double click the link, question 3 is loaded instead of 2.
Is there a way in jQuery to make an event fire only once, if a link is single or double clicked?
Thanks
$('#next-question-click').on( "click", function(){
if ($('[name="radio-question"]').is(':checked')){
var answer = $(".question-content ul li input:checked + label").text();
question_number = question_number + 1;
if(question_number<100){
next_question(question_number);
}
} else {
$("#error-text").html('Please select an answer.');
}
return false;
})
.on("dblclick", function(e){
e.preventDefault(); //cancel system double-click event
});
You just need to gate the execution by adding a class. So your code will only execute if the current question is not being changed.
Now, ideally you should remove the active class from $('#next-question-click') in the success function of your ajax call to load the new question to ensure the function will only execute after the new question has been loaded
The advantage of adding a class is so that it will not pollute the global variable space, as to what class to add, it is up to you. I just used active as an example
$('#next-question-click').on("click", function () {
if (!$(this).hasClass('active')) {
if ($('[name="radio-question"]').is(':checked')) {
$(this).addClass('active');
var answer = $(".question-content ul li input:checked + label").text();
question_number++;
if (question_number < 100) {
next_question(question_number);
$(this).removeClass('active'); // this should go into the success/complete function of the ajax call
}
} else {
$("#error-text").html('Please select an answer.');
}
}
return false;
});
The jQuery.one() function is what you are looking for.
Instead of unbinding and rebinding events, I usually use a variable as a flag.
Something like this...
var working = false;
$('#next-question-click').on( "click", function(){
if (working) return false; //Dont do anything, basically.
if ($('[name="radio-question"]').is(':checked')){
var answer = $(".question-content ul li input:checked + label").text();
question_number = question_number + 1;
if(question_number<100){
working = true;
next_question(question_number);
}
} else {
$("#error-text").html('Please select an answer.');
}
return false;
})
And, on the next_question function, after the next question is loaded and ready to be answered, you would add working = false;

How Store and Disable Event of another element Temporary

I am looking for a way to manage the events. I have a hover function for element A, and click function for element B. I want to disable A`s hover function temporary while the second click of B.
I am looking for a way that not necessary to rewrite the hole function of A inside of B. Something very simply just like "Store and Disable Event, Call Stored Function"
I found some technique like .data('events') and console.log. I tired but failed, or maybe I wrote them in a wrong way.
Please help and advice!
$(A).hover();
$(b).click(
if($.hasData($(A)[0])){ // if A has event,
//STORE all the event A has, and disable
}else{
//ENABLE the stored event for A
}
);
Try this
var hoverme = function() {
alert('Hover Event Fired');
};
$('.A').hover(hoverme);
var i = 0;
$('.B').on('click', function(){
if(i%2 === 0){
// Unbind event
$('.A').off('hover');
}
else{
// Else bind the event
$('.A').hover(hoverme);
}
i++;
});
Check Fiddle
I think that what you want to do is something like this (example for JQuery 1.7.2):
$("#a").hover(function(){alert("test")});
$("#a")[0].active=true;
$("#b").click(function(){
if($("#a")[0].active){
$("#a")[0].storedEvents = [];
var hoverEvents = $("#a").data("events").mouseover;
jQuery.each(hoverEvents , function(key,handlerObj) {
$("#a")[0].storedEvents.push(handlerObj.handler);
});
$("#a").off('hover');
}else{
for(var i=0;i<$("#a")[0].storedEvents.length;i++){
$("#a").hover($("#a")[0].storedEvents[i]);
}
}
$("#a")[0].active = ($("#a")[0].active)==false;
});​
JSFiddle Example
But there are a couple of things that you must have in consideration:
This will only work if you add the events with JQuery, because JQuery keeps an internal track of the event handlers that have been added.
Each version of JQuery handles data("events") differently, that means that this code may not work with other version of JQuery.
I hope that this helps.
EDIT:
data("events") was an internal undocumented data structure used in JQuery 1.6 and JQUery 1.7, but it has been removed in JQuery 1.8. So in JQuery 1.8 the only way to access the events data is through: $._data(element, "events"). But keep in mind the advice from the JQuery documentation: this is not a supported public interface; the actual data structures may change incompatibly from version to version.
You could try having a variable that is outside the scope of functions a and b, and use that variable to trigger the action to take in function b on function a.
var state;
var a = function() {
if(!state) {
state = true;
// Add hover action and other prep. I'd create a third function to handle this.
console.log(state);
};
var b = function() {
if(state) {
state = false;
// Do unbinding of hover code with third function.
} else {
state = true;
// Do whatever else you needed to do
}
}
Without knowing more about what you're trying to do, I'd try something similar to this.
It sounds like you want to disable the click hover event for A if B is clicked.
$("body").on("hover", "#a", function(){
alert("hovering");
});
$("#b").click( function(){
$("body").off("hover", "#a", function() {
alert("removed hovering");
});
});
You can use the jQuery off method, have a look at this fiddle. http://jsfiddle.net/nKLwK/1/
Define a function to assign to hover on A element, so in b click, call unbind('hover') for A element and in second click on b element define again a function to hover, like this:
function aHover(eventObject) {
// Todo when the mouse enter object. You can use $(this) here
}
function aHoverOut(eventObject) {
// Todo when the mouse leave the object. You can use $(this) here
}
$(A).hover(aHover, aHoverOut);
// ...
$(b).click(function(eventObject) {
if($.hasData($(A)[0])){ // if A has event,
$(A).unbind('mouseenter mouseleave'); // This is because not a event hover, jQuery convert the element.hover(hoverIn, hoverOut) in element.bind('mouseenter', hoverIn) and element.bind('mouseleave', hoverOut)
}else{
$(A).hover(aHover, aHoverOut);
}
});
There are provably better ways to do it, but this works fine, on document ready do this:
$("#a")[0].active=false;
$("#b").click(function(){
$("#a")[0].active = ($("#a")[0].active)==false;
if($("#a")[0].active){
$("#a").hover(function(){alert("test")});
}else{
$("#a").off('hover');
}
});
JSFiddle example
You can use .off function from jQuery to unbind the hover on your "a" element.
function hoverA() {
alert('I\'m on hover');
}
$('#a').hover( hoverA );
var active = true;
$('#b').on('click', function(){
if(active){
$('#a').off('hover');
active = false;
} else{
$('#a').hover(hoverA);
active = true;
}
});
Live demo available here : http://codepen.io/joe/pen/wblpC

How to call a function with jQuery blur UNLESS clicking on a link?

I have a small jQuery script:
$('.field').blur(function() {
$(this).next().children().hide();
});
The children that is hidden contains some links. This makes it impossible to click the links (because they get hidden). What is an appropriate solution to this?
This is as close as I have got:
$('.field').blur(function() {
$('*').not('.adress').click(function(e) {
foo = $(this).data('events').click;
if(foo.length <= 1) {
// $(this).next('.spacer').children().removeClass("visible");
}
$(this).unbind(e);
});
});
The uncommented line is suppose to refer to the field that is blurred, but it doesn't seem to work. Any suggestions?
You can give it a slight delay, like this:
$('.field').blur(function() {
var kids = $(this).next().children();
setTimeout(function() { kids.hide(); }, 10);
});
This gives you time to click before those child links go away.
This is how I ended up doing it:
var curFocus;
$(document).delegate('*','mousedown', function(){
if ((this != curFocus) && // don't bother if this was the previous active element
($(curFocus).is('.field')) && // if it was a .field that was blurred
!($(this).is('.adress'))
) {
$('.' + $(curFocus).attr("id")).removeClass("visible"); // take action based on the blurred element
}
curFocus = this; // log the newly focussed element for the next event
});
I believe you can use .not('a') in this situation:
$('.field').not('a').blur(function() {
$(this).next().children().hide();
});
This isn't tested, so I am not sure if this will work or not.

Toggle State Incorrect in jQuery

I am using jQuery to show / hide lists, but it takes two clicks on a link instead of just one to show the list. Any help?
jQuery.showList = function(object) {
object.toggle(function(){
object.html("▾");
object.siblings("ul.utlist").show("fast");
}, function(){
object.html("▸");
object.siblings("ul.utlist").hide("fast");
});
}
$(document).ready(function() {
$("#page").click(function (e){
e.preventDefault();
var target = $(e.target);
var class = target.attr("class");
if(class == "list")
$.showList(target);
});
});
It's probably because toggle thinks the object is already visible, and executes the 'hide' clause.
edit:
Eh.. quite circular logic; how else would a user be able to click on it :-)
PS. You changed the logic from is-object-visible? to is-list-visible? in your own reply.
Not sure if this will fix everything but stop using reserved keywords.
Change variable class to something like c. And Change object variable to at least obj.
Doing the following worked well
jQuery.showList = function(obj) {
var list = obj.siblings("ul.utlist");
if(list.is(":visible")){
obj.html("▸");
list.hide("fast");
} else {
obj.html("▾");
list.show("fast");
}
}

Categories