30

I'm trying to modify the icons for the jQuery UI portlets. Rather than have a plus to minimize and a minus to expand, I wanted to switch them.

I've only had limited success with it where the first time to click the minus it flips to a plus, but the plus never flips to a minus. Any help on this would be much appreciated.

Here's a sample HTML:

<script src="scripts/jquery-1.3.2.js" type="text/javascript" ></script>
<script src="scripts/ui/ui.core.js" type="text/javascript"></script>
<script src="scripts/ui/ui.sortable.js" type="text/javascript"></script>

<div class="column">
    <div class="portlet">
        <div class="portlet-header">Links</div>
        <div class="portlet-content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div>
    </div>
</div>

Here's what I came up with for the jQuery:

<script type="text/javascript">
    $(function() {
        $(".column").sortable({
            connectWith: '.column'
        });

        $(".portlet").addClass("ui-widget ui-widget-content ui-helper-clearfix ui-corner-all")
        .find(".portlet-header")
            .addClass("ui-widget-header ui-corner-all")
            .prepend('<span class="ui-icon ui-icon-minusthick"></span>')
            .prepend('<span class="ui-icon ui-icon-closethick"></span>')
            .end()
        .find(".portlet-content");

        $(".portlet-header .ui-icon-minusthick").click(function() {
            $(this).removeClass("ui-icon-minusthick");
            $(this).addClass("ui-icon-plusthick");
            $(this).parents(".portlet:first").find(".portlet-content").toggle();
        });

        $(".portlet-header .ui-icon-plusthick").click(function() {
            $(this).removeClass("ui-icon-plusthick");
            $(this).addClass("ui-icon-minusthick");
            $(this).parents(".portlet:first").find(".portlet-content").toggle();
        });

        $(".portlet-header .ui-icon-closethick").click(function() {
            $(this).parents(".portlet:first").toggle();
        });

        $(".column").disableSelection();
    });
</script>


EDIT: Here's the original javascript from the jQuery UI demo site:
<script type="text/javascript">
$(function() {
    $(".column").sortable({
        connectWith: '.column'
    });

    $(".portlet").addClass("ui-widget ui-widget-content ui-helper-clearfix ui-corner-all")
        .find(".portlet-header")
            .addClass("ui-widget-header ui-corner-all")
            .prepend('<span class="ui-icon ui-icon-plusthick"></span>')
            .end()
        .find(".portlet-content");

    $(".portlet-header .ui-icon").click(function() {
        $(this).toggleClass("ui-icon-minusthick");
        $(this).parents(".portlet:first").find(".portlet-content").toggle();
    });

    $(".column").disableSelection();
});
</script>

I'm not exactly sure how they were able to get the plus and minus to toggle correctly.

CAbbott
  • 8,078
  • 4
  • 31
  • 38

5 Answers5

118

How about

$(YOUR_ELEMENT).live("EVENT_NAME", function() {
    $(".portlet-header").toggleClass("ui-icon-plus").toggleClass("ui-icon-minus");
});

Even more shorter

$(YOUR_ELEMENT).live("EVENT_NAME", function() {
    $(".portlet-header").toggleClass("ui-icon-plus ui-icon-minus");
});

EDIT

As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().


jQuery API reference

e-Learner
  • 517
  • 1
  • 4
  • 15
Bongs
  • 5,502
  • 4
  • 30
  • 50
  • 6
    I been trying to figure out how to toggle between 2 classes for almost a day now, thank god I found your answer, it solved my problem in seconds! I have a grid view switcher for a layout, when user clicks it has to add 1 class and remove the other or remove the current and replace so it's always 1 of the 2 classes. I didn't know you could link them together like that so thanks for sharing that – JasonDavis Dec 24 '11 at 15:37
47

You can try the below code

$(this).toggleClass('ui-icon-plusthick ui-icon-minusthick');
Pbk1303
  • 3,702
  • 2
  • 32
  • 47
George
  • 4,323
  • 3
  • 30
  • 33
  • 3
    I do believe this is the best answer. – Pardoner Nov 16 '12 at 00:05
  • @Pardoner Strangely this works. However the jquery documentation states that applying `$('.tumble').toggleClass('bounce spin')` alternates between `
    ` and `
    `. But it seems to toggle instead between: `
    ` and `
    `
    – JayAr Nov 27 '12 at 19:10
  • 1
    I dont see that behavior ... http://jsfiddle.net/4kDaR/30/ the difference is that in the OPs request the element being toggled on starts with one of the classes. The toggle command turns that off and the second on because it was previously off. thus alternating the two. To get the behavior you describe at the end see here... http://jsfiddle.net/4kDaR/34/ – George Nov 28 '12 at 02:31
6

It probably because when you bind those functions there are no results for $(".portlet-header .ui-icon-plusthick"). It doesn't find it. You may add this binding to $(".portlet-header .ui-icon-minusthick").click(function() { ... after adding "ui-icon-plusthick" class.

EDIT: Alternative solution could be:

$(".portlet-header .ui-icon-minusthick").toggle(function() {
        $(this).removeClass("ui-icon-minusthick");
        $(this).addClass("ui-icon-plusthick");
        $(this).parents(".portlet:first").find(".portlet-content").toggle();
    }, function() {
        $(this).removeClass("ui-icon-plusthick");
        $(this).addClass("ui-icon-minusthick");
        $(this).parents(".portlet:first").find(".portlet-content").toggle();
    });

So first click would be first function and second click would be second function.

Marek Tihkan
  • 1,914
  • 13
  • 11
  • I see your point, but I couldn't get this to work correctly. I added the *.click(function() {...* on to the *addClass('ui-icon-plusthick')* but that seemed to make it unstable. Would you be able to provide an example of what you mean? – CAbbott Oct 29 '09 at 16:15
  • Sweet! Thanks, this has been hanging me up for a while. btw, your example needs to be $(".portlet-header .ui-icon-minusthick").toggle(... – CAbbott Oct 29 '09 at 17:18
  • .toggle() (event) is now deprecated http://api.jquery.com/toggle-event/ refer to http://stackoverflow.com/questions/14301935/where-has-fn-toggle-handlereventobject-handlereventobject-gone If you still want to do this option, here's a very nice and clean option http://stackoverflow.com/questions/14301935/where-has-fn-toggle-handlereventobject-handlereventobject-gone#answer-25150375 – Facundo Colombier Mar 16 '15 at 20:44
0

I wrote this jQuery function, not a plugin, to cycle through any number of classes. Two acts like a toggle. Just put your CSV of classnames in the element's data-classes. Then cycle it with $(selector).cycleClass()

See it in use at www.PluginExamples.com/draggable choose draggable-axis.

(function($){
    $.fn.cycleClass = function(){
        if( !$(this).data("aClasses") ){
            var classes = $(this).attr("data-classes").split(",");
            $(this).data("aClasses", classes);
            $(this).data("classes", classes.join(" "));
            $(this).data("class", classes.length);
        }
        $(this).data("class",($(this).data("class")+1) % $(this).data("aClasses").length);
        $(this).removeClass($(this).data("classes"))
            .addClass( $(this).data("aClasses")[$(this).data("class")] );
        return $(this);
    }
});
-2

Instead of doing all that Javascript, why don't you just modify the ui-icon-plusthick CSS class to show the minus image instead of the plus image?

Rahil Sondhi
  • 656
  • 6
  • 7
  • Would you be able to give an example of how you would be able to toggle between the two images within the class? – CAbbott Oct 29 '09 at 15:48
  • Actually, come to think of it, that wouldn't work. I wouldn't want other porlets on the site that aren't minimized to change their image. – CAbbott Oct 29 '09 at 15:58