This question already has answers here:
Jquery Toggle two function not work in 1.10.1
(7 answers)
Closed 9 years ago.
I would like to update my website to jQuery 1.10 but I use a function with the deprecated toggle().
I remember, I was having a hard time to make this function works in first time, does it exists a function that could replace the toggle() without changing all the code.
I am not a jQuery expert and help would be appreciated.
css:
fieldset.collapsed * {
display: none;
}
fieldset.collapsed h2, fieldset.collapsed {
display: block !important;
}
fieldset.collapsed h2 {
background-image: url(../img/nav-bg.gif);
background-position: bottom left;
color: #999;
}
fieldset.collapsed .collapse-toggle {
background: transparent;
display: inline !important;
}
jquery:
var sPath=window.location.pathname;
(function ($) {
$(document).ready(function () {
function show () { // Show
$(this).text(gettext("Hide"))
.closest("fieldset")
.removeClass("collapsed")
.trigger("show.fieldset", [$(this).attr("id")]);
window.localStorage.setItem($(this).attr("id"), true);
}
function hide () { // Hide
$(this).text(gettext("Show"))
.closest("fieldset")
.addClass("collapsed")
.trigger("hide.fieldset", [$(this).attr("id")]);
window.localStorage.removeItem($(this).attr("id"))
return false;
}
// Add anchor tag for Show/Hide link
$("fieldset.collapse").each(function (i, elem) {
// Don't hide if fields in this fieldset have errors
key = 'fieldsetcollapser' + i + sPath;
if (typeof (window.localStorage) != 'undefined') {
var item = $(elem)
.addClass("collapsed")
.find("h2")
.first()
.append(' (<a id=' +
key +
' " class="collapse-toggle" href="#">' +
gettext("Show") +
'</a>)'
).find('a');
if (window.localStorage.getItem(key)) {
//alert('show')
show.apply(item);
$(item).toggle(hide, show);
}else {
if ($("ul.errorlist").length >0) {
//alert('yo show')
show.apply(item);
$(item).toggle(hide, show);
}else{
$(item).toggle(show, hide);
//alert("hide")
}
}
} else {
throw "window.localStorage, not defined";
}
});
});
EDITED:See how it works here (working with jQuery 1.6)
The reason that the .toggle() function was deprecated was because of confusion just like this!
What's going on is that your code is calling (on an alternating basis) your own internal "hide" and "show" functions. The .toggle(hide,show) call takes care of that for you.
However, inside of your hide() and show() functions, you're not actually hiding or showing anything. What you're doing is adding or removing a class, which may or may not hide or show something.
The solution
The only solution to alternatively call these two functions is to change the 'click' event each time one of those functions is called.
At the bottom of your show() code, you need to add:
$(this).one("click", hide);
At the bottom of your hide() code, you need to add:
$(this).one("click", show);
Finally, you need to replace your calls to .toggle() with these calls:
$(item).one("click", hide); // replaces $(item).toggle(hide,show);
$(item).one("click", show); // replaces $(item).toggle(show,hide);
Why not .is(":visible")?
Quite simply, the class that you are adding/removing is the "collapsed" class. This class does not actually hide the $(item). Because of this the $(this).is(":visible") will always be true!
Clearly, that won't work.
Here is a demonstration that illustrates the point: JSFiddle
Fully in code
For those who like to read code instead of words:
function firstEvent() { // e.g. "hide"
//First event code
$(item).one("click", secondEvent);
}
function secondEvent() { // e.g. "show"
//Second event code
$(item).one("click", firstEvent);
}
$(item).one("click", firstEvent); // replaces $(item).toggle(firstEvent, secondEvent);
I would replace your instances with an if statement
$(item).click(function(){
if ($(this).is(':visible')) {
$(this).hide();
}
else {
$(this).show();
}
});
Here is a demo of my above code working using a p element and an img.
DEMO http://jsfiddle.net/kevinPHPkevin/8TFFx/
You could also do it by using CSS/Jquery
$('p').click(function(){
if ($('img').is(':visible')) {
$('img').css("display","none");
}
else {
$('img').css("display","block");
}
});
Related
First time posting, I wouldn't call my Javascript knowledge even rudimentary so please forgive my ignorance.
I found a snippet of code here last week (shown in first code example) and I'm trying to get a tweaked version of the same to work as well alongside.
Both are loaded into the footer together as shown below, but the one that is first works, the one that follows doesn't run
I've swapped their order in the footer and confirmed that only the first call functions correctly, I think it's just something conflicting, but I don't know what.
// First function call
$(function() {
var items = $('#v-nav>ul>li').each(function() {
$(this).click(function() {
//remove previous class and add it to clicked tab
items.removeClass('current');
$(this).addClass('current');
//hide all content divs and show current one
$('#v-nav>div.tab-content').hide().eq(items.index($(this))).show();
window.location.hash = $(this).attr('tab');
});
});
if (location.hash) {
showTab(location.hash);
} else {
showTab("tab1");
}
function showTab(tab) {
$("#v-nav ul li:[tab*=" + tab + "]").click();
}
// Bind the event hashchange, using jquery-hashchange-plugin
$(window).hashchange(function() {
showTab(location.hash.replace("#", ""));
})
// Trigger the event hashchange on page load, using jquery-hashchange-plugin
$(window).hashchange();
});
// Second function call
$(function() {
var items = $('#h-nav>ul>li').each(function() {
$(this).click(function() {
//remove previous class and add it to clicked tab
items.removeClass('current');
$(this).addClass('current');
//hide all content divs and show current one
$('#h-nav>div.tab-content').hide().eq(items.index($(this))).show();
window.location.hash = $(this).attr('tab');
});
});
if (location.hash) {
showTab(location.hash);
} else {
showTab("tab1");
}
function showTab(tab) {
$("#h-nav ul li:[tab*=" + tab + "]").click();
}
// Bind the event hashchange, using jquery-hashchange-plugin
$(window).hashchange(function() {
showTab(location.hash.replace("#", ""));
})
// Trigger the event hashchange on page load, using jquery-hashchange-plugin
$(window).hashchange();
});
https://codepen.io/adouglas1880/pen/RzMqBV
I am trying to understand how javascript (jquery in this case) if statements work. I thought i understood but i don't fully get some things. Please see the code below. Why is it when i click on the element with the class of "cat" that it does not remove the class of "black" and add the class of "red".
$(function() {
var cat = true;
$( ".cat" ).click(function() {
cat = false;
});
if (cat === true) {
$('.cat').removeClass('red').addClass('black');
} else {
$('.cat').removeClass('black').addClass('red');
}
});
i know there is probably a very simple answer to this but i'm just learning so any help would be appreciated, thanks in advance.
Toggle the value of cat and put the if block inside the function that you want to bind with the event 'click':
$(".cat").click(function() {
cat = !cat;
if (cat === true) {
$('.cat').removeClass('red').addClass('black');
} else {
$('.cat').removeClass('black').addClass('red');
}
});
Edit: Simpler way to do this is to use .toggleClass():
$(".cat").click(function() {
$(this).toggleClass('red black');
});
If you want to check on click, put the if inside the click event. The reason why your solution doesn't work is because you attach a listener to the element, but you immediately do a check. The check doesn't happen every time the user clicks, just once. You must put it in the listener's callback function so it executes every time the element is clicked:
$(function() {
$(".cat").click(function() {
$(".cat").toggleClass("black red");
});
});
How this works is it attaches a click event to .cat and, on click, toggles the classes black and red. This completely gets rid of the checking because that isn't necessary. Just toggle the classes on click. Also, no need to repeat the selector, just use this. Here's a snippet:
$(function() {
$(".cat").click(function() {
$(this).toggleClass("black red");
});
});
.black {
color: black;
}
.red {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cat red">Test</div>
Your code is not removing class black and adding class red because your if(){}else{} code block running when your page is loading. When you are clicking the cat class it is only assigning the value of cat variable to false. since your if else code block is out of your click function that is why it is not executing again. and that is why it is not working. To work your code place your if else code block in the click function like this:
$( ".cat" ).click(function() {
cat = false;
if (cat === true) {
$('.cat').removeClass('red').addClass('black');
} else {
$('.cat').removeClass('black').addClass('red');
};
});
recently I wrote one few lines of js in order to check the DOM structure and add "in" class in case user clicked on link. Now I need to use has property but I dont know how its used. Here is code:
$(document).on('click', '.collapse-all > a', function () {
var $collapseList = $(this).closest('#main-content').find('.collapse-list'),
$container = $collapseList.find('.collapse').removeAttr('style'),
$collapsed = $collapseList.find('.mehr-pfeil');
if ($container.filter('.in').length > 0) {
$container.removeClass('in');
} else {
$container.addClass('in');
}
});
$(function () {
$('.collapse-all > a').click();
});
// here is my try to check the DOM and add another class on <a> element
$(function () {
$container.hasClass('in') {
if ($container.filter('.in').length > 0) {
$collapsed.addClass('mehr-pfeil-active');
} else {
$collapsed.removeClass('mehr-pfeil-active');
}
}
});
So right now everything worked but when I tried to check if js has gave in class to .collapse then my code breaks. Can anyone tell me where I've made mistake
hasClass() returns a bool so your function may check something like this
if($container.hasClass('in')) {
...
}
As noted by TheBlueAussie, your $container is also not in the scope of your ready function.
A quick fix would be to global the variable like so
var $container;
$(document).on('click', '.collapse-all > a', function () {
var $collapseList = $(this).closest('#main-content').find('.collapse-list'),
$collapsed = $collapseList.find('.mehr-pfeil');
$container = $collapseList.find('.collapse').removeAttr('style');
...
}
There are 2 problems in your code
1,$container is not in the scope of your class checking function.
2, The way you used hasClass method is wrong
It will return true or false. So you can check it inside an if condition.
var $collapseList = $(this).closest('#main-content').find('.collapse-list');
$container = $collapseList.find('.collapse');
if ($container.hasClass('in')) {
$collapsed.addClass('mehr-pfeil-active');
} else {
$collapsed.removeClass('mehr-pfeil-active');
}
take a look at
.hasClass() to check if element has a class.
you can use it in a if and than addClass
if($('.class').hasClass('className'))
{
$('.class').addClass('xy');
//or
$('.class').removeClass('className');
//and so on
//.class could be #id as well
}
You should move the hasClass statement to a condition start since this method returns a boolean (true/false) value:
// here is my try to check the DOM and add another class on <a> element
$(function () {
if ($container.hasClass('in')) {
if ($container.filter('.in').length > 0) {
$collapsed.addClass('mehr-pfeil-active');
} else {
$collapsed.removeClass('mehr-pfeil-active');
}
}
});
You should also declare the $container variable inside this function or move its initialization to be a global one.
try this
$container.hasClass('in');
or if you want to toggle class
$container.toggleClass('in')
I'm trying to execute a function twice, and I can't figure out what I'm doing wrong. JSFiddle here: http://jsfiddle.net/g6PLu/3/
Javascript
function truncate() {
$(this).addClass('closed').children().slice(0,2).show().find('.truncate').show();
}
$('div').each(truncate);
$('.truncate').click(function() {
if ($(this).parent().hasClass('closed')) {
$(this).parent().removeClass('closed').addClass('open').children().show();
}
else if ($(this).parent().hasClass('open')) {
$(this).parent().removeClass('open').addClass('closed');
$('div').each(truncate);
$(this).show();
}
});
The problem is on line 15, where I call $('div').each(truncate); the second time. For some reason it doesn't seem to be executing. Any ideas?
I think you are overcomplicating a simple task. I'd take advantage of the classes to show/hide stuff with CSS (you're adding the classes but not using them!).
Check out this simpler version:
Relevant CSS
.closed p { display: none; }
.closed p:nth-child(2) { display: block; }
JS
$('div').addClass('closed');
$('.truncate').click(function() {
$(this).closest('div').toggleClass('closed');
});
http://jsfiddle.net/g6PLu/9/
When you call show, the <p> changes to <p style="display: block; "> that's why, you need to call hide or remove that style part
is this the spected behavior?
else if ($(this).parent().hasClass('open')) {
$(this).parent().removeClass('open').addClass('closed').children().hide();
$('div').each(truncate);
$(this).show();
}
<div class="example">
Test
</div>
$('.example').click(function(){
$(this).css('color','red');
});
When the code above get's clicked, it will apply the .css. Now what I need is for another bit of code (let's say $(this).css('color','blue');) to be applied, replacing the previous code when .example gets clicked a second time.
I've searched for this and askers seem to only need .show/.hide events which can be substituted with .toggle, which is obviously not the case here.
Since you may have many instances of class example, simply maintaining a state using a single variable is not feasible, what you can do is to maintain the state of each instance of example within itself:
Define two css classes
.example { background:blue }
.example.red { background:red }
Then your click method:
$('.example').click(function(){
$(this).toggleClass('red');
});
If you prefer not to define new css classes, you can use data(), to make sure that the state is exclusive within each .example, this is useful if you have many instances of .example
$('.example').click(function() {
var color = $(this).data('color');
if(color != 'blue') {
$(this).css('color', 'blue');
$(this).data('color', 'blue');
} else {
$(this).css('color', 'red');
$(this).data('color', 'red');
}
});
http://api.jquery.com/data/
Something like this would work to toggle between 2 colours (or styles).
$('.example').click(function(){
if($(this).css('color') == "red")
{
$(this).css('color','blue');
}
else
{
$(this).css('color','red');
}
});
<div class="example">
Test
</div>
just maintain a bool and you are done..
var isRed=false;
$('.example').click(function(){
if(isRed)
{
$(this).css('color','blue');
isRed=false;
}
else
{
$(this).css('color','red');
isRed=true;
}
});
Use addClass and removeClass
.blueColor
{
background-color: blue;
}
.redColor
{
background-color: red;
}
And use in your javascript the addClass and removeClass functions:
<script>
$(document).ready(function(){
$(".example").keypress(function() {
if($(".example").val().length > 0)
{
$(".example").addClass("redColor");
}
else {
if($(".example").val().length == 0)
{
$(".example").addClass("blueColor");
$(".example").removeClass("redColor");
}
}
});
});
</script>
I guess you need something more generic about click event exactly so I'd suggest you to use data method to leave the flags
$('.example').click(function() {
if (!$(this).data("custom-even")) {
// odd execution
$(this).data("custom-even", true)
} else {
// even execution
$(this).data("custom-even", false)
}
});
$('.example').click(function(){
var theExample = $(this);
if(theExample.hasClass("clicked")){
theExample.css('color','blue').removeClass("clicked");
}else{
theExample.css('color','red').addClass("clicked");
}
});
http://jsfiddle.net/SnDgh/
Hiya Try this with toggle :)) http://jsfiddle.net/FVXAZ/
SO you can use toggle with your css and every second click will have the vice-a-versa affect. :)
Code
$(function() {
$('.example').toggle(function() {
$(this).css('color','red');
}, function() {
$(this).css('color','blue');
});
});
Have a nice man man, cheers!
Try this:
$('.example').click(function(){
if($('.example').data('isAlreadyClicked')=='true')
{
$(this).css('color','blue');
$('.example').data('isAlreadyClicked','false')
}
else
{
$(this).css('color','red');
$('.example').data('isAlreadyClicked','true')
}
});
Use the one method to handle one-time event binding is a good choice, however this solution will stop all events binded after this code, it may cause inconsistency.
$('.example')
.one('click', function(e) {
e.stopImmediagePropagation();
})
.on('click', function() {
$(this).css('color', blue');
});
Lot of answers all defining a single solution.
Basically, there are two ways that you should use. The other ways mentionned are either unperformant or unsemantic (using data for this kind of solution is overkill). Here are the two ways you may use:
// Toggle a class 'red' defined in your stylesheet
$('.example').on('click', function() {
$(this).toggleClass('red')
})
// Toggle the color with an "if" check
$('.example').on('click', function() {
if (this.style.color === 'red') { // using jQuery is not required
this.style.color === 'blue'
}
else {
this.style.color === 'red'
}
})
You can write:
$('#id').toggle(function() {
$('.css').css('color','red');}
,function() { /////////the second click
$('.css').css('color','blue');}
);