Search code examples
javascriptclicktogglemootoolsdom-events

mootools | toggler event


I have mootools code:

document.getElements('.toggler').addEvent('click', function(e){

var target  = this.getChildren('i');
console.log(target);

if (target.hasClass('icon-minus')) {
   console.log('hasclass - minus'); 
   target.addClass('icon-plus').removeClass('icon-minus');
   this.getNext('div').hide();
} else {    
   console.log('hasclass - plus');
   target.addClass('icon-minus').removeClass('icon-plus');
   this.getNext('div').show();
}                           
});

My HTML layout:

<div class="filter">
   <sup class="toggler">
      <i class="icon-minus"></i>
   </sup>
</div>

But if I click on the toggler I will get:

1: Object[i.icon-minus]
hasclass - minus
2: Object[i.icon-plus]
hasclass - minus
3: Object[i.icon-plus]
hasclass - minus

This is an error! How to solve this issue?


Solution

  • an alternative way to write would be:

    document.getElements('.toggler').addEvent('click', function(e){
        e && e.stop();
        // the i and the div won't change. only get them from DOM once.
        var i = this.retrieve('i', this.getElement('i')),
            next = this.retrieve('next', this.getNext('div')),
            // keep state in storage also, no need to query dom all the time.
            isCollapsed = this.retrieve('state', i.hasClass('icon-plus'));
    
        // based upon current state (which we don't need in DOM after the first time)
        // calls either hide or show dynamically.
        next[['hide', 'show'][+isCollapsed]]();
        // all we want is to swap the classes, use toggleClass. 
        i.toggleClass('icon-plus').toggleClass('icon-minus');
        // save new state
        this.store('state', !isCollapsed);
    });
    

    http://jsfiddle.net/dimitar/3ZY9Q/

    this minimizes your dom lookups and works from memory (element storage) - and it also removes if/then/else code complexity.