gloriousCatnip
gloriousCatnip

Reputation: 431

How can I get jQuery to toggle a class with fadeToggle?

I am using fadeToggle() to toggle between the visibilty of the chosen elements. When my page is loaded, all the given elements are given the class 'invisible' (which gives them the CSS property display: none;).

I want to be able to toggle this class name, because another function I use to toggle the visibility/invisiblity of all the elements requires it to be able to find elements with the property invisible.

This is my current code:

  var sections = $('.ovelseSeksjon');
  var title = sections.find("h1")
  var assignments = sections.find(".ovelseInnhold");
  var plusMinus = sections.find(".fa");
  var toggleAll = $("#mainText").find(".toggleall");

  // Hide all assignments at page load
  assignments.addClass("invisible");

  // Toggle the invisible class when the title is clicked
  title.on('click', function() {
    // To capture the scope of this, it will be something else in setTimeout.
    $(this).parent().find(".invisible").fadeToggle("fast", "linear");
  });

  toggleAll.on("click", function() {
    console.log($(this).attr("class"));
    if($(this).hasClass("open")) {
      assignments.filter(".invisible").removeClass("invisible");
    }
    if($(this).hasClass("close")) {
      assignments.not(".invisible").addClass("invisible");
    }
  });

This works, but not in the way I want it to work. This simply adds a new CSS property display: block, that only overrides the previous invisibility value. The invisible class still remains. What can I do to achieve my desired effect? If there is no easy way to remove the invisible class, how can I update my toggleAll to work properly again? (It can't hide the elements. Even though it indeed removes the invisible property, the display: block is still there and it does not get removed by my toggleAll).

Thanks!

Upvotes: 2

Views: 1288

Answers (2)

zer00ne
zer00ne

Reputation: 43870

I started the HTML before you posted it so bear that in mind. The details are commented in the Snippet.

SNIPPET

var txt = $('#mainText');
var sec = $('.section');
var hdr = $("h1");
var sub = $(".subSection");
var ico = $(".fa");
var all = $(".toggleAll");

sub.addClass("inv");

// Click a title to...
hdr.on('click', function() {
  
  /*
  |Select this title's siblings that follow afterwards
  |and switch their class between .inv and .vis
  */
  $(this).nextAll(sub).toggleClass('inv vis');
});

// Click the .toggleAll button...
all.on("click", function(e) {
  
  // Prevents anchor from jumping
  e.preventDefault();
  
  // Switch between plus and minus icons
  ico.toggleClass('fa-plus fa-minus');
  
  //Switch `.toggleAll` classes
  $(this).toggleClass('close open');
  
  // if this button ends up with class .close...
  if ($(this).hasClass('close')) {
    
    // remove/add = classes .vis and .inv
    sub.removeClass('vis').addClass('inv');
  } 
  else {
    
    // else vice versa
    sub.removeClass('inv').addClass('vis');
  }
});
html,
body {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
  background: #999;
}
.vis {
  display: block;
  opacity: 1;
  line-height: 1;
  width: 100%;
  transition: all 500 linear;
  color: white;
  background: black;
}
.inv {
  display: none;
  opacity: 0;
  line-height: 0;
  width: 0;
  transition: all 500 linear;
}
.close {
  background: black;
  color: yellow;
  line-height: 0;
  transition: all 1s ease-in;
}
.open {
  background: yellow;
  color: black;
  line-height: 3;
  transition: all 1s ease-out;
}
h1,
section {
  cursor: pointer;
  background: rgba(0, 0, 0, .3);
}
.toggleAll {
  width: 100%;
  padding: 15px 5px 0;
}
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css'>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<main id='mainText'>
  <a href='#/' class='toggleAll close'>
    <i class='fa fa-plus fa-2x'>ALL</i>
  </a>
  <section class='section'>
    <h1>I to IV</h1>
    <div class='subSection'>ONE</div>
    <div class='subSection'>TWO</div>
    <div class='subSection'>THREE</div>
    <div class='subSection'>FOUR</div>
  </section>
  <section class='section'>
    <h1>V to VIII</h1>
    <div class='subSection'>FIVE</div>
    <div class='subSection'>SIX</div>
    <div class='subSection'>SEVEN</div>
    <div class='subSection'>EIGHT</div>
  </section>
  <section class='section'>
    <h1>IX to XII</h1>
    <div class='subSection'>NINE</div>
    <div class='subSection'>TEN</div>
    <div class='subSection'>ELEVEN</div>
    <div class='subSection'>TWELVE</div>
  </section>
</main>

Upvotes: 1

Edmar Miyake
Edmar Miyake

Reputation: 12390

I'm not sure if this is the right hierarchy for your HTML, but here an example.

Your assignment content (.ovelseInnhold) should start with display:noneset via CSS.

var sections = $('.ovelseSeksjon');
  var title = sections.find("h1")
  var assignments = sections.find(".ovelseInnhold");
  var plusMinus = sections.find(".fa");
  var toggleAll = $("#mainText").find(".toggleall");


  // Toggle the invisible class when the title is clicked
  title.on('click', function() {
    // To capture the scope of this, it will be something else in setTimeout.
    $(this).parent().find(".ovelseInnhold").fadeToggle("fast", "linear");
  });

  toggleAll.on("click", function() {
    $('.ovelseInnhold').fadeToggle("fast", "linear");
  });
.ovelseInnhold { 
  display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="mainText">
  <div class="toggleall">Toggle All</div>
</div>


<section class="ovelseSeksjon">
  <h1>Title 1</h1>
  <div class="ovelseInnhold">
    Assignments
  </div>
</section>


<section class="ovelseSeksjon">
  <h1>Title 2</h1>
  <div class="ovelseInnhold">
    Assignments
  </div>
</section>

Upvotes: 1

Related Questions