datatable-message.js revision 40731a101f30570a8fe653d123035c7e836f92d1
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt SweeneyYUI.add('datatable-message', function(Y) {
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney/**
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt SweeneyAdds support for a message container to appear in the table. This can be used
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeneyto indicate loading progress, lack of records, or any other communication
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeneyneeded.
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt SweeneyFeatures added to `Y.DataTable`, and made available for custom classes at
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney`Y.DataTable.Message`.
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney@module datatable-message
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney@class DataTable.Sortable
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney@for DataTable
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney**/
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeneyvar Message;
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt SweeneyY.namespace('DataTable').Message = Message = function () {};
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt SweeneyMessage.ATTRS = {
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney /**
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney Enables the display of messages in the table. Setting this to false will
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney prevent the message Node from being created and `showMessage` from doing
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney anything.
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney @attribute showMessages
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney @type {Boolean}
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney @default true
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney **/
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney showMessages: {
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney value: true,
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney validator: Y.Lang.isBoolean
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney }
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney};
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt SweeneyY.mix(Message.prototype, {
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney /**
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney Template used to generate the node that will be used to report messages.
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney @property MESSAGE_TEMPLATE
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney @type {HTML}
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney @default <tbody class="{className}"><td class="{contentClass}" colspan="{colspan}"></td></tbody>
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney **/
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney MESSAGE_TEMPLATE: '<tbody class="{className}"><tr><td class="{contentClass}" colspan="{colspan}"></td></tr></tbody>',
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney /**
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney Hides the message node.
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney @method hideMessage
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney @return {DataTable}
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney @chainable
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney **/
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney hideMessage: function () {
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney this.get('boundingBox').removeClass(
b0e8ba0bb1024f36f17e1c8c55f531698df8bec7Matt Sweeney this.getClassName('message', 'visible'));
return this;
},
/**
Display the message node and set its content to `message`. If there is a
localized `strings` entry for the value of `message`, that string will be
used.
@method showMessage
@param {String} message The message name or message itself to display
@return {DataTable}
@chainable
**/
showMessage: function (message) {
var content = this.getString(message) || message;
if (!this._messageNode) {
this._initMessageNode();
}
if (this.get('showMessages')) {
if (content) {
this._messageNode.one(
'.' + this.getClassName('message', 'content'))
.setContent(content);
this.get('boundingBox').addClass(
this.getClassName('message','visible'));
} else {
// TODO: is this right?
// If no message provided, remove the message node.
this.hideMessage();
}
}
return this;
},
//--------------------------------------------------------------------------
// Protected methods
//--------------------------------------------------------------------------
/**
Updates the colspan of the `<td>` used to display the messages.
@method _afterMessageColumnsChange
@param {EventFacade} e The columnsChange event
@protected
**/
_afterMessageColumnsChange: function (e) {
var contentNode;
if (this._messageNode) {
contentNode = this._messageNode.one(
'.' + this.getClassName('message', 'content'));
if (contentNode) {
contentNode.set('colSpan', this._displayColumns.length);
}
}
},
/**
Relays to `_uiSetMessage` to hide or show the message node.
@method _afterMessageDataChange
@param {EventFacade} e The dataChange event
@protected
**/
_afterMessageDataChange: function (e) {
this._uiSetMessage();
},
/**
Removes the message node if `showMessages` is `false`, or relays to
`_uiSetMessage` if `true`.
@method _afterShowMessagesChange
@param {EventFacade} e The showMessagesChange event
@protected
**/
_afterShowMessagesChange: function (e) {
if (e.newVal) {
this._uiSetMessage(e);
} else if (this._messageNode) {
this.get('boundingBox').removeClass(
this.getClassName('message', 'visible'));
this._messageNode.remove().destroy(true);
this._messageNode = null;
}
},
/**
Binds the events necessary to keep the message node in sync with the current
table and configuration state.
@method _bindMessageUI
@protected
**/
_bindMessageUI: function () {
this.after(['dataChange', '*:add', '*:remove', '*:reset'],
Y.bind('_afterMessageDataChange', this));
this.after('columnsChange', Y.bind('_afterMessageColumnsChange', this));
this.after('showMessagesChange',
Y.bind('_afterShowMessagesChange', this));
},
/**
Merges in the message related strings and hooks into the rendering cycle to
also render and bind the message node.
@method initializer
@protected
**/
initializer: function () {
this._initMessageStrings();
if (this.get('showMessages')) {
this.after('renderBody', Y.bind('_initMessageNode', this));
}
this.after(Y.bind('_bindMessageUI', this), this, 'bindUI');
this.after(Y.bind('_syncMessageUI', this), this, 'syncUI');
},
/**
Creates the `_messageNode` property from the configured `MESSAGE_TEMPLATE`
and inserts it before the `<table>`'s `<tbody>` node.
@method _initMessageNode
@protected
**/
_initMessageNode: function () {
if (!this._messageNode) {
this._messageNode = Y.Node.create(
Y.Lang.sub(this.MESSAGE_TEMPLATE, {
className: this.getClassName('message'),
contentClass: this.getClassName('message', 'content'),
colspan: this._displayColumns.length || 1
}));
this._tableNode.insertBefore(this._messageNode, this._tbodyNode);
}
},
/**
Add the messaging related strings to the `strings` map.
@method _initMessageStrings
@protected
**/
_initMessageStrings: function () {
// Not a valueFn because other class extensions will want to add to it
this.set('strings', Y.mix((this.get('strings') || {}),
Y.Intl.get('datatable-message')));
},
/**
Node used to display messages from `showMessage`.
@property _messageNode
@type {Node}
@value `undefined` (not initially set)
**/
//_messageNode: null,
/**
Synchronizes the message UI with the table state.
@method _syncMessageUI
@protected
**/
_syncMessageUI: function () {
this._uiSetMessage();
},
/**
Calls `hideMessage` or `showMessage` as appropriate based on the presence of
records in the `data` ModelList.
This is called when `data` is reset or records are added or removed. Also,
if the `showMessages` attribute is updated. In either case, if the
triggering event has a `message` property on the EventFacade, it will be
passed to `showMessage` (if appropriate). If no such property is on the
facade, the `emptyMessage` will be used (see the strings).
@method _uiSetMessage
@param {EventFacade} e The columnsChange event
@protected
**/
_uiSetMessage: function (e) {
if (!this.data.size()) {
this.showMessage((e && e.message) || 'emptyMessage');
} else {
this.hideMessage();
}
}
});
if (Y.Lang.isFunction(Y.DataTable)) {
Y.Base.mix(Y.DataTable, [ Message ]);
}
}, '@VERSION@' ,{requires:['datatable-base'], lang:['en'], skinnable:true});