Saturday, September 15, 2007

YUI :: First Impressions

People must think I've been living in a cave, but I've only recently been playing with YUI. In the past two years, I've been a Bindows developer creating a few examples here and there and so, I know that framework pretty well.

Of course, now that I'm at Yahoo!, I'm supposed to get a firm grasp on the library. Unlike other web devs at Yahoo!, I haven't taken any classes on YUI. So, this series of entries will be a "fresh eyes" approach to YUI.

It's not a difficult library to learn and it's definitely not as comprehensive with it's controls/widgets as Bindows.

As you probably know, I think Bindows is great. IMHO, it's one of the best ( if not the best ) traditional front-end frameworks out there. You can do a lot with it ( just check my archives for examples or visit my site ).

In contrast, YUI isn't a framework. It's **mainly** an a la carte library of JavaScript utilities and widgets that help with web development. It abstracts browser differences so that you don't have to worry about it.

YUI also contains other things like CSS files that help with layout, font sizes and other troubling difficult to solve cross-browser issues.

What's interesting about YUI is that it's a mixture of things --
  • Utilities that help with DOM manipulation and event handling
  • CSS for cross-browser visual consistency
  • A few "hard to do by yourself" controls/widgets
One of the fundamental assumptions of YUI is that you need to know the DOM and how to manipulate it. You also need to know event handling. You'll need to know the structure of your application and how to style it. So, you need to know the "Big 3" - HTML, CSS and JavaScript.

YUI doesn't attempt to abstract these things ( which is a lot different than Bindows and a few other libraries which abstracts everything and all you really need to learn is JavaScript and the API. Of course, these libraries are typically "fatter" than a la carte libraries, but also have ways to remove libraries if they're not used ).

One advantage to the YUI approach is that it's a lot easier to add functionality to pre-existing systems. This is because you directly manipulate DOM elements. So, you basically load the library and then pass nodes, ids, etc. to helper methods which performs the magic.

Because YUI is an a la carte system, you'll only pick and choose what you want. It's easy for you to control the "size" of your library.

Like Ajax technologies, you can gradually introduce it into your system. For example, if you're interested in cross-browser event handling, you'd just pull in event.js which includes the YAHOO.util.Event class. You can throw one away home grown solutions like my own.

For now, we're just going to look at two of the utility components. In the future, we'll look at the core components and some of the handful of YUI controls/widgets.

About the Example
I'm really fond of DnD. People are still amazed that you can drag and drop in the browser. So, our first example will use the dragdrop library with a little sprinkle of animation.

Here's the example -- we'll drag a little box around and as we drag it, we'll provide visual indicators of the location of the box. Once we stop, we can undo our current position ( see it full screen here ) --



Both of these libraries manipulate the DOM, so you have to have markup.

So, the very first thing we do is take care of all the visual pieces. For us, it's the little draggable box, the "Undo Button" ( which is initially is not shown ), the left and the top positional markers which result in this simple structure --



The CSS is just as simple --



To use the dragdrop and animation libraries, you'll need to pull in three JavaScript files --



Note that yahoo-dom-event.js is used by both libraries.

Next, the fun begins! The general sequence for DnD is -
-
  • Get the element you want to drag
  • Instantiate a YAHOO.util.DD object with that element
  • Override the drag event handlers ( typically onDrag, but in our case we also overrode startDrag and endDrag as well; note that you can find a slew of event handlers as well as other information here; the dragdrop library is pretty comprehensive; you can even drop to targets; here's one of my examples )



YAHOO.util.DD is the wrapper around the object that's being dragged. So, if you need to get the object, you'll need to do this --

var dragEl = this.getDragEl();

dragEl is the node with ID "ThingToDrag". You'll also notice that we can use the node to get position information relative to the entire HTML document --

YAHOO.util.Dom.getX(dragEl);
YAHOO.util.Dom.getY(dragEl);

The x and y positions are tucked away in object literals which are pushed on an array. This is a stack of starting positions which we pop when we undo ( we'll talk more about this in the animation section ).

The handler that does most of the **work** is onDrag. It basically handles all the visual updates like --
  • The information on the position of the dragged element
  • Positions both the top and left grid markers so that they move with the element
Note that we're directly manipulating the node ( i.e. thingToDrag.style.left, etc. ). Of course, we don't have to do it this way. We could have just use YUI and the YAHOO.util.Dom.get/set methods, but we did it this way to remind us that we directly manipulate elements in the DOM ( this is in contrast to other toolkits like Bindows which totally abstracts the DOM ).

Once we've completed the drag, we can undo it. Undo starts the animation.

We'll instantiate the YAHOO.util.Motion object for the ThingToDrag node, subscribe to ( listen for ) the onTween and onComplete event handlers and then start the animation --



onTween is fired for each frame of the animation ( for each movement of ThingToDrag ) and onComplete is fired when the animation is finished ( ThingToDrag no longer moves ).

In this example the onTween handler, handleTween is the same handler as onDrag. Likewise, the onComplete handler, handleComplete is the same as endDrag.



This makes sense. There's a symmetry to undoing what you just did so it's no surprise that these event handlers are the same!

In the handler, handleComplete, we also unhook our event handlers. It's good practice to free up resources like this when they're not needed to avoid nasty memory leaks.



That's it! You can read more about the YUI dragdrop and the animation library here and here.

Feel free to study and use the example anyway you like.

Have fun!

No comments: