Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

My JavaScript (with a little jQuery) isn't doing quite what I want it to do. Can you help me figure out why?

I'd like it to be that when you click a category name its info slides down and if you click it again it slides up. If info is already showing and you click a different category, the info showing slides up, and then the new info slides down. Right now the new info just slides up unless its the first category, in which case it slides down.

document.addEventListener('DOMContentLoaded', () => {

const catNameDiv = document.getElementById('cat-name-div'); // one div holds all the category names with different classes
const catInfoDiv = document.getElementsByClassName('cat-info-div'); // this is a collection of divs, with ids, holding info 

catNameDiv.addEventListener('click', (e) => {
    const catName = e.target; // category name that was clicked
    const catClass = catName.className; // the class of the category name that was clicked
    const catInfo = document.getElementById(catClass); // div with an id that matches the class of the category name

    for (let i = 0; i < catInfoDiv.length; i += 1) {
        // catInfoDiv is a collection of ALL the divs holding info.
        // info is each div when it goes through the loop
        let info = catInfoDiv[i];
        if (info === catInfo) {
            // catInfo is the one div with info for the category clicked.
            $(catInfo).slideToggle();
        } else if (info != catInfo) {
            $(info).slideUp();
        }; 
    };
});

});

This is some of the html

    <div class="name-div-holder">
        <div class="categories" id="cat-name-div"><!-- flex container -->
            <h5 class="signature">Signature Cocktails</h5>
            <h5 class="classic">Classic Cocktails</h5>
            <h5 class="white-wine">White Wines</h5>
            <h5 class="red-wine">Red Wines</h5>
            <h5 class="lagers-ales">Lagers &amp; Ales</h5>
        </div>
    </div>
    <div class="info-div-holder">
        <div class="cat-info-div" id="signature">
            <p>There's info here</p>
        </div>  
        <div class="cat-info-div" id="classic"> 
            <p>There's info here</p>
        </div>
        <div class="cat-info-div" id="white-wine">
            <p>There's info here</p>
        </div>
        <div class="cat-info-div" id="red-wine">
            <p>There's info here</p>
        </div>
        <div class="cat-info-div" id="lagers-ales">
            <p>There's info here</p>
        </div>
  </div> 
Steven Parker
Steven Parker
243,656 Points

What does the HTML look like that goes with this?

1 Answer

Steven Parker
Steven Parker
243,656 Points

The error seems to be in the HTML where after the first "info" area there is an extra open <div> tag instead of a closing </div> tag. After fixing that it seems to operate as you intended.

Personally, I found it a bit more intuitive to replace "slideToggle" with "slideDown" to be sure there's always something visible, but that's up to you.

I was trying to only put in some of the html, and I didn't cut and paste very well. But I added more and updated. The trouble I've been having with slideDown instead of slideToggle is that I need the info to slide up again if the same name is clicked as matches the info already showing.

Steven Parker
Steven Parker
243,656 Points

Using the revised HTML, and after some text is added to the info areas so the effect can be seen, it seems to operate as you intended.

I understand the effect you're after, and the code seems to do just that. I just happen to have a personal preference for having the last selected item always displayed. :wink: