#

API Docs for: 3.10.3
Show: Inherited Protected Private Deprecated

# File: datatable/js/message.js

    /**
    Adds support for a message container to appear in the table.  This can be used
    to indicate loading progress, lack of records, or any other communication
    needed.

    @module datatable
    @submodule datatable-message
    @since 3.5.0
    **/
    var Message;

    /**
    _API docs for this extension are included in the DataTable class._

    Adds support for a message container to appear in the table.  This can be used
    to indicate loading progress, lack of records, or any other communication
    needed.

    Features added to `Y.DataTable`, and made available for custom classes at
    `Y.DataTable.Message`.

    @class DataTable.Message
    @for DataTable
    @since 3.5.0
    **/
    Y.namespace('DataTable').Message = Message = function () {};

    Message.ATTRS = {
        /**
        Enables the display of messages in the table.  Setting this to false will
        prevent the message Node from being created and `showMessage` from doing
        anything.

        @attribute showMessages
        @type {Boolean}
        @default true
        @since 3.5.0
        **/
        showMessages: {
            value: true,
            validator: Y.Lang.isBoolean
        }
    };

    Y.mix(Message.prototype, {
        /**
        Template used to generate the node that will be used to report messages.

        @property MESSAGE_TEMPLATE
        @type {HTML}
        @default <tbody class="{className}"><td class="{contentClass}" colspan="{colspan}"></td></tbody>
        @since 3.5.0
        **/
        MESSAGE_TEMPLATE: '<tbody class="{className}"><tr><td class="{contentClass}" colspan="{colspan}"></td></tr></tbody>',

        /**
        Hides the message node.

        @method hideMessage
        @return {DataTable}
        @chainable
        @since 3.5.0
        **/
        hideMessage: function () {
            this.get('boundingBox').removeClass(
                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
        @since 3.5.0
        **/
        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'))
                        .setHTML(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
        @since 3.5.0
        **/
        _afterMessageColumnsChange: function () {
            var contentNode;

            if (this._messageNode) {
                contentNode = this._messageNode.one(
                    '.' + this.getClassName('message', 'content'));

                if (contentNode) {
                    // FIXME: This needs to become a class extension plus a view or
                    // plugin for the table view.
                    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
        @since 3.5.0
        **/
        _afterMessageDataChange: function () {
            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
        @since 3.5.0
        **/
        _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
        @since 3.5.0
        **/
        _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
        @since 3.5.0
        **/
        initializer: function () {
            this._initMessageStrings();

            if (this.get('showMessages')) {
                this.after('table: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
        @since 3.5.0
        **/
        _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
        @since 3.5.0
        **/
        _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)
        @since 3.5.0
        **/
        //_messageNode: null,

        /**
        Synchronizes the message UI with the table state.

        @method _syncMessageUI
        @protected
        @since 3.5.0
        **/
        _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
        @since 3.5.0
        **/
        _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 ]);
    }