Categories
Development

YUI 3 Awesomeness

I’ve been a huge fan of the YUI Library for quite some time now, using it in some form in almost all of my web projects done over the last 2+ years. Every now and then, I’m pleasantly surprised in just how useful it can be to me as a developer.

For instance, recently I’ve been working on building an application that will need an easy to use sortable list, that will fire off an event upon the list order changing. As simple as this sounds, it would require a lot of coding and cross browser testing to pull this one off with just javascript alone.

YUI 3 allowed me to accomplish the above in just a few minutes. I’m not even going to try to guess just how much time it’d of taken me to do on my own.

I made use of the Sortable Utility to make and unordered list sortable in just a few lines of code.

First I just added the YUI seed file to my page:

<script src="http://yui.yahooapis.com/3.1.1/build/yui/yui-min.js" type="text/javascript"><!--mce:0--></script>

Then just added a simple div and unordered list to my page:

 

Things I want

    • puppy dog

 

  • ice cream

 

 

  • G.I. Joe USS Flagg Aircraft Carrier

 

 

  • Lego bricks

 

 

  • iPad

 

 

  • Infinity Gauntlet

 

 

  • world peace

 

 

  • Star Scream

 

 

  • waffles

 

 

  • pb&j sandwich

 

 

And added the script that brings the unordered list to life:

YUI().use('sortable', function(Y) {
    var sortable = new Y.Sortable({
        container: '#want-list',
        nodes: 'li',
        opacity: '.1'
    });
});

That was it, a fully user sortable list!

I also needed this list to fire an event when a list item order had been changed. The Drag & Drop (DD) Utility has some nifty events that conveniently work with the Sortable Utility. So, I just added the following to my above script:

var doSomething = function() {
    	alert('do something');
	};
	Y.DD.DDM.on('drop:hit', doSomething);

When a drop:hit event occurs, it calls the doSomething function. In this case the doSomething function fires up an alert that says “do something”. It’s pretty basic and a rather useless alert, but it does demo what I’m working to do.

Again, YUI 3 is so awesome, that I easily spent more time writing up this little post than I did in making my above requirements happen. That’s really amazing to me. YUI 3 documentation is great, tons of examples there too.

Categories
Development

Feature Box

Needed to create an area on a web page that could contain several feature items that could be easily navigated through. There are many excellent carousel type components available, but they didn’t meet all my needs or were conflicting with a drop down menu that we have on this particular site. So I decided to create my own solution.

So that it’s semantically correct, all you need is to wrap a div around an ordered list and give that div an id of “feature-box”.

<div id="feature-area">
    <ol>
        <li><img src="http://www.atlantic.edu/aca/images/homeSplashCareer.jpg" width="548" height="200" alt="Turn your passion into a culinary career" /></li>
    	<li><img src="http://www.atlantic.edu/aca/images/homeSplashBaking.jpg" width="548" height="200" alt="Rise to the challenge of a baking and pastry career" /></li>
    	<li><img src="http://www.atlantic.edu/aca/images/homeSplashFire.jpg" width="548" height="200" alt="Get fired up for a culinary career" /></li>
    	<li><img src="http://www.atlantic.edu/aca/images/homeSplashRestaurant.jpg" width="548" height="200" alt="Learn in a real restaurant setting" /></li>
    </ol>
</div>

The rest of my javascript relies pretty heavily on the YUI DOM Collection and the YUI Event Library, so I included their yahoo-dom-event.js file. YUI library is amazing and if you’re not familiar with it I highly recommend you check it out.

<script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>

Then I wrote up a little function that on page load takes the ordered list and only shows the first item and creates the navigation to control the feature box.

init:function(e) {
    // object test if js available
    if (!document.getElementById || !document.createTextNode){return;}
    if (!document.getElementById("feature-area")) return false;
 
    // assign feature-aread div, ol, and items
    var featureDiv = document.getElementById('feature-area');
    var featureOl = featureDiv.getElementsByTagName('ol');
    var featureItems = featureOl[0].getElementsByTagName('li');
 
    // set class on li's to hide and show for the first item
    for (var i=1; i<featureItems.length; i++) {
        YAHOO.util.Dom.addClass(featureItems[i], 'hide');
    }
    YAHOO.util.Dom.addClass(featureItems[0], 'show');
 
    // create navigation
    var navDiv = document.createElement('div');
    navDiv.setAttribute('id', 'feature-nav');
    navDiv.innerHTML = '<a href="#" id="feature-prev">prev</a> <span id="feature-nav-marker"></span> <a href="#" id="feature-next">next</a>';
 
    // insert navigation
    YAHOO.util.Dom.insertAfter(navDiv, featureOl[0]);
 
    // create nav dots
    for (var i=0; i<featureItems.length; i++) {
        var navMarkerItem = document.createElement('span');
	var navMarkerId = 'feature-nav-'+i;
	navMarkerItem.setAttribute('id', navMarkerId);
	navMarkerItem.innerHTML = 'item '+i;
	var navMarkerList = document.getElementById('feature-nav-marker');
	navMarkerList.appendChild(navMarkerItem);
	// assign class of active to first marker
	if (i==0) {
	    YAHOO.util.Dom.addClass(navMarkerItem, 'active');
	}
	YAHOO.util.Event.addListener(navMarkerItem, "click", acccFeatureArea.gotoFeature);
    }
}

First we grab then apply the class of “hide” to all the list items’s. But the very first list item we apply a class of “show”. Now only the first list item is being displayed.

// assign feature-aread div, ol, and items
var featureDiv = document.getElementById('feature-area');
var featureOl = featureDiv.getElementsByTagName('ol');
var featureItems = featureOl[0].getElementsByTagName('li');
 
// set class on li's to hide and show for the first item
for (var i=1; i<featureItems.length; i++) {
    YAHOO.util.Dom.addClass(featureItems[i], 'hide');
}
YAHOO.util.Dom.addClass(featureItems[0], 'show');

Then we create the navigation. To figure out how many navigation dots to create, we have to figure out how many list items there are. Also those navigation dots need an event handler attached to them so they can be used to control the feature box.

// create navigation
var navDiv = document.createElement('div');
navDiv.setAttribute('id', 'feature-nav');
navDiv.innerHTML = '<a href="#" id="feature-prev">prev</a> <span id="feature-nav-marker"></span> <a href="#" id="feature-next">next</a>';
 
// insert navigation
YAHOO.util.Dom.insertAfter(navDiv, featureOl[0]);
 
// create nav dots
for (var i=0; i<featureItems.length; i++) {
    var navMarkerItem = document.createElement('span');
    var navMarkerId = 'feature-nav-'+i;
    navMarkerItem.setAttribute('id', navMarkerId);
    navMarkerItem.innerHTML = 'item '+i;
    var navMarkerList = document.getElementById('feature-nav-marker');
    navMarkerList.appendChild(navMarkerItem);
    // assign class of active to first marker
    if (i==0) {
        YAHOO.util.Dom.addClass(navMarkerItem, 'active');
    }
    YAHOO.util.Event.addListener(navMarkerItem, "click", acccFeatureArea.gotoFeature);
}

Functions are attached to the navigation arrows to reveal the next item in the list while hiding all the other items. If it’s at the end or beginning of the list it then circles around to the first or last item.

nextFeature:function(e) {
    var currentItem = YAHOO.util.Dom.getElementsByClassName('show', 'li', 'feature-area');
    var nextItem = YAHOO.util.Dom.getNextSibling(currentItem[0]); 
    // if no more items, go to first item
    if (nextItem == null) {
        var featureItems = YAHOO.util.Dom.getElementsByClassName('hide', 'li', 'feature-area');
	var nextItem = featureItems[0];
    }
 
    YAHOO.util.Dom.replaceClass(currentItem[0], 'show', 'hide');
    YAHOO.util.Dom.replaceClass(nextItem, 'hide', 'show');
    acccFeatureArea.setMarker();
}

The navigation dots get their own function attached to them to reveal their respective list item. It adjusts the class associated with the list items as well as the navigation dots to control the feature box.

gotoFeature:function(e) {
    // assign feature-aread div, ol, and items
    var featureDiv = document.getElementById('feature-area');
    var featureOl = featureDiv.getElementsByTagName('ol');
    var featureItems = featureOl[0].getElementsByTagName('li');
 
    var navMarker = document.getElementById('feature-nav-marker');
    var navMarkerItems = navMarker.getElementsByTagName('span');
 
    var navMarkerId = this.getAttribute('id');
    var currentSelection = navMarkerId.substring(navMarkerId.length-1);
 
    if (this.className != 'active') {
        for (var i=0; i<featureItems.length; i++) {
	    YAHOO.util.Dom.replaceClass(featureItems[i], 'show', 'hide');	
	}
	YAHOO.util.Dom.replaceClass(featureItems[currentSelection], 'hide', 'show');
 
	for (var i=0; i<navMarkerItems.length; i++) {
	    YAHOO.util.Dom.removeClass(navMarkerItems[i], 'active');
	    YAHOO.util.Dom.addClass(navMarkerItems[currentSelection], 'active');
	}
    }
}

Here is a link to a sample of this.