Categories
Development

YUI Treeview

The sitemap for atlantic.edu has grown quite a bit over the years, and we were looking for a way to make it more manageable while still being accessible. The YUI Treeview version 2.6.0 supports progressive enhancement, focus and keyboard navigation. Which seemed a perfect fit for what was needed.

Implementing it couldn’t of been any easier too. Just include the necessary source files. Then just create and render the Treeview.

tree1 = new YAHOO.widget.TreeView("markup");
tree1.render();
Categories
Development

Jom Comment

I needed to incorporate a comment system for a client. Their site is powered by Joomla, so I was checking out what options were available. Instead of making this completely from scratch I figured I’d see what existing extensions were available.

After some research, Jom Comment turned out to be the best fit for the clients needs. Installation was fairly simple, and it gives the client a very user friendly admin interface to work with. I highly recommend this commenting solution if you are running a Joomla site.

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.

Categories
Development

Using YUI Get Utility to consume Flickr API

I wanted to pull photos from a Flickr account onto a site. The Flickr API is awesome and there’s a ton of libraries out there for using it. Unfortunately, cURL isn’t currently installed on the server, so the PHP libraries won’t work for this case.

So I figured I’d give the YUI Get Utility a try. The Get Utility provides a mechanism for attaching script and css resources – including cross-domain resources – to the DOM after the page has loaded. And this has worked really well.

Here’s what I did:

  1. Included the following YUI scripts:
    <script src="http://yui.yahooapis.com/2.6.0/build/yahoo-dom-event/yahoo-dom-event.js" type="text/javascript"><!--mce:0--></script>
    <script src="http://yui.yahooapis.com/2.6.0/build/get/get-min.js" type="text/javascript"><!--mce:1--></script>
  2. Then fetch the Flickr feed in JSON format using the Get Utility.var
    objTransaction = YAHOO.util.Get.script(<url goes here>);

    Be sure that the Flickr REST call is set to output to JSON so that the Get Utility can consume it properly.  Append &format=json

  3. Then write a function to act on the JSON response from Flickr.  Here’s an example of taking the JSON response and outputting thumbnails of photos with links to the larger view:
    function jsonFlickrApi(rsp){ 
     
        if (rsp.stat != "ok"){
     
         alert('no data returned');
     
         return;
     
        }
     
        for (var i=0; i<rsp.photoset.photo.length; i++){
     
    		var photo = rsp.photoset.photo[i];
     
    		var container = document.getElementById('container');
    		var photosList = container.getElementsByTagName('ul');
     
    		// create elements
    		var photoItem = document.createElement('li');
     
    		var photoAnchor = document.createElement('a');
    		var photoImg = document.createElement('img');
     
    		// set attributes
    		photoAnchor.setAttribute('href', 'http://farm'+photo.farm+'.static.flickr.com/'+photo.server+'/'+photo.id+'_'+photo.secret+'_b.jpg');
    		photoImg.setAttribute('src', 'http://farm'+photo.farm+'.static.flickr.com/'+photo.server+'/'+photo.id+'_'+photo.secret+'_s.jpg');
    		photoImg.setAttribute('width', '75');
    		photoImg.setAttribute('height', '75');
    		photoImg.setAttribute('alt', photo.title);
     
    		// append to DOM
    		photoAnchor.appendChild(photoImg);
    		photoItem.appendChild(photoAnchor);
     
    		photosList[0].appendChild(photoItem); 
     
    		}
     
        }
     
        var objTransaction = YAHOO.util.Get.script("http://api.flickr.com/services/rest/?method=flickr.photosets.getPhotos&api_key=<insert_your_api_key>&photoset_id=72157594235977414+&format=json&per_page=60");

View an example

Categories
Development

Using DataSource URL with Google Visualization API and Spreadsheet

Spent a good chunk of the day figuring out how to work with the Google Visualization API DataSource URL from a Google Docs Spreadsheet.  It was a little tricky at first, but it’s not too bad once you figure it out.

First make a query of the URL using the built in Visualization API methods:

var query = new google.visualization.Query('http://spreadsheets.google.com/tq?range=&lt;your cell ranges go here&gt;&amp;headers=-1&amp;key=&lt;your URL info goes here&gt;&amp;gid=17&amp;pub=1'); 

ok, let’s break down the key variables in the URL above:

  1. tq?range=E2-G2Anything after the tq is a query written in the Google Visualization API Query Language.  It’s very similar to basic SQL.  In the case above it’s saying “Select the cells between the range of E2 to G2”.  A pretty basic selection, but you can make much more elaborate ones using the Query Language.
     
  2. &key<your URL info goes here> can be found in the URL of the spreadsheet that you’re pulling data from.
  3.  &pub=1Appending this variable with the value of 1 states that the data is public.  This is important if you want you data available to any web visitor.
You then make a call to the API using the send() function.
query_day.send(handleQueryResponse);
Then send method requires a callback function.  In this case we name it handleQueryResponse.
Below is a basic function that when called pulls a value from the spreadsheet and sets that value on a web page.
function handleQuery_dayResponse(response) {
  var data = response.getDataTable();
  var sampleText = document.getElementById('sample-text-div');
  sampleText.innerHTML = 'Enrollment  as <strong>Day ' + data.getValue(0,0) + '</strong>.';
}
This assigns the variable data with the value of the response formatted as a DataTable.  It then grabs the specific value from the DataTable, in this case there’s only one value returned so the column and row values are (0,0).  The getValue() function makes this really easy to do.

Check out a basic example.

Categories
Development

Adding chat powered by Google Talk

Bioderma Medical Laser & Aesthetics wanted real time chat added to their website. I really wanted to find a solution that would be extremely easy for the site visitors (no leaving the site, nor having to download any plugins, or having to register or login) and easy and convenient for the client as well.  After researching many different options, I found that having the client set up a free Google Talk account and incorporating a chatback badge into the site was most effective.

The Google Talk account presents numerous advantages for the client:

  • it’s free
  • is a full featured IM client
  • can be accessed via an application or even through the browser
  • Google Talk is compatible with other IM clients
  • has a robust API
  • features are continually being rolled out for Google Talk
  • can be used on multiple devices (iPhone, etc.)

From the web visitors end, they just see a text bubble stating the status of the client.  Whether they’re available or not for chat, busy, etc.  If someone is available to chat all they have to do is click on the link and a chat session begins.  No logging in, downloading software, etc.  It’s very cool, and a great solution for incorporating real time chat into a website.