These are my early thoughts on how to structure DataTable in 3.5.0. Feedback is welcome in the comments.
new Y.DataTable({...});
new Y.DataTable.Base({...});
| /*global SM:true*/ | |
| 'use strict'; | |
| // Publish a very special, promise-compatible event that supports the default | |
| // function behavior to chain on internally created promises before executing | |
| // the after() subs. on() subs can still e.preventDefault(), which will | |
| // reject the promise and thus skip the default behavior and after() subs. | |
| var asyncEvent = eventTarget.publish('foo'); | |
| asyncEvent._firing = new Y.Promise(function (resolve) { resolve(); }); |
| <!doctype html> | |
| <html> | |
| <head> | |
| <title>IO with transports and promises</title> | |
| </head> | |
| <body> | |
| <script src="http://yui.yahooapis.com/3.9.1/build/yui/yui.js"></script> | |
| <script> | |
| // sm-io is an alias for sm-io-core and sm-io-xhr. The two modules don't require one another. | |
| YUI({ filter: 'raw' }).use('sm-io', function (Y) { |
| var proxy = { | |
| _data: {}, | |
| get: function (name) { | |
| var model = this._data; | |
| return model.isYUIModel ? | |
| model.apply(model, arguments) : | |
| model[name]; | |
| }, | |
| set: function () { |
| // Class extension to DataTable ... | |
| Y.DataTable.Selection = function () {} | |
| Y.DataTable.Selection.ATTRS = { | |
| // selectionMode: for supporting multiple selection could be its own extension | |
| selectionType: { | |
| value: null, // Feature should not change base behavior by default | |
| validator: '_validateSelectionType' |
| // Include this after the table's render() | |
| // CAVEAT: this is NOT compatible with nodeFormatters | |
| table.body._afterDataChange = function (e) { | |
| var type = (e.type.match(/:(add|remove|change)$/) || [])[1], | |
| odd = ['yui3-datatable-odd', 'yui3-datatable-even'], | |
| even = ['yui3-datatable-even', 'yui3-datatable-odd'], | |
| row, index; | |
| switch (type) { | |
| case 'change': |
| /* | |
| This code should allow users to tab to the first row in the table, which will "select" it by | |
| adding a class to it and storing a reference to the row node. Alternately, users can click | |
| on a row to select it. Selection can be shifted to the next or previous row with the up and down arrow keys. The 'enter' key will fire a 'rowAction' custom event. | |
| */ | |
| table.getRow(0).setAttribute('tabindex', table.get('tabIndex') || 0); | |
| table.delegate('keydown', function (e) { | |
| var selected = this._selectedRow, | |
| tbody = this._tbodyNode, |
| // Add support for table.getColumn( node ) | |
| Y.DataTable.prototype.getColumn = (function (original) { | |
| return function (seed) { | |
| var cell; | |
| if (Y.instanceof(seed, Y.Node)) { | |
| cell = this.getCell(seed); | |
| seed = cell && (cell.get('className').match( | |
| new RegExp(this.getClassName('col', '(\\w+)'))) || [])[1]; |
| YUI.add('event-multi-defaultFn', function (Y) { | |
| // FIXME: publish() needs to be patched to support allowing this to be called before | |
| // publish(). Today, the publish() call will clobber the AOP wrapper. | |
| Y.EventTarget.prototype.addEventBehavior = function (type, fn, when) { | |
| var event = this.getEvent(type), | |
| method = when === 'before' ? 'before' : 'after', | |
| handle; |
| // For Y.Foo | |
| // Class extensions that will be used in the base class | |
| function ExtA() {} | |
| ... | |
| Y.namespace('Foo').ExtA = ExtA; | |
| // Base Class definition | |
| function FooBase() {} | |
| ... |