Yahoo User Interface library (YUI)


YUI 2.8: Learning the Library

My first published book. Something I didn't expect. The guys at Packt Books sent me an email around December 2009 asking if I cared to do an update to their existing book on YUI. The original author was busy at the time and could not do it. My first question was if they weren't a little late. More and more of YUI3 was coming out of beta at the time, why YUI2? Anyway, I had the time and the knowledge and they were willing to pay a modest advance so they were serious about it, so I did it. It wasn't such a bad idea after all, YUI3 added the ability to load YUI2 components into its sandbox, which means YUI2 widgets have a long way to go.

It gave me a big oportunity to really learn the whole library, not just the components I am most used to. It also allowed me to work with very nice people whom I never met face to face and, funny enough, for a book published in English, many of them weren't native English speakers, starting with me.

Anyway, it is finally out there: YUI 2.8: Learning the Library


Server driven DataTable with pagination and sorting.

This example builds a DataTable based on the columns information taken from the server. Instead of building a statically defined DataTable it will build it based on what the server says.

It has been based on the server-side pagination and server-side sorting examples. They have both been changed in that they do not use the DataSource to communicate with the server but use a plain Connection Manager request to fetch the information and then pass it as a local source to the DataSource. This allows full access to all the information received from the server before it gets sent to the DataTable. Reported bugs on both examples have been fixed as well.

The source files for this sample are available for download in a zip file. The PHP server script requires an active PHP interpreter. The YUI compoments are fetched from the YUI site.

Data Grid

The DataTable is basically meant to represent data structured as in a regular database table. As such, it has a definition for each of the columns which applies to all rows in the table. Unless the designer provides customized code, every cell in the same column will behave the same.

This example uses an extra invisible column to provide data type definitions for each individual cell so that instead of a single definition applicable to all the cells in a column, each cell has its own definition. For the purpose of the example, this definition is only a string indicating whether the cell contains a number, text or date, nevertheless, in a real case there is no reason why it cannot be a complex object describing several attributes.

All columns have a custom formatter and editor function. These do not actually do any formatting or editing but they check the corresponding data type information stored in the extra column paired to the one being actually formatted or edited and then calls the standard formatters and editors provided for along the DataTable component

The example is fully contained in the HTML file, its only external resources are the YUI component files which are downloaded from the YUI download site.

New for 2.5.1

No changes where required for this version

New for 2.6.0

Editors are now separate classes and their interface to the DataTable has changed so the example had to be redone to handle this separate editor classes. A pool of an assortment of already instanced editors is placed in an object and used as requested

DataTable with extra details in tabbed pop-up

This example draws a very basic DataTable and on clicking on any cell, a YUI Panel will pop-up containing a YUI TabView with four tabs. Each tab has a child DataTable with different contents, all related to the clicked record. The contents in the cells of these child tables is generated dynamically and it reflects the base table row number and tab numbers active plus the row and column position of the cell.

In order to make the example totally self-contained, the data on all the tables is created locally. In an actual application the data would come from data servers. Besides changing the columns and field definitions to match the actual data, to make this example work in client-server environments the single argument to the constructors of all the new DataSources would need to be changed to the URL of the servers providing the data.

New for 2.5.1

This example uses method sendRequest of the DataSource to retrieve new data for the child tables. It has been modified to accept the arguments in the new format. The new version has provided backward-compatibility so it would have worked just the same the way it was.

Invoice: drag and drop, summary row and field validation

This example allows you to do an invoice by dragging items out of a DataTable with a list of items into another DataTable. It has in-line cell editing with an editor with a regular expression validator. The invoice uses the TFOOT element of the table to do the totals

New for 2.5.1

There are only two changes for this version. Method getTableEl does not exist anymore so it has been replaced by a way around. Also, the inline style definition for className number had to be replaced due to the new 'liner' element in between the HTML cell and the actual content.

Since now the headers are a separate table from the body of the DataTable the column widths are now calculated by the DataTable on each refresh. The footer is not included in this calculation since the DataTable ignores it exists. When first loaded, the right-hand table is empty and the footer with the totals does not match the headers (the titles in grey to the left don't end where they should). As soon as an item is dropped into the invoice, the borders align fine.

Fixed: Also, if you enter a large quantity on any of the items so that the totals grow wide, the headers and the table won't match any longer. Finally, there must be some padding or margin in the 'liner' element so that the totals are not aligned with the item prices. This I should be able to fix ASAP. The overflowing totals with large quantities was fixed by calling method _syncColWidths after the values are recalculated. Though the DataTable does not know about the tfoot element, the tbody of the table does adjust its width to it so _syncColWidths is able to adjust the headers to it. This was a tip by Jenny Han Donnelly, thanks. I often discourage the use of private methods and properties (those signaled by a leading underscore) since they are unsupported. In this case, tfoot elements are also unsupported so this whole example may break at any moment. Also, the alignment issue was solved by adding the same padding to the extra cells as the liner element has in the body of the table.

New for 2.6.0

The example was updated to use the new cell editors.

One of the purposes of this example was to show how to create your own cell editor. Since the whole way the cell editors work has changed, my sample text editor has changed as well. I also used the cell editor to edit a cell which is not actually part of the editor. Once again, that has been changed to use the new-style cell editors.

Show and hide columns in a DataTable

This example uses the new Selector component to hide and show columns in a DataTable with only two lines of code.

It uses the same server script as the Server driven DataTable example above.

New for 2.5.1

Showing and hiding columns is now a feature of the DataTable itself so there is no need to do any tricks with CSS styls and the Selector component.

Handling of active cell content

This example show an assortment of HTML controls: radio buttons, checkboxes, dropdowns, regular and image buttons and an in-line textbox and how to handle them.

New for 2.5.1

Not much new, simply using the getTdLinerEl method to reach the cell value container.

New for 2.6.0

Nothing really, I simply changed the names of the shortcuts to those I finally adopted.

Delete Rows By

Here, the DataTable is extended with a function deleteRowsBy analogous to function getChildrenBy in YAHOO.util.Dom, where you provide a function that will return a Boolean indicating whether the record is to be deleted or not. This function receives an object with all the values of each record to decide.

TreeView with DataTables as leafs

The example builds a couple of random trees. It will show a DataTable at the end of each branch.

In the first tree, several branches can be open at the same time so it builds a DataTable for each.

In the second tree, only one branch will be open at a time so it uses just one DataTable for all of them and just moves it around. It also uses a single DataSource with caching enabled so that if a node is visited again the data can be read from the cache.

New for 2.6.0

I learned to use the TreeView much better so I changed my initial use of TextNodes to HTMLNodes which provide a much more natural generic container for the table. Since 2.6 provides keyboard navigation, I also made the example respond to the Enter key as well as clicks. Finally, I just cleaned it up a bit, providing more standard shortcut names and reordering things around.

Send JSON data as POST to PHP

This is a working example of how you can send JSON data via a POST request with Connection Manager's asyncRequest method, and how to read it on the PHP side.

Using DataTable 2.6

This example is for the features shown in the articles in the YUI blog. More information can be found in them.

Showing Tooltips over the DataTable

Showing Tooltips over the DataTable

The example shows how you can show ToolTips over DataTable cells. It uses just one ToolTip for the whole of the DataTable which is filled and positioned each time. It uses events cellMouseoverEvent and cellMouseoutEvent to detect when the cursor is over the table cells we care about. A couple of timers handle the delay until the tooltip is shown and how long it shows. The text for the tooltip is taken from an extra field in the table which is not shown.

Grouping repeated column values

The example shows how you can group cells in the same column where values are the same.

It is like using the rowspan HTML attribute but without really doing so.

For a much better way of doing it, take a look at Anthony Super's blog article

Row Editor

A possible extension to allow row editing in the Datatable.

DataTable requery method

A custom method added to the DataTable to allow for easy refreshing of the DataTable with new data.

New for 2.8.0

I improved the requery method to support client and server-side paging and sorting, with some limitations. It is not a universal solution, some of the functionality will require support of the server or added code on the client. Please do read the notes, don't just copy the code and expect it to work because it might not work in all circumstances.

Highlighting tree nodes

The TreeView control now supports highlighting of nodes. The visual element showing the highlight can be checkboxes, as in the TaskNode example. However, this facility is now supported in all node types, including TextNodes.

This is an example that due to administrative issues, didn't make it into the examples at the YUI site.

The example is now available at the YUI site

Building trees from HTML markup or from previous definitions

The TreeView control can read existing markup, can build a tree from the definition of an existing TreeView or of any branch of it and can also build a tree from a literal object definition. This example shows some extra features of these capabilities.

This is an example that due to administrative issues, didn't make it into the examples at the YUI site.

YQL DataSource

YQL (YAHOO! Query Language) provides a simple mechanism to access information stored in YAHOO servers from all its services, not only its search engine but Flickr, contacts, weather, places and such. To use that information from YUI widgets such as DataTable, Charts or AutoComplete you need to use a ScriptNodeDataSource. Since most of the settings for it would be fixed when using YQL and others can be deduced from the query results, it makes sense to subclass ScriptNodeDataSource to handle as many defaults as possible.

The example code contains the definition of YQLDataSource and a simple example of how to use it on a DataTable. The idea came via this article on the YUI Blog

Key Navigation in DataTable cell editor

Surrendering to popular demand, once again. Many people asked to navigate in between cell editors by using the TAB key, so I gave it a try. I threw in arrow keys as well. It works a little funny when getting to the edges and doesn't pop up all editors, don't know why.

Suggestions welcome

Matt Parker has improved on this idea by adding a method allowMoveCellWhileEdit to the cell editors that tell whether a particular keystroke should allow moving to other cell editor. In my example, I allowed it for all editors but Textareas. Matt's code allows a far better control on what is allowed for each cell editor. It is all in one package with his Column Chooser, which can be enabled separately.

ProgressBar in a pop up panel

This example shows a ProgressBar in a pop up window.

Dynamic dropdownOptions

This example shows how the dropdown options for a dropdownCellEditor can be set after the cell editor instance has been created.

Build Tree from DataSource

A function that can read a table representing a tree from a DataSource and turn it into a tree.

Nested DataTables

A complex example that shows how to nest a series of child tables in a master DataTable. This example uses my requery method for DataTable and my YQLDataSource to fetch the data from Yahoo!'s own music API via YQL.

A new subclass of DataTable: NestedDataTable was created so the application and the nesting are separate.


Featured in the YUI Blog:

Filtering by hiding rows

In this example I show how to selectively hide rows to filter out rows with values I don't want shown. I guess that the most important point is the redoing of the stripes once some of the rows are gone.

Infinite Scrolling DataTable

How to create a DataTable that keeps filling up with new records the further you scroll.

Drag and Drop within a TreeView

Dragging and Dropping tree nodes in a TreeView.

DataTable with Dynamic Context Menu

Showing how to dynamically change the options in a ContextMenu based on the DataTable cell being clicked.


Progress Bar widget

After a message in the YUI discussion forum and after writting the article about how to do widgets, I did my own Progress Bar component.

There is a 3.0 version of the ProgressBar which inherits from Y.Widget and follows the guidelines for 3.0.0 widgets as per the Preview Release 2

New for 2.8.0

The ProgressBar is now an official component of the YUI library.

New for 3.4.0

MakeNode Extension

An extension for Y.Widget that makes it easier to write Widgets in a more declarative way, encapsulating some of the best practices for developing widgets in a few declarations and saving tons of code.

This extension was described in an article in the YUI Blog, The "MakeNode" Widget Extension

Spinner Widget

I used the Spinner from the example of using Widgets as an example for using MakeNode as well. Just as the original Widget example, this one is fully functional but much smaller since some of the functionality is provided by MakeNode and much cleaner.

This widget requires MakeNode

Button family of Widgets

I also needed some buttons for an app I was doing and instead of using Anthony Pipkin's gallery button I changed it to use MakeNode. Once again, the code is smaller and quite cleaner (the roles of each piece of code is better defined.

There is a plain button, a two position button and a button group with a button separator, to build toolbars.

This widget requires MakeNode. At this point, most of my widgets have MakeNode so it is a kByte weight shared.

Accordion Widget

Of course, when I needed an accordion, I also tried adapting something out there to use (and test) MakeNode itself. This is based on Iliyan Peychev's accordion from the gallery. The code is mostly mine, the images are his. It has most of his functionality plus it allows resizing. I still have to do the progressive enhancement for this one.

This widget requires MakeNode.


Working with the YUI DataTable Control

After using the DataTable for a while and answering questions from fellow users about it I realized I could help a little bit by putting together all I had learned in the process so I wrote a big article which Eric Miraglia very kindly refused, and right he was on doing so! After clearing up my ideas I realized there were about four separate articles that could be written. The first two were then accepted for publication by Eric at the YUI blog site after some editing which he very kindly handled.

New for 2.6.0

The articles were written in the last days of 2.3 so they got outdated. I re-wrote them for 2.6.0

New for 3.x

Some articles for YUI3:

A PHP back end to YUI

Some of the material in the article I originally prepared for publication at the YUI blog had no JavaScript at all, it was pure PHP so here it is with some extra PHP thrown in.

This article contains the code that would be the back-end to the code in the other two articles or, for that matter, in any AJAX application or, perhaps, it should be AJAJ since it uses JSON and not XML.

It also contains the code for my BuildSql function which is a sort of sprintf oriented towards SQL so that you write your SQL statement with placeholders and then the function takes care of inserting the rest of the arguments into the template with the proper format, quoting and escaping.

Making your own DataTable

YUI's DataTable component has many options so that it can be used in all sorts of applications and environments. Any single user, though, uses just a few of them. It is a good idea to encapsulate those few options in a single place so that even if at some point you decide to make a change, it will be propagated to all places at once.

Whatever options the server provides will probably determine how we communicate with it. The nature of our application will define the types of data we handle. The looks and behavior of our site will fix some more options. Finally, we may desperately need some patch and can't wait for the next release. These are options that we may cast into our own DataTable, inherited from YUI DataTable

New for 2.6.0

Most of this article became obsolete with later versions of the DataTable. Many of the features I showed here are now part of the DataTable, others have to be done in different ways. The example for the new articles for the DataTable in the YUI blog now cover mostly all this article has so if you are using 2.6, this is not for you.

Building Your Own Widget Library with YUI

At one point, the YUI discussion forum got several messages about people developing their own widgets. The YUI blog also reported a few. All of them failed to conform to the current YUI standards, with good reason, those standards are not available anywhere.

There is a good reason for that, the YUI library has been continuously growing and perfecting itself, but nobody had time to get all that experience gained by the YUI team anywhere. Moreover, the YUI library itself is not a good means of learning those standards since many of the components follow different conventions. Adapting those components to the ever improving standards would have meant making them incompatible with earlier versions. This means that each component is frozen at its historical moment, and if you don't know the history of the library, you don't know why each one is as it is.

So, in the end, I went to the newest components and started learning from them and compiled a list of guidelines which I later put together into this article. Eric Miraglia was very kind to check that I wasn't saying anything stupid (both in my use of English and in describing the library) and also asked me to explore some features I had overlooked.

Inside RIA, a couple of articles

I've got to write a couple of articles for O'Reilly's Inside RIA web site.

Nothing new on them. I hope they finally get their act together, it is a hassle to work with them and I don't intend to publish anything else with them, but there they are:

Changing the style of an element in a YUI widget

This question has come up quite often in the YUI forum: How can I change the color / background color / whatever of an element in a YUI component. To avoid explaining that once again, I've put it all here.

External links

A brief list of places that have good examples on the use of DataTables or similar components.

Component Dependencies Calculator (2.6.0)

A utility to figure out what needs to be included when you are loading several components at once.

It uses the YUI Loader to find out what you need and in which order.

It is now obsolete, it has been superseeded by YUI's own dependency configurator