Unobtrusive Rollovers Using YUI

April 28, 2008 at 4:12 pm by Eric Miraglia | In Development | 10 Comments

Introduction to Unobtrusive JavaScript, DOM Scripting, and the Yahoo! User Interface (YUI) Library on 2tsp.com.

Chad at 2tbsp.com wrote up a nice tutorial last week outlining some practical fundamentals with respect to writing "unobtrusive JavaScript." His example implements a standard rollover, beginning with bad-old-days obtrusive scripting, migrating to unobtrusive scripting, and concluding with an unobtrusive script that leverages YUI’s Event Utility for event attachment and the Dom Collection’s getElementsByClassName, addClass and removeClass for class management.

Click through for his functioning example.

Click through for the functioning example.

Of course, Chad just means this as an example of some of the practical points involved in unobtrusive scripting. Others have looked at the problem more encyclopedically — for a more ambitious (and not YUI-related) analysis of the paradigm, check out Christian Heilmann’s "The seven rules of Unobtrusive JavaScript".

Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!

DjangoSnippets: YUI Loader as Django Middleware

April 25, 2008 at 4:47 am by Eric Miraglia | In Development, In the Wild | No Comments

YUI Loader integration on DjangoSnippets.com

Over on DjangoSnippets.org, akaihola has posted a YUILoader class (based on Adam Moore’s client-side YUI Loader) that makes it a snap to pull YUI components into your Django projects.

This server-side middleware implements some of the functionality in the Yahoo User Interface Loader component. YUI JavaScript and CSS modules requirements can be declared anywhere in the base, inherited or included templates, and the resulting, optimized <script> and <link rel="stylesheet"> tags are inserted at the specified position of the resulting page.

Requirements may be specified in multiple locations. This is useful when zero or more components are included in the HTML head section, and inherited and/or included templates require possibly overlapping sets of YUI components in the body across inherited and included templates. All tags are collected in the head section, and duplicate tags are automatically eliminated.

The middleware understands component dependencies and ensures that resources are loaded in the right order. It knows about built-in rollup files that ship with YUI. By automatically using rolled-up files, the number of HTTP requests is reduced.

Back in August on DjangoSnippets, pigletto posted a nice YUI snippet for use with the YUI AutoComplete Control.

Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!

David Cilley’s Tutorial Series on Ajax Image Sliders

April 24, 2008 at 5:14 am by Eric Miraglia | In Development | 1 Comment

David Cilley on Ajax image sliders using YUI.

David Cilley on Ajax image sliders using YUI.David Cilley this week published the second in his series of articles on using the YUI Slider Control to provide real-time previewing of image changes.

In this second installment, David takes on the challenge of making the preview feel instantaneous without computing or delivering every possible image represented by the slider’s continuum:

On the previous slider example, I used a YUI slider that had a range from -100 to 100. This is a total of 201 different combinations for one image dialog, and that’s about 10-20 times more requests than a web server should have to handle in a reasonable amount of time. We want to make this look as if the slider is actually changing the image while we scroll it, but we don’t want to request 201 images up front, and we don’t want to load them all on demand either.

A part 3 in the series, David notes, will continue to refine the control. [Update: David has posted Part 3.]

For more Slider Control examples, check out the YUI Slider example roster; and don’t miss Todd Kloots’s Slider/Button example, which would be another way of presenting the control David is describing in his article series.

Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!

Hidden Gems in the YAHOO Object

April 23, 2008 at 5:45 am by Eric Miraglia | In Development, In the Wild | 2 Comments

Lang's little gems, on PlankDesign.com

Mitch at PlankDesign.com has posted a nice review of one of the least-discussed aspects of YUI Core — the YAHOO Global Object’s YAHOO.lang member. He covers a number of the language conveniences provided therein, including type checking, trim, substitute, later and merge.

Luke Smith from the YUI team recently added some great examples of other features in the YAHOO object, so check those out, too, if you’re interested in learning more about this essential building block of YUI.

Thanks for the insights, Mitch!

Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!

YUI Engineers at Web 2 Expo This Week

April 22, 2008 at 6:30 pm by Eric Miraglia | In Development | No Comments

YUI Engineers Dav Glass, Jenny Han Donnelly, and Adam Moore

If you’re heading to Web 2.0 Expo this week, stop by the big Yahoo booth and say hello. Dav Glass will be at the booth tomorrow (Wednesday) and Jenny Han Donnelly will be joined by Adam Moore on Thursday along with our friends and colleauges from the Yahoo Developer Network. We’ll have YUI Cheat Sheet packets to give away and lots of other good YDN schwag; come by early and often! Dav, Adam and Jenny will obviously be there to answer any questions you might have about YUI, too, so bring those by if you want some one-on-one time with the team.

Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!

Creating Component Communication Pipelines with YUI (Decoupling)

April 22, 2008 at 11:29 am by Caridy Patiño | In Development | 7 Comments
Caridy Patiño Mayea

Caridy, a leading and always-helpful contributor to the YUI community forum, has been working in front of a PC since the nineties. For the past eight years he’s been a professional programmer developing LAMP applications for the University of Las Villas where he received his B.S. in Computer Science in 2003, and for several companies around the world. He left his university job in August to pursue an independent consulting career and to follow his passion for open source solutions and agile development.

For the last two years he’s been focused on JavaScript as a development platform. Early last year he decided to create an easy-to-adopt YUI extension called “Bubbling Library” as a side project; you can read his YUIBlog introduction to the Bubbling Library here.

Creating complex web applications demands organization and modularization. Modularization introduces a new problem — the comunication pipes between components. This is a serious challenge for developers, as more components and widgets mean more pipelines and more dependencies. In this article, we’ll look at a technique to mitigate these issues: Creating an abstraction layer to moderate the comunication between the components and widgets in a web application. This technique is based on YUI and makes use of my Bubbling Library, which is a BSD-licensed superset of functionality that builds on top of the YUI foundation.

Most current YUI components use "Custom Events" as their main communication pipes. This is good. Using custom events you can, for example, know when a YUI Panel is opened or closed, and the components in your application can subscribe a listener to this custom event to know when the Panel’s status changes.

YAHOO.example.myPanel.showEvent.subscribe(function(){
// your stuff here…
});

The weakness of this model is that all the components in your application need to know about or have access to the YUI Panel object to subscribe a listener. Even worse, they all need to wait until the YUI Panel instance is created (because that’s when the custom event is created and becomes available for subscription), so they need to be aware of the timeline in the application. If you need to introduce a new component in your application, to attach a listener you must wait until the YUI Panel has been created. What happens if you have several panels instead of one? You keep adding more and more listeners, creating more dependencies, and more timeline control.

The solution for this overwhelming amount of complexity is simple and very useful for complex web applications. Those who are accustomed to high-level programming languages, blackbox programmers,and APIs fans will love this implementation for sure.

Decoupling

The idea here is to create components that do not need to know about other components in the application. Each component will catch certain messages (listening events) generated by another component, o create a new message (broadcasting events) based on the received message, and fire the new message to reach all the listeners. We’ll have an abstraction layer that will allow us to subscribe listeners for a specific message. For example:

YAHOO.Bubbling.on( 'onPanelShow', function(layer, args) {
// do the job here… });

DecouplingIn this diagram, we have two components that will broadcast a message to the abstraction layer (Custom Behavior Layer), reaching all the listeners for that specific message (keying on the message’s name).

Each component will also have three listeners (C1: B1,B2 and B3; C2:B4, B5, B2). In the case of the message B2, both components will be listeners for the same message, and both will be able to react when the message arrives.

What’s critical here is that we will be able to subscribe listeners to an undefined event, without worrying about what will fire this type of event or about what else might belistening for the same event. And this new listener will be executed whenever something (a component in your application) fires an event with the same name, in this case onPanelShow.

On the other hand, we will be able to fire an event, without previously defining it. For example:

YAHOO.Bubbling.fire ('onPanelShow', {
param1: value1, param2: value2
});

This call will send a message to all listeners, passing the name of the layer and the literal object (second argument).

We can go one step further, and pass the YUI Panel’s reference in the literal object, and the listeners will be able to query the Panel instance’s data, check the panel name, etc. For example::

var myPanel = YAHOO.widget.Panel("win", {fixedcenter: true});

myPanel.showEvent.subscribe(function(){
YAHOO.Bubbling.fire (’onPanelShow’, {
panel: myPanel, param1: ‘value1′, param2: ‘value2′
});
});

Each time the YUI Panel is displayed, a broadcast message will be fired, the name of the event will be onPanelShow, and the listeners of this type of event will be queried, using the panel, param1 and param2 as references. There are some interesting aspects to this example. You don’t need a global reference for the Panel object because there will be no subscribers attached directly to the YUI Panel object. Instead, we will subscribe the listener to the abstract layer (YAHOO.Bubbling). You can have more than one Panel, each Panel will fire the same event, and the listeners will be able to handle the broadcast without knowing anything about the Panel’s nature or environment. Finally, each subscriber will be able to define its execution scope, using the 3rd parameter:

YAHOO.Bubbling.on( 'onPanelShow', myListenerFunc, myScope);

Utilized well, this technique gives us the possibility to create a complex web application where each component will have an API to use for communicating with other components without knowing the component itself, or knowing the nature of the component.

Requirements

The Bubbling Library YUI Extension has already implemented this technique, so the requirements are simple:

<script type="text/javascript" src="http://yui.yahooapis.com/2.5.1/build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type=”text/javascript” src=’http://js.bubbling-library.com/1.5.0/build/bubbling/bubbling.js’></script>

* Bubbling Core (6k minify version)

Other examples

  • Creating a notification system that will handle application messages — displaying each message in a box on the bottom-right corner of the browser, with different backgrounds, all the components in your application will be able to broadcast a message; the notification system will catch the event and will display the message in the corresponding box, depending on the parameters sent by the sender.
  • Creating a loading mask (just like Gmail) that will display the message every time that the YUI Connection Manager, the YUI Get Utitlity or the YUI Loader starts waiting for a response from the server. In this case, all the components will have access to the Connection Manager, and each component will need to fire the LOADING EVENT every time it uses one of the loading mechanisms.
  • In a web app that supports multiple layouts — every time you switch the current layout, all the web parts will need to be notified in order to readjust the visual interface. All the components can define a listener to the switching action, and all will be notified with the name of the new layout to apply and new css rules isplaying or hiding certain information related to the component.
  • In a webmail system, you need to be notified when a new message arrives or when an unread message has been read. There are some pieces of the application that would be interested in this event (inbox, messenger, the message counter, etc), but the reader panel don’t know which of these parts are present on the page.

Conclusions

  • This technique is ideal for a large development teams. It reduces the complexity of the code and minimizes the number of global variables by eliminating the hard pipelines between components.
  • Large applications with many dynamic areas are tricky when you need to control the loading timeline. Using this technique you don’t need to worry about the loading timeline.
  • Applications based on this technique are easy to extend.
  • Each component has a simpler API making it easier for other developers to understand and reuse.
  • All the listeners will share the same syntax
    YAHOO.Bubbling.on('onEventName', function(layer, args) {});

Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!

Global Domination, Part Two

April 16, 2008 at 1:29 pm by Douglas Crockford | In Development | 3 Comments

As I continue the practice of the craft of programming, I am always examining my practices. Can I improve the patterns that I use so that I can make my programs clearer, stronger, better? This is particularly important when working with a language like JavaScript which has a bias that favors patterns that are confusing, weak, and worse.

One of the worst features of JavaScript is its reliance on global variables. This can be mitigated with global abatement and the module pattern, which can significantly reduce the number of global variables that we need to declare.

But when we must declare a global variable, how best should we do that? JavaScript provides three ways of declaring a global variable, and they all have problems. Which is least worst?

The first is to assign to a new name outside of any function.

    pity = {};  // The first form

The second is to use the var keyword outside of any function.

    var pity = {};  // The second form

The third is to assign to a property of the global object.

    this.pity = {};  // The third form

All three forms do the same thing. (There is also a fourth way, the abominable implied global, but we will not speak of that here. And don’t get me started on the fifth and sixth ways.)

So, given three ways to do the same thing, which should we use? I used to favor the second way. It looked to me the clearest in stating (or at least suggesting) my intention to declare something.

But it wasn’t completely satisfactory. First, some people read var in that position as declaring the variable in the scope of the compilation unit, similar to the way static works in C. This would be a useful reading, except that JavaScript does not have compilation unit scope. A knowledgeable programmer should know that, but an alarming percentage of web developers program in ignorance of the language, so this is a mild concern.

A greater concern is that the second form is larger than the first form, but does the same thing. Generally, I prefer minimal forms.

But the thing that finally convinced me that the first form is the least worst is that IE gets the second form wrong, so that responsibly adaptive programs fail when using constructs like

    var pity = this.pity || {};

In order to be maximally productive, I want to avoid features that have portability problems. It took me too long to accept that the second form is problematic and should therefore be avoided.

The thing I liked about the second form was that it seemed more intentional. By typing var, I declared that this isn’t an accidental misspelling. I am intentionally declaring a new global variable. But JavaScript paid no attention. I still feel the need to state that intention, so I state it in a comment.

    /*global pity*/
    pity = {};

JSLint is able to understand that comment, and can alert me to any global variables that I did not intentionally declare. That gives me confidence that I am not making a common mistake. The second form made me feel good, but didn’t actually give me any real assurance.

I am still learning how to program. I read code, and I consider the opinions of other programmers. I still have the capacity to change my practices. It is hard sometimes to admit that my previous practices were weak. But that is more than offset by adopting practices that are stronger.

Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!

Next Page »
Hosted by Yahoo!

Copyright © 2007 Yahoo! Inc. All rights reserved. Privacy Policy - Terms of Service

Powered by WordPress on Yahoo! Web Hosting.