Tag

Jump to Table of Contents

The Tag module provides a way to hook into Node creation and insertion. This allows you to build simple to use and powerful components that behave more like standard DOM nodes.

Getting Started

To include the source files for Tag and its dependencies, first load the YUI seed file if you haven't already loaded it.

<script src="http://yui.yahooapis.com/3.5.0/build/yui/yui-min.js"></script>

Next, create a new YUI instance for your application and populate it with the modules you need by specifying them as arguments to the YUI().use() method. YUI will automatically load any dependencies required by the modules you specify.

<script>
// Create a new YUI instance and populate it with the required modules.
YUI({
    //Last Gallery Build of this module
    gallery: 'gallery-2012.07.18-13-22',
}).use('gallery-tag', function (Y) {
    // Tag is available and ready for use. Add implementation
    // code here.
});
</script>

For more information on creating YUI instances and on the use() method, see the documentation for the YUI Global Object.

Using Tag

To hook into Node creation you must first specify what kind of node to hook into and what should be done on creation. You do that by registering a simple CSS selector and a mixin. If a node is found to match the selector, the mixin is applied and its created method is called.

Registering Tags

// Tag selector matches all ydate tags
Y.Tag.register('ydate', {
    created: function(config) {
        this.addAttr('date', {value: new Date()});
        this.get('host').setHTML(Y.DataType.Date.format(this.get('date'), {format: config.format}));
    }
});

When registering a tag, data- attributes are passed in as config parameters. Dashes are used for camelization (i.e. data-full-name would be passed as config.fullName).

<!-- Copyright © 2012 Yahoo! Inc. -->
Copyright &copy; <ydate data-format="%Y"></ydate> Yahoo! Inc.

Every Node has a tag plugin already created. The plugin is the receiver of a registered mixin.

Y.one('ydate').tag.get('date');

Nodes will always be matched whether they are present on page load or created dynamically. That means creating a new component is often as simple as Y.Node.create(...). Supported selectors are limited to tags and attributes.

Y.one('body').append('<ydate data-format="%T"></ydate>');

Registering Attributes

Registering attributes is a way to provide more graceful degredation to your elements. You could also register both an attribute and a tag to provide more flexible usage.

// Attribute selector matches all highdpi attributes
Y.Tag.register('[highdpi]', {
    created: function(config) {
        if (Y.config.win.devicePixelRatio <= 1) {return;}

        var host = this.get('host'),
            alt = config.alt || '@2x',
            src = host.get('src').replace(/(\.[a-zA-Z]+)$/, function(m) {return alt + m;});

        if (src) {
            Y.io(src, {
                method: 'HEAD',
                onsuccess: function(e) {
                    host.set('src', src);
                }
            });
        }
    }
});

Y.Tag.register('example, [example]', {});

When registering an attribute, the attribute name becomes a namespace for config parameters. It's possible to have a tag and many different attributes all with separate configs.

<!-- Updates image with higher resolution if large_photo@4x.jpg exists -->
<img highdpi highdpi:alt="@4x" src="large_photo.jpg" />

<!-- Registered tag and multiple attributes with configs -->
<foo data-name="Foo Inc." bar bar:name="Bar Inc." baz baz:name="Baz Inc."></foo>

Inserted Event

When a registered tag has been created it can listen for the tag:inserted event. This event is fired when the tag is added to the document. Most tags will do their work in the created method however more complicated tags like widgets can do things like bind to click events or render once they are part of the document.

How It Works

gallery-event-inserted provides the magic behind the tag:inserted event. It uses CSS3 Animation to create efficient inserted events. If CSS3 Animation is unsupported it falls back to using the slower DOMNodeInserted mutation event.

Why Tag

The main benefit to using Tag is to reduce the amount of boilerplate instantiation code most large web apps accumulate. When dynamically creating components nothing could be simpler than creating a tag with attributes. It also becomes very simple for those less familiar with Javascript to make use of widgets. They don't need to know valid Javascript syntax, HTML has a far lower barrier to entry.

Registry

There are many predefined tags available in the Tag Registry. tag-ybind is one of the most useful, it provides data binding using HTML. To use, include the following in your YUI config:

YUI({
    //Last Gallery Build of this module
    gallery: 'gallery-2012.07.18-13-22',
    groups: {tag: {
        combine: true,
        root: 'gallery-2012.07.18-13-22',
        patterns: {'tag-': {configFn: function(cfg) {
            cfg.path = '/build/gallery-tag-registry/' + cfg.name + '-min.js'
        }}}
    }}
}).use(/* 'tag-yautocomplete', 'tag-ybind', '...etc' */);
Name Description Module
yautocomplete Wrapper for AutoComplete. tag-yautocomplete
ybind Provides support for data binding. tag-ybind
ybutton Wrapper for Button. tag-ybutton
ycalendar Wrapper for Calendar. tag-ycalendar
ydial Wrapper for Dial. tag-ydial
yoverlay Wrapper for Overlay. tag-yoverlay
ytemplate Creates a template using Y.Lang.sub. Replaces all text between double brackets. tag-ytemplate

About

X-Tag was the initial inspiration, however the Tag module goes beyond the current implementation and allows you to register attributes in addition to tags.

Compatibility: IE9+, FF5+, Chrome 4+, Safari/iOS 4+, Android 2.1+