Search code examples
javascriptmootoolsthumbnailstogglebutton

mootools toggle button problem


I'm trying to code a function that let me toggle in and out all thumbnails in a list depending on their classes. e.g., if I click "print" on my menu bar, I need all thumbs with the "print" class to be hidden. If I click it a second time, the hidden thumbs are showing up.

Here is what I came up with :

window.addEvent('domready', function(){
       $$('.menu_button').toggle(
        function() {
            this.fade(0.5);
            var buttonId = this.id;
            $('slider_list').getElements('.'+buttonId).each(function(li) {
                li.tween('width','0');
            });
        },
        function() {
            this.fade(1);
            var buttonId = this.id;
            $('slider_list').getElements('.'+buttonId).each(function(li) {
                li.tween('width','100');
            });
        }
    );  

});



//toggle (emulate JQuery's toggle)
(function() {
    var toggled = 0;
    Element.implement({
        toggle: function(fn1, fn2) {
            var fns = [fn1, fn2];
            return this.addEvent('click', function(){
                fns[toggled].apply(this, arguments);
                toggled = toggled == 0 ? 1 : 0;
            });
        }
    });
})();

I've found the toggle function here

Now I experience some issues. First no matter what I do there will always be a thumb left at the end of the list. Then some clicks on the menu won't do anything. Generally when I click on a button in a different state (hidden/shown) than the previous one, there will always be a null click...

Anybody ?


Solution

  • I implemented it in a way that allows multiple functions, although not at all MooTools like, it will work. The problem with the code you are using is that each element which uses toggle is toggling the same toggled variable

    Element.implement({
        toggle: function() {
           this.store('toggle_options', {
             fn: arguments,
             cur: 0
           });
           this.addEvent('click', function(e) {
               e.stop();
               var opts = this.retrieve('toggle_options');
               console.log(opts.fn.length, opts.cur);
               opts.fn[opts.cur++].apply(this);
               if(opts.cur >= opts.fn.length) opts.cur = 0;
           }); 
        } 
    });
    
    $('button').toggle(
        function() {
          this.set('text', 'foo 1');  
        },
        function() {
          this.set('text', 'bar 2');
        }
    );
    

    fiddle here: http://jsfiddle.net/94FFj/

    Although I would recommend you implemented your code as this:

      $$('.menu_button').each(function(button) {
        button.store('toggle_active', 0);
        button.addEvent('click', function(e) {
          e.stop();
          var active = this.retrieve('toggle_active');
          var opts = [{opacity: 1, width: 0}, {opacity: 0.5, width: 100}];
          this.fade(opts[active].opacity);
          $$('slider_list .' + this.get('id')).tween('width', opts[active].width);
          this.store('toggle_active', active ? 0 : 1);
        });
      })