diff -r 322d0feea350 -r 89ef5ed3c48b src/cm/media/js/lib/yui/yui_3.10.3/docs/tabview/tabview-add-remove.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cm/media/js/lib/yui/yui_3.10.3/docs/tabview/tabview-add-remove.html Tue Jul 16 14:29:46 2013 +0200 @@ -0,0 +1,664 @@ + + + + + Example: Adding and Removing Tabs + + + + + + + + + + +
+
+

+
+ + +

Example: Adding and Removing Tabs

+
+
+
+
+
+

This example shows how to give TabView buttons for adding and removing tabs.

+
+ +
+
+ +
+
+

foo content

+
+
+

bar content

+
+
+

baz content

+
+
+
+ +
+
+ +
+
+ + + +
+ +

+Note: be sure to add the yui3-skin-sam classname to the +page's <body> element or to a parent element of the widget in order to apply +the default CSS skin. See Understanding Skinning. +

+
<body class="yui3-skin-sam"> <!-- You need this skin class -->
+ + +

Plugin Template

+ +

In order to make these addons reusable, we can build them as plugins. This +allows the option for multiple tabviews that mix and match functionality. +To get started, we will first fill in a basic Plugin template. +The NAME property is required to prefix events, classNames, et cetera. +The NS is the namespace where the plugin will live on the +host. This is where its API can be accessed (e.g. "node.addable.destroy()"). +Adding the this._host alias provides a convenient way to get back to the TabView +instance. Calling the superclass constructor kicks off the Base lifecycle, +which will call the initializer. + +

+ +
var Addable = function(config) {
+    this._host = config.host;
+    Addable.superclass.constructor.apply(this, arguments);
+};
+
+Addable.NAME = 'addableTabs';
+Addable.NS = 'addable';
+
+Y.extend(Addable, Y.Plugin.Base, {
+    initializer: function(config) {
+    }
+});
+ + +

Addable Tab Plugin

+ +

To simplify adding new tabs, we are going to add a button that +users can click and that will prompt them for some details regarding the new tab. +The main task we are trying to accomplish is to add some HTML to the +TabView, listen for clicks on the button, prompt the user for input, +and update the tabs accordingly.

+ +

HTML Template

+

The first thing we need is a template for the markup to be generated. Adding +this to the prototype allows separate customization for each TabView +instance. For this example, we want it to look and feel like another Tab +without actually being one.

+ +
Y.extend(Addable, Y.Plugin.Base, {
+    ADD_TEMPLATE: '<li class="yui3-tab" title="add a tab">' +
+                '<a class="yui3-tab-label yui3-tab-add">+</a></li>',
+
+    initializer: function(config) {
+    }
+});
+ + +

Adding the HTML

+

Now that we have a markup template, we will need to add it to the TabView +somehow. The render phase is the appropriate moment to do so. Listening +for the render event will give us access to that moment. Listening +for after('render') ensure that the rendering has actually happened. Then +we just need to find the tab list and, using the template, add the new item. +The contentBox provides a Node that can be used to manage +the TabView HTML.

+ +
Y.extend(Addable, Y.Plugin.Base, {
+    ADD_TEMPLATE: '<li class="yui3-tab" title="add a tab">' +
+                '<a class="yui3-tab-label yui3-tab-add">+</a></li>',
+
+    initializer: function(config) {
+        var tabview = this.get('host');
+        tabview.after('render', this.afterRender, this);
+    },
+
+    afterRender: function(e) {
+        var tabview = this.get('host');
+        tabview.get('contentBox').one('> ul').append(this.ADD_TEMPLATE);
+    }
+});
+ + +

Handling the Click

+

All that remains is to listen for clicks on the add button and prompt +the user for the relevant Tab data. Again we can leverage +the Node API, this time to delegate clicks on the add button. +Stopping event propagation in our handler ensures that the event does +not bubble any further, preventing the TabView from trying +to handle it. To keep the example simple, a basic prompt is +used to get the user input. This could be refined to use an +Overlay or other custom control. The data is then handed off +to TabView's add method.

+ +
Y.extend(Addable, Y.Plugin.Base, {
+    ADD_TEMPLATE: '<li class="yui3-tab" title="add a tab">' +
+                '<a class="yui3-tab-label yui3-tab-add">+</a></li>',
+
+    initializer: function(config) {
+        var tabview = this.get('host');
+        tabview.after('render', this.afterRender, this);
+
+        tabview.get('contentBox')
+            .delegate('click', this.onAddClick, '.yui3-tab-add', this);
+    },
+
+    afterRender: function(e) {
+        this.get('host').get('contentBox').one('> ul').append(this.ADD_TEMPLATE);
+    },
+
+    getTabInput: function() {
+        return {
+            label: window.prompt('label:', 'new tab'),
+            content: window.prompt('content:', '<p>new content</p>'),
+            index: Number(window.prompt('index:', this._host.size()))
+        }
+    },
+
+    onAddClick: function(e) {
+        e.stopPropagation();
+        var tabview = this.get('host');
+            input = this.getTabInput();
+        tabview.add(input, input.index);
+    }
+});
+ + +

Using the Plugin

+

Now we can go ahead and plug in our functionality. This can be during +construction with the plugins attribute, or subsequently +via the plug method.

+ +
var tabview = new Y.TabView({
+    children: [{
+        label: 'foo',
+        content: '<p>foo content</p>'
+    }, {
+        label: 'bar',
+        content: '<p>bar content</p>'
+    }, {
+        label: 'baz',
+        content: '<p>baz content</p>'
+    }],
+    plugins: [Addable]
+});
+
+// or
+// tabview.plug(Addable);
+ + +

Removeable Tabs Plugin

+

The process for creating a removeable plugin for TabView +is very similar. The full source is provided below.

+ +
var Removeable = function(config) {
+    Removeable.superclass.constructor.apply(this, arguments);
+};
+
+Removeable.NAME = 'removeableTabs';
+Removeable.NS = 'removeable';
+
+Y.extend(Removeable, Y.Plugin.Base, {
+    REMOVE_TEMPLATE: '<a class="yui3-tab-remove" title="remove tab">x</a>',
+
+    initializer: function(config) {
+        var tabview = this.get('host'),
+            cb = tabview.get('contentBox');
+
+        cb.addClass('yui3-tabview-removeable');
+        cb.delegate('click', this.onRemoveClick, '.yui3-tab-remove', this);
+
+        // Tab events bubble to TabView
+        tabview.after('tab:render', this.afterTabRender, this);
+    },
+
+    afterTabRender: function(e) {
+        // boundingBox is the Tab's LI
+        e.target.get('boundingBox').append(this.REMOVE_TEMPLATE);
+    },
+
+    onRemoveClick: function(e) {
+        e.stopPropagation();
+        var tab = Y.Widget.getByNode(e.target);
+        tab.remove();
+    }
+});
+ +

Complete Example Source

+

+Note: be sure to add the yui3-skin-sam classname to the +page's <body> element or to a parent element of the widget in order to apply +the default CSS skin. See Understanding Skinning. +

+
<body class="yui3-skin-sam"> <!-- You need this skin class -->
+ + +
<div id="demo">
+    <ul>
+        <li><a href="#foo">foo</a></li>
+        <li><a href="#bar">bar</a></li>
+        <li><a href="#baz">baz</a></li>
+    </ul>
+    <div>
+        <div id="foo">
+            <p>foo content</p>
+        </div>
+        <div id="bar">
+            <p>bar content</p>
+        </div>
+        <div id="baz">
+            <p>baz content</p>
+        </div>
+    </div>
+</div>
+
+<div id="demo2">
+</div>
+
+<div id="demo3">
+</div>
+
+<script type="text/javascript">
+YUI().use('tabview', 'escape', 'plugin', function(Y) {
+    var Addable = function(config) {
+        Addable.superclass.constructor.apply(this, arguments);
+    };
+
+    Addable.NAME = 'addableTabs';
+    Addable.NS = 'addable';
+
+    Y.extend(Addable, Y.Plugin.Base, {
+        ADD_TEMPLATE: '<li class="yui3-tab" title="add a tab">' +
+                    '<a class="yui3-tab-label yui3-tab-add">+</a></li>',
+
+        initializer: function(config) {
+            var tabview = this.get('host');
+            tabview.after('render', this.afterRender, this);
+            tabview.get('contentBox')
+                .delegate('click', this.onAddClick, '.yui3-tab-add', this);
+        },
+
+        getTabInput: function() {
+            var tabview = this.get('host');
+            return {
+                label: Y.Escape.html(window.prompt('label:', 'new tab')),
+                content: '<p>' + Y.Escape.html(window.prompt('content:', 'new content')) + '</p>',
+                index: Number(window.prompt('index:', tabview.size()))
+            }
+        },
+
+        afterRender: function(e) {
+            var tabview = this.get('host');
+            tabview.get('contentBox').one('> ul').append(this.ADD_TEMPLATE);
+        },
+
+        onAddClick: function(e) {
+            e.stopPropagation();
+            var tabview = this.get('host'),
+                input = this.getTabInput();
+            tabview.add(input, input.index);
+        }
+    });
+
+    var Removeable = function(config) {
+        Removeable.superclass.constructor.apply(this, arguments);
+    };
+
+    Removeable.NAME = 'removeableTabs';
+    Removeable.NS = 'removeable';
+
+    Y.extend(Removeable, Y.Plugin.Base, {
+        REMOVE_TEMPLATE: '<a class="yui3-tab-remove" title="remove tab">x</a>',
+
+        initializer: function(config) {
+            var tabview = this.get('host'),
+                cb = tabview.get('contentBox');
+
+            cb.addClass('yui3-tabview-removeable');
+            cb.delegate('click', this.onRemoveClick, '.yui3-tab-remove', this);
+
+            // Tab events bubble to TabView
+            tabview.after('tab:render', this.afterTabRender, this);
+        },
+
+        afterTabRender: function(e) {
+            // boundingBox is the Tab's LI
+            e.target.get('boundingBox').append(this.REMOVE_TEMPLATE);
+        },
+
+        onRemoveClick: function(e) {
+            e.stopPropagation();
+            var tab = Y.Widget.getByNode(e.target);
+            tab.remove();
+        }
+    });
+
+    var tabview = new Y.TabView({
+        srcNode: '#demo',
+        plugins: [Addable]
+    });
+
+    var tabview2 = new Y.TabView({
+        children: [{
+            label: 'foo',
+            content: '<p>foo content</p>'
+        }, {
+            label: 'bar',
+            content: '<p>bar content</p>'
+        }, {
+            label: 'baz',
+            content: '<p>baz content</p>'
+        }],
+        plugins: [Removeable]
+    });
+
+    var tabview3 = new Y.TabView({
+        children: [{
+            label: 'foo',
+            content: '<p>foo content</p>'
+        }, {
+            label: 'bar',
+            content: '<p>bar content</p>'
+        }, {
+            label: 'baz',
+            content: '<p>bar content</p>'
+        }],
+        plugins: [Addable, Removeable]
+    });
+
+    tabview.render();
+    tabview2.render('#demo2');
+    tabview3.render('#demo3');
+});
+</script>
+ +
+
+
+ +
+ +
+
+
+ + + + + + + + + + +