<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>Dave Dash</title>
 <link href="http://davedash.com/tag/toggles/atom.xml" rel="self"/>
 <link href="http://davedash.com/tag/toggles"/>
 <updated>2012-01-17T21:54:19-08:00</updated>
 <id>http://davedash.com/</id>
 <author>
   <name>Dave Dash</name>
   <email>dd+atom1@davedash.com</email>
 </author>

 
 <entry>
   <title>Building a triangle toggler in YUI</title>
   <link href="http://davedash.com/2008/02/25/building-a-triangle-toggler-in-yui/"/>
   <updated>2008-02-25T00:00:00-08:00</updated>
   <id>http://davedash.com/2008/02/25/building-a-triangle-toggler-in-yui</id>
   <content type="html">&lt;p&gt;If someone knows the more common name for triangle-toggle menu's similar to &lt;a href=&quot;http://developer.yahoo.com/yui/examples/treeview/menu_style.html&quot;&gt;this&lt;/a&gt;.  Let me know.&lt;/p&gt;

&lt;p&gt;There is a widget where an element toggles the display of a secondary set of elements.  The toggle shows an arrow pointing down or right depending on the visibility of the elements.  I wanted to build that in YUI.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;The problem is two-fold:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build a triangle that toggles from right to down.&lt;/li&gt;
&lt;li&gt;Show and hide content.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;However, with some clever CSS we can do this all in a single class change on an element.&lt;/p&gt;

&lt;h3&gt;Build that triangle&lt;/h3&gt;

&lt;p&gt;There's a number of ways to show or hide this triangle.  Because it is flexible, I'm going to opt for using a background image.  Also to save on HTTP requests, I'll use a sprite-d image.  This may get merged with other icons on the system.&lt;/p&gt;

&lt;p&gt;The particular site I'm working on uses a black background with white text, therefore a white triangle toggle seems appropriate.&lt;/p&gt;

&lt;div style=&quot;background:black;text-align:center; padding:1em&quot;&gt;
&lt;img src=&quot;http://spindrop.us/wp-content/uploads/2008/02/sprite.png&quot; alt=&quot;sprite.png&quot; border=&quot;0&quot; width=&quot;11&quot; height=&quot;29&quot; /&gt;
&lt;/div&gt;


&lt;p&gt;This is what I use.  I leave a little space, because the background will only clip horizontally based on the size of the element.&lt;/p&gt;

&lt;h3&gt;Add the HTML/CSS&lt;/h3&gt;

&lt;p&gt;The following HTML:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;html&quot;&gt;
&lt;div id=&quot;area&quot; class=&quot;off&quot;&gt;
  &lt;h3&gt;&lt;span class=&quot;toggle&quot;&gt;Toggle Me&lt;/span&gt;&lt;/h3&gt;
  &lt;ul class=&quot;hide_me&quot;&gt;
  &lt;/ul&gt;
&lt;/div&gt;
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;and the following CSS:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;css&quot;&gt;

.toggle {
    background: url(../images/icons/sprite.png) no-repeat 0px -14px;
    padding: 0 0 0 18px;
}

.off .hide_me {
    display: none;
}

.on .toggle {
    background-position: 0 9px;
}

&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;Provide the two states we require for the triangle.  If you are new to sprites, rather than changing the background image entirely we just shift the background image up or down appropriately to show a new background.&lt;/p&gt;

&lt;h3&gt;The Javascript&lt;/h3&gt;

&lt;p&gt;The javascript is rather simple, but we put in some magical tricks here and there.&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;js&quot;&gt;
var MA = {}
MA.toggler = function()
{
    var e = YAHOO.util.Event; 
    var d = YAHOO.util.Dom;
    
    return {
        init: function() {
            e.onDOMReady(this.setup,this, true)
        },
        
        setup: function() {
            e.on(d.get('doc4'),'click',this.handleClick,this,true);
        },
        
        handleClick: function(ev) {
            var target = e.getTarget(ev);
            if (d.hasClass(target, 'toggle')) {
                var toggle = target.parentNode.parentNode;
                this.toggle(toggle);
            }
        },
        toggle: function(element) {
            var on  = &quot;on&quot;;
            var off = &quot;off&quot;;
            if (d.hasClass(element, on)){
                d.removeClass(element, on);
                d.addClass(element, off);
            } else {
                d.removeClass(element, off);
                d.addClass(element, on);
            }
        }
    }
}();

MA.toggler.init();
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;If you're unfamiliar with this style of Javascript, here's what's going on.  Everything is done in the &lt;code&gt;MA&lt;/code&gt; namespace as to not conflict with other javascript.&lt;/p&gt;

&lt;p&gt;The toggler is fairly generic and expects a similar HTML structure for &lt;em&gt;any&lt;/em&gt; toggle-able element.  That means this code only needs to be written once, and anytime we use the &lt;code&gt;toggle&lt;/code&gt; class, toggling in this fashion will occur.&lt;/p&gt;

&lt;p&gt;We only run the &lt;code&gt;init&lt;/code&gt; function.  &lt;code&gt;init&lt;/code&gt; says when the &lt;code&gt;DOM&lt;/code&gt; is available then run the &lt;code&gt;setup&lt;/code&gt; function.  &lt;code&gt;setup&lt;/code&gt; adds an event handler to &lt;code&gt;doc4&lt;/code&gt;.  &lt;code&gt;doc4&lt;/code&gt; just happens to be the id we use on our &lt;code&gt;body&lt;/code&gt; tag.&lt;/p&gt;

&lt;p&gt;Note that we're listening for clicks everywhere.  This means we have to define only one event handler, regardless of how many toggle-able items there are.  The event handler checks to make sure we clicked on a relevant element and then applies the &lt;code&gt;toggle&lt;/code&gt; function to the grandparent element (switching the class from &lt;code&gt;off&lt;/code&gt; to &lt;code&gt;on&lt;/code&gt; as appropriate).&lt;/p&gt;

&lt;p&gt;Note that this style of event handling means you need to carefully apply your class names.  Also note, that this code could be optimized a little bit more, I haven't put this code into production, and therefore haven't optimized it for the YUI compressor.&lt;/p&gt;

&lt;p&gt;Try this out if you want, I'm sure it can be trimmed down overtime.  If you have trouble with it, let me know.&lt;/p&gt;

&lt;p&gt;-d&lt;/p&gt;
</content>
 </entry>
 

</feed>

