Tag: YUI

Nested Grids in YUI Grids CSS

Posted by – February 17, 2009

Today I was trying to achieve a 25%|50%|25% layout within the main block of my YUI Grid CSS layout. Everything I read in documentation seemed to indicate you could nest grids in any way you desire. So I tried doing the following:


    <div class="yui-gf">
      <div class="yui-u first">
        <p>First Column (25%)</p>
      </div>
      <div class="yui-u">
        <div class="yui-gc">
          <div class="yui-u first">
            <p>2nd Column (50%)</p>
          </div>
          <div class="yui-u">
            <p>3rd Column (25%)</p>
          </div>
        </div>
      </div>
    </div>

However this didn’t work, it appears you can only nest grids in the ‘first’ column, unless you are using ‘yui-g’ (instead of one of the alternate layouts, such as yui-gc above). I couldn’t find this documented anywhere, but I don’t know why else the above code wouldn’t work.

I asked for help on twitter, and senior Yahoo engineer and CSS component author Nate Koechley (@natekoechley) was kind enough to point me to this solution. It appears that moving the nested grid under the ‘first’ unit fixes the problem. Of course, then you have to change which grids you are using, as follows:


<div class="yui-ge">
  <div class="yui-u first">
    <div class="yui-gd">
      <div class="yui-u first">
        <p>First Column (25%)</p>
      </div>
      <div class="yui-u">
        <p>2nd Column (50%)</p>
      </div>
    </div>
  </div>
  <div class="yui-u">
    <p>3rd Column (25%)</p>
  </div>
</div>

This seems to reinforce my hypothesis that nesting of alternate grid layouts can only be done under the first grid unit. Is this by design, or is it a bug? If anyone has any insight, please let me know in the comments.

Working off the above code, I decided I might as well clean it up a little bit. Nate Koechley himself says that if you are going to use a nested grid, you do not need to enclose that grid in a grid unit div (in other words, a grid container can act as a grid unit). This was said during his YUI CSS Foundation speech (about 24 minutes in).

However, I quickly found that removing the first grid unit div broke the layout. As this goes against what Nate has said publicly, I am curious if this is a bug or if he misspoke in his presentation. Here is the non-working code:


<div class="yui-ge">
  <div class="yui-gd first">
    <div class="yui-u first">
      <p>First Column (25%)</p>
    </div>
    <div class="yui-u">
      <p>2nd Column (50%)</p>
    </div>
  </div>
  <div class="yui-u">
    <p>3rd Column (25%)</p>
  </div>
</div>

I would like to point out that I am loving the idea of the YUI Grid CSS, and am hoping to utilize it in all my future projects. All of the issues I have discovered thus far are not deal breakers. I am simply looking to master the framework in a basic testing environment, so I’m not wresting with it in a complex, large scale implementation. So again, if anyone has any insight, I would be happy to hear it!

Convert UTC dates to local timezone offset automatically

Posted by – September 11, 2007

So I was working on an application that printed out lots of dates to the user. However, I get traffic from all over the world, and as this is kind-of time sensitive information, I wanted to display the time in their own timezone. I have don’t this before on things like forums, where you allow the user to select their timezone when they register. But what if your users don’t register?

I decided to build a javascript function that would automatically convert from UTC time to the users’ local timezone. This is a pretty simple task, and should work very effectively. I already store the dates in my database as UTC format, which is a good idea to do so that there is never any confusion later as to what timezone a date is in (What if you and/or your server moves?). Also because this is a javascript function, we have the ability to determine the users local time – something that we normally wouldn’t have.

Without further ado, here is the code:


var dateFunction = {
  convertDate : function (gmtDate){
    var originalDate = new Date(gmtDate);
    var retStr = (originalDate.getMonth()+1) + "-" + originalDate.getDate() + "-" + originalDate.getFullYear();
    return retStr;
  },
  init : function(){
    var elems = YAHOO.util.Dom.getElementsByClassName('utcDate');
    for(var i=0;i

As you can see, I am using the YUI library to do some DOM parsing, and unobtrusively add some event listeners. The code should be pretty straight forward, when the page loads I look for all elements with a class of "utcDate" and pass the innerHTML into a separate function. The other function create a new date object, using the original UTC date as the time. By doing this, javascript automatically will display this new date in the users' local time. I can then return the date in whatever format I want. Finally, I replace the innerHTML of the element with the new date string, and we are all set

This provides a simple way to convert dates to local timezone offset, and all the is required is for you to wrap any date you want converted in an element with a class equal to "utcDate". It also degrades gracefully, because without javascript users will simply see the date in UTC format, which isn't really a bad thing, and probably what you would be showing them anyways, if you didn't have this nifty script!

Javascript form validation object

Posted by – July 21, 2007

Today I thought I would share with you what I consider to be a fantastic way to handle form validation in javascript. Of course you need to remember that you have to validate any user input on the server side, but it’s nice to do things on the client side also, so they don’t have to wait as long for a response.

My approach to form validation in javascript involves 2 parts. First off is a extensible object that includes a variety of validation functions that I can have at my disposal. Secondly, I always format my forms with particular IDs, so that I can easily add error messages in javascript. First off, lets discuss the form layout (the easy part). The general rule of thumb here is to create a spot below the form element that will hold the error message, and give it an ID that is the same as the element, with ‘_error’ after it. So


Email:
 

Here the class ‘msg’ simply defines it as being hidden. Then with javascript if we determine email to be invalid, we can set the spans innerHTML to the text we want, and the class to something that will make it appear.

The second part is the fun javascript. What I do is create an empty object which i then prototype out with validation functions. Here is the code:


function Validator()
{
}

/**
 *  Check Email Function
 */
Validator.prototype.checkEmail=function(ELEM, EVENT)
{
  if(EVENT)
  {
    var scope = this;
    YAHOO.util.Event.addListener(ELEM, EVENT, function(){scope.checkEmail(ELEM);});
    return false;
  }
  try
  {
	var elem = this._getElem(ELEM);
	var targetElem = this._findTarget(elem);
	var email = elem.value;
	var regex = /^[-_.a-zA-Z0-9]+@[-_.a-zA-Z0-9]+\.[a-zA-Z0-9]+$/
	if (regex.test(email))
	{
           targetElem.className = "msg";
	   return true;
	}
	else
	{
           targetElem.innerHTML = "please enter a valid email address";
           targetElem.className = "msgshow";
	   return false;
	}
  }
  catch(e)
  {
	alert("Error in Validator() -> checkEmail(): " + e.message);
	return false;
  }
}

Here I create the object, and a email validation prototyped function. The function takes to arguments: an element, and an optional event. If an event is passed in, it is used to create a listener using the yahoo YUI library. This listener will fire on the given event, calling the same function without the optional argument (and thus running the validation).

The rest of the function is fairly straight forward. It first makes calls to getElem, and findTarget. if getElem is given a string, it returns the element with the given ID. If getElem is given an element, it simply returns the element. findTarget simply gets the ID of the passed in element, and appends ‘_error’, then gets the element with the new string ID.

From there is simply runs a regex expression, and if the regular expression matches it makes sure the error message is hidden, otherwise it sets the text and displays the error message.

This total solution is very portable and easy to use. After including the YUI libraries needed, and the validator code, one can add validation to an element by simply doing:


var validator = new Validator();
validator.checkEmail('email', 'change');

The only custom bit of code is two lines, and you have a regular expression checking the input field every time the field is changed, and will dynamically display an error message when incorrect.

Ajax loading overlay with YUI

Posted by – July 7, 2007

First off, let me say that I love Yahoo’s YUI Library. It seems to be very well thought out, and makes many tasks much simpler.

For Example, let say you upgrade your web app with some tasty Ajax. Now lets assume some of these ajax requests are working a little slow. The proper thing to do would be inform the user that something is happening in the background, so they aren’t lost. YUI makes it easy to display an overlay window with a loading image during the requests.

To do this, we use a Panel object. A panel object is basically a DIV with methods to hide and display itself, as well as advanced display options. Here is some starter code:


ajaxLoadingPanel = new YAHOO.widget.Panel("ajaxLoadPanel", {
width:"240px",
fixedcenter:true,
close:false,
draggable:false,
modal:true,
visible:false,
effect:{effect:YAHOO.widget.ContainerEffect.FADE, duration:0.5}
}
);

What we did here is create a basic panel. The first argument is the elements ID. This can either be an ID of an existing DIV in your DOM, or can be a new ID which will be applied to a dynamically created DIV. The next argument is an Object containing configuration options. These are pretty self explanatory: we set a width, tell it to display in the exact middle of the screen, don’t display a close button, don’t allow the user to drag it, make it a model window, and have it fade in and out. (FYI – a model window just means that it fades everything else on screen).

Next, we fill the DIV with content. If you used an ID of a pre-existing DIV, you can skip this code:


ajaxLoadingPanel.setHeader("Loading, please wait...");
ajaxLoadingPanel.setBody(' ');
ajaxLoadingPanel.render(document.body);

Here we simply set the header and body content of the div, and then add it to the DOM as a child of the body tag.

Good News! We are almost done! The panel is created, now all we need to do is trigger it to open, and close. This is done with the following 2 methods:


ajaxLoadingPanel.show();
ajaxLoadingPanel.hide();

All you need to do is call the show method right before your ajax call, and then the hide method right after recieving your ajax response. Thats it!