1

Basically I have this problem. I have an accordion that toggles one heading open at a time and I am having a problem adding in the open/close image that sits to the right of the heading.

I have it so far so that once you click a heading it removes the 'open' image and toggles another class for the 'close' image. Now I need to basically swap out these classes again so that if you toggle another heading it removes the other image and goes back to the original.

Here is the code I am using.

JavaScript

<SCRIPT>
    $("#accordion > li").click(function () {
        $("#accordian li").removeClass("faq-header");
        $(this).addClass("faq-header2");
        if (false == $(this).next().is(':visible')) {
            $('#accordion > ul').slideUp(250);
            $('#accordion > ul').addClass('faq-header');
            $(this).removeClass("faq-header");
        }
        $(this).next().slideToggle(300);
    });

    $('#accordion > ul:eq(0)').show();
</SCRIPT>

CSS

#accordion {
    list-style: none;
    margin-left:-38px;
}
#accordion ul:eq {
    background-image:url(../img/faq-open.gif);
    background-repeat:no-repeat;
    background-position:right;
    padding-right:20px;
}
#accordion li{
    display: block;
    background-color: #FFF;
    font-weight: bold;
    cursor: pointer;
}
.faq-header {
    text-align:left;
    background-image:url(../img/faq-close.gif);
    background-repeat:no-repeat;
    background-position:right;
    margin-right:20px;
}
.faq-header2 {
    text-align:left;
    background-image:url(../img/faq-open.gif);
    background-repeat:no-repeat;
    background-position:right;
    margin-right:20px;
}
#accordion ul {
    list-style: none;
    display: none;
}
#accordion ul li{
    font-weight: normal;
    cursor: auto;
    background-color: #fff;
    border-bottom:1px solid #999;
    margin-left:-38px !important;
}

I have removed one class and added another class as you can see $("#accordian li").removeClass("faq-header"); and added the following $(this).addClass("faq-header2");

But I need to now remove .faq-header2 and add back .faq-header after it is no longer the section selected. It doesn't seem too hard to me but i just can't figure out how to code it. Should be a basic if function I would think...

3
  • 1
    jquery has a really cool plugin for accordions...why make your own when the code already exists? Commented Jul 10, 2012 at 4:04
  • Yea i have already incorporated an accordion plugin but i can't find one that toggles different images if it is open/closed. This is why i am resorting to altering the one i have Commented Jul 10, 2012 at 4:06
  • Also this is totally cross browser compatible and i haven't found a bug with it yet as i have used it in the past but not with a switch toggle. Commented Jul 10, 2012 at 4:07

2 Answers 2

4

The jQuery UI accordion is a well proven cross browser widget, and does images on open and close (by default on the left, but one change of CSS will put them on the right)

as per here

if you don't won't to use it, I would persue an option with toggleClass, here

EDIT

Thanks for posting your HTML, I didn't necessarily mean the whole page, just the HTML for you accordion functionality, but hey thats cool

First point though, your HTML seems a bit heavy for just doing an accordion. Its also not entirely valid to put a ul inside a ul (they tend to go inside li, as in a drop down menu style). Further more it doesn't seem to be much point in all those ul and li as each ul only has one li anyway, just seems like a lot more tags than you would really need. ul and li tend to come with a lot of default styling (bullet points, margins, padding, indents etc), which can mean a lot more CSS than need to make them display how you want. I would have gone with a simpler structure, makes it easier to write your jQuery. A bit more like this

<div id="accordion">
    <h3>First header</h3>
    <div>First content</div>
    <h3>Second header</h3>
    <div>Second content</div>
</div>

Anyway, that was just a comment from my experience. To your problem at hand, this worked for me

    $("#accordion > li").click(function () {              
            var self = $(this);
            self.next('ul').slideToggle(300, function () {
                if ($(this).is(':visible')) {
                    self.removeClass('faq-header').addClass('faq-header2')
                }
                else {
                    self.removeClass('faq-header2').addClass('faq-header')
                }
            });
            self.siblings().removeClass('faq-header2').addClass('faq-header').next('ul').slideUp(250);
        });

toggleClass, although useful, in your circumstance as to how you want classes to be added and removed, may not be as useful as I would have thought

Sign up to request clarification or add additional context in comments.

5 Comments

Hi OJay, Thank you for that it is a great help. I originally was using the jQuery UI accordion but it messed with other functions i have on the page as i have a 'jQuery lightbox', a hover over drop down menu and login functions also within the same page so had to go with a bit more of a 'lightweight' model unfortunately... I will try some more with the 'toggle' between classes function but aren't having luck so far. I have also tried appending classes but to no avail.
Cool, if you are still having trouble, put your HTML code up as well, as some of the things your doing in the jQuery seem a bit strange to me, but without the HTML I can't really say
Yea no worries thanks again. I will have to strip alot of the content because i can't show my client to everyone so that will take a little time sorry.
It isn't showing everything correctly but you get the idea of what i am trying to do. Has alot of features as the client wants... Rounded corners, pop-up login areas, dropdown hover menu, and on other pages of the site that i have got working great is a pagination feature and google integrated search as well as a rotating carousel on the main page. It is a very nice looking site once together.
<script type="text/javascript"> $(document).ready(function() { $("#firstpane p.menu_head").click(function() { $(this).css({backgroundImage:"url(img/faq-open.gif)"}).next("div.menu_body").slideToggle(300).siblings("div.menu_body").slideUp("slow"); $(this).siblings().css({backgroundImage:"url(img/faq-close.gif)"}); }); $("#secondpane p.menu_head").mouseover(function() { $(this).css({backgroundImage:"url(img/faq-open.gif)"}).next("div.menu_body").slideDown(500).siblings("div.menu_body").slideUp("slow"); $(this).siblings().css({backgroundImage:"url(img/faq-close.gif)"}); }); }); </script>
0

I think that toggle() function is a bit not intuitive. I usually use my pwn method replaceClass() to do as you want:

void replaceClass(Object classList, String surrogateClass, String classToReplace);

defined as follow

function replaceClass(elementClassList, firstClass, secondClass) {
 if(elementClassList.contains(firstClass)){
 {
  elementClassList.remove(firstClass);
elementClassList.add(secondClass);
}
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.