All Downloads are FREE. Search and download functionalities are using the official Maven repository.

META-INF.resources.bower_components.datatables.net-buttons.js.dataTables.buttons.js Maven / Gradle / Ivy

/*! Buttons for DataTables 1.5.4
 * ©2016-2018 SpryMedia Ltd - datatables.net/license
 */

(function (factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['jquery', 'datatables.net'], function ($) {
            return factory($, window, document);
        });
    }
    else if (typeof exports === 'object') {
        // CommonJS
        module.exports = function (root, $) {
            if (!root) {
                root = window;
            }

            if (!$ || !$.fn.dataTable) {
                $ = require('datatables.net')(root, $).$;
            }

            return factory($, root, root.document);
        };
    }
    else {
        // Browser
        factory(jQuery, window, document);
    }
}(function ($, window, document, undefined) {
    'use strict';
    var DataTable = $.fn.dataTable;


// Used for namespacing events added to the document by each instance, so they
// can be removed on destroy
    var _instCounter = 0;

// Button namespacing counter for namespacing events on individual buttons
    var _buttonCounter = 0;

    var _dtButtons = DataTable.ext.buttons;

    /**
     * [Buttons description]
     * @param {[type]}
     * @param {[type]}
     */
    var Buttons = function (dt, config) {
        // If there is no config set it to an empty object
        if (typeof(config) === 'undefined') {
            config = {};
        }

        // Allow a boolean true for defaults
        if (config === true) {
            config = {};
        }

        // For easy configuration of buttons an array can be given
        if ($.isArray(config)) {
            config = {buttons: config};
        }

        this.c = $.extend(true, {}, Buttons.defaults, config);

        // Don't want a deep copy for the buttons
        if (config.buttons) {
            this.c.buttons = config.buttons;
        }

        this.s = {
            dt: new DataTable.Api(dt),
            buttons: [],
            listenKeys: '',
            namespace: 'dtb' + (_instCounter++)
        };

        this.dom = {
            container: $('<' + this.c.dom.container.tag + '/>')
                .addClass(this.c.dom.container.className)
        };

        this._constructor();
    };


    $.extend(Buttons.prototype, {
        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	 * Public methods
	 */

        /**
         * Get the action of a button
         * @param  {int|string} Button index
         * @return {function}
         *//**
         * Set the action of a button
         * @param  {node} node Button element
         * @param  {function} action Function to set
         * @return {Buttons} Self for chaining
         */
        action: function (node, action) {
            var button = this._nodeToButton(node);

            if (action === undefined) {
                return button.conf.action;
            }

            button.conf.action = action;

            return this;
        },

        /**
         * Add an active class to the button to make to look active or get current
         * active state.
         * @param  {node} node Button element
         * @param  {boolean} [flag] Enable / disable flag
         * @return {Buttons} Self for chaining or boolean for getter
         */
        active: function (node, flag) {
            var button = this._nodeToButton(node);
            var klass = this.c.dom.button.active;
            var jqNode = $(button.node);

            if (flag === undefined) {
                return jqNode.hasClass(klass);
            }

            jqNode.toggleClass(klass, flag === undefined ? true : flag);

            return this;
        },

        /**
         * Add a new button
         * @param {object} config Button configuration object, base string name or function
         * @param {int|string} [idx] Button index for where to insert the button
         * @return {Buttons} Self for chaining
         */
        add: function (config, idx) {
            var buttons = this.s.buttons;

            if (typeof idx === 'string') {
                var split = idx.split('-');
                var base = this.s;

                for (var i = 0, ien = split.length - 1; i < ien; i++) {
                    base = base.buttons[split[i] * 1];
                }

                buttons = base.buttons;
                idx = split[split.length - 1] * 1;
            }

            this._expandButton(buttons, config, false, idx);
            this._draw();

            return this;
        },

        /**
         * Get the container node for the buttons
         * @return {jQuery} Buttons node
         */
        container: function () {
            return this.dom.container;
        },

        /**
         * Disable a button
         * @param  {node} node Button node
         * @return {Buttons} Self for chaining
         */
        disable: function (node) {
            var button = this._nodeToButton(node);

            $(button.node).addClass(this.c.dom.button.disabled);

            return this;
        },

        /**
         * Destroy the instance, cleaning up event handlers and removing DOM
         * elements
         * @return {Buttons} Self for chaining
         */
        destroy: function () {
            // Key event listener
            $('body').off('keyup.' + this.s.namespace);

            // Individual button destroy (so they can remove their own events if
            // needed). Take a copy as the array is modified by `remove`
            var buttons = this.s.buttons.slice();
            var i, ien;

            for (i = 0, ien = buttons.length; i < ien; i++) {
                this.remove(buttons[i].node);
            }

            // Container
            this.dom.container.remove();

            // Remove from the settings object collection
            var buttonInsts = this.s.dt.settings()[0];

            for (i = 0, ien = buttonInsts.length; i < ien; i++) {
                if (buttonInsts.inst === this) {
                    buttonInsts.splice(i, 1);
                    break;
                }
            }

            return this;
        },

        /**
         * Enable / disable a button
         * @param  {node} node Button node
         * @param  {boolean} [flag=true] Enable / disable flag
         * @return {Buttons} Self for chaining
         */
        enable: function (node, flag) {
            if (flag === false) {
                return this.disable(node);
            }

            var button = this._nodeToButton(node);
            $(button.node).removeClass(this.c.dom.button.disabled);

            return this;
        },

        /**
         * Get the instance name for the button set selector
         * @return {string} Instance name
         */
        name: function () {
            return this.c.name;
        },

        /**
         * Get a button's node
         * @param  {node} node Button node
         * @return {jQuery} Button element
         */
        node: function (node) {
            var button = this._nodeToButton(node);
            return $(button.node);
        },

        /**
         * Set / get a processing class on the selected button
         * @param  {boolean} flag true to add, false to remove, undefined to get
         * @return {boolean|Buttons} Getter value or this if a setter.
         */
        processing: function (node, flag) {
            var button = this._nodeToButton(node);

            if (flag === undefined) {
                return $(button.node).hasClass('processing');
            }

            $(button.node).toggleClass('processing', flag);

            return this;
        },

        /**
         * Remove a button.
         * @param  {node} node Button node
         * @return {Buttons} Self for chaining
         */
        remove: function (node) {
            var button = this._nodeToButton(node);
            var host = this._nodeToHost(node);
            var dt = this.s.dt;

            // Remove any child buttons first
            if (button.buttons.length) {
                for (var i = button.buttons.length - 1; i >= 0; i--) {
                    this.remove(button.buttons[i].node);
                }
            }

            // Allow the button to remove event handlers, etc
            if (button.conf.destroy) {
                button.conf.destroy.call(dt.button(node), dt, $(node), button.conf);
            }

            this._removeKey(button.conf);

            $(button.node).remove();

            var idx = $.inArray(button, host);
            host.splice(idx, 1);

            return this;
        },

        /**
         * Get the text for a button
         * @param  {int|string} node Button index
         * @return {string} Button text
         *//**
         * Set the text for a button
         * @param  {int|string|function} node Button index
         * @param  {string} label Text
         * @return {Buttons} Self for chaining
         */
        text: function (node, label) {
            var button = this._nodeToButton(node);
            var buttonLiner = this.c.dom.collection.buttonLiner;
            var linerTag = button.inCollection && buttonLiner && buttonLiner.tag ?
                buttonLiner.tag :
                this.c.dom.buttonLiner.tag;
            var dt = this.s.dt;
            var jqNode = $(button.node);
            var text = function (opt) {
                return typeof opt === 'function' ?
                    opt(dt, jqNode, button.conf) :
                    opt;
            };

            if (label === undefined) {
                return text(button.conf.text);
            }

            button.conf.text = label;

            if (linerTag) {
                jqNode.children(linerTag).html(text(label));
            }
            else {
                jqNode.html(text(label));
            }

            return this;
        },


        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	 * Constructor
	 */

        /**
         * Buttons constructor
         * @private
         */
        _constructor: function () {
            var that = this;
            var dt = this.s.dt;
            var dtSettings = dt.settings()[0];
            var buttons = this.c.buttons;

            if (!dtSettings._buttons) {
                dtSettings._buttons = [];
            }

            dtSettings._buttons.push({
                inst: this,
                name: this.c.name
            });

            for (var i = 0, ien = buttons.length; i < ien; i++) {
                this.add(buttons[i]);
            }

            dt.on('destroy', function (e, settings) {
                if (settings === dtSettings) {
                    that.destroy();
                }
            });

            // Global key event binding to listen for button keys
            $('body').on('keyup.' + this.s.namespace, function (e) {
                if (!document.activeElement || document.activeElement === document.body) {
                    // SUse a string of characters for fast lookup of if we need to
                    // handle this
                    var character = String.fromCharCode(e.keyCode).toLowerCase();

                    if (that.s.listenKeys.toLowerCase().indexOf(character) !== -1) {
                        that._keypress(character, e);
                    }
                }
            });
        },


        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	 * Private methods
	 */

        /**
         * Add a new button to the key press listener
         * @param {object} conf Resolved button configuration object
         * @private
         */
        _addKey: function (conf) {
            if (conf.key) {
                this.s.listenKeys += $.isPlainObject(conf.key) ?
                    conf.key.key :
                    conf.key;
            }
        },

        /**
         * Insert the buttons into the container. Call without parameters!
         * @param  {node} [container] Recursive only - Insert point
         * @param  {array} [buttons] Recursive only - Buttons array
         * @private
         */
        _draw: function (container, buttons) {
            if (!container) {
                container = this.dom.container;
                buttons = this.s.buttons;
            }

            container.children().detach();

            for (var i = 0, ien = buttons.length; i < ien; i++) {
                container.append(buttons[i].inserter);
                container.append(' ');

                if (buttons[i].buttons && buttons[i].buttons.length) {
                    this._draw(buttons[i].collection, buttons[i].buttons);
                }
            }
        },

        /**
         * Create buttons from an array of buttons
         * @param  {array} attachTo Buttons array to attach to
         * @param  {object} button Button definition
         * @param  {boolean} inCollection true if the button is in a collection
         * @private
         */
        _expandButton: function (attachTo, button, inCollection, attachPoint) {
            var dt = this.s.dt;
            var buttonCounter = 0;
            var buttons = !$.isArray(button) ?
                [button] :
                button;

            for (var i = 0, ien = buttons.length; i < ien; i++) {
                var conf = this._resolveExtends(buttons[i]);

                if (!conf) {
                    continue;
                }

                // If the configuration is an array, then expand the buttons at this
                // point
                if ($.isArray(conf)) {
                    this._expandButton(attachTo, conf, inCollection, attachPoint);
                    continue;
                }

                var built = this._buildButton(conf, inCollection);
                if (!built) {
                    continue;
                }

                if (attachPoint !== undefined) {
                    attachTo.splice(attachPoint, 0, built);
                    attachPoint++;
                }
                else {
                    attachTo.push(built);
                }

                if (built.conf.buttons) {
                    var collectionDom = this.c.dom.collection;
                    built.collection = $('<' + collectionDom.tag + '/>')
                        .addClass(collectionDom.className)
                        .attr('role', 'menu');
                    built.conf._collection = built.collection;

                    this._expandButton(built.buttons, built.conf.buttons, true, attachPoint);
                }

                // init call is made here, rather than buildButton as it needs to
                // be selectable, and for that it needs to be in the buttons array
                if (conf.init) {
                    conf.init.call(dt.button(built.node), dt, $(built.node), conf);
                }

                buttonCounter++;
            }
        },

        /**
         * Create an individual button
         * @param  {object} config            Resolved button configuration
         * @param  {boolean} inCollection `true` if a collection button
         * @return {jQuery} Created button node (jQuery)
         * @private
         */
        _buildButton: function (config, inCollection) {
            var buttonDom = this.c.dom.button;
            var linerDom = this.c.dom.buttonLiner;
            var collectionDom = this.c.dom.collection;
            var dt = this.s.dt;
            var text = function (opt) {
                return typeof opt === 'function' ?
                    opt(dt, button, config) :
                    opt;
            };

            if (inCollection && collectionDom.button) {
                buttonDom = collectionDom.button;
            }

            if (inCollection && collectionDom.buttonLiner) {
                linerDom = collectionDom.buttonLiner;
            }

            // Make sure that the button is available based on whatever requirements
            // it has. For example, Flash buttons require Flash
            if (config.available && !config.available(dt, config)) {
                return false;
            }

            var action = function (e, dt, button, config) {
                config.action.call(dt.button(button), e, dt, button, config);

                $(dt.table().node()).triggerHandler('buttons-action.dt', [
                    dt.button(button), dt, button, config
                ]);
            };

            var tag = config.tag || buttonDom.tag;
            var button = $('<' + tag + '/>')
                .addClass(buttonDom.className)
                .attr('tabindex', this.s.dt.settings()[0].iTabIndex)
                .attr('aria-controls', this.s.dt.table().node().id)
                .on('click.dtb', function (e) {
                    e.preventDefault();

                    if (!button.hasClass(buttonDom.disabled) && config.action) {
                        action(e, dt, button, config);
                    }

                    button.blur();
                })
                .on('keyup.dtb', function (e) {
                    if (e.keyCode === 13) {
                        if (!button.hasClass(buttonDom.disabled) && config.action) {
                            action(e, dt, button, config);
                        }
                    }
                });

            // Make `a` tags act like a link
            if (tag.toLowerCase() === 'a') {
                button.attr('href', '#');
            }

            // Button tags should have `type=button` so they don't have any default behaviour
            if (tag.toLowerCase() === 'button') {
                button.attr('type', 'button');
            }

            if (linerDom.tag) {
                var liner = $('<' + linerDom.tag + '/>')
                    .html(text(config.text))
                    .addClass(linerDom.className);

                if (linerDom.tag.toLowerCase() === 'a') {
                    liner.attr('href', '#');
                }

                button.append(liner);
            }
            else {
                button.html(text(config.text));
            }

            if (config.enabled === false) {
                button.addClass(buttonDom.disabled);
            }

            if (config.className) {
                button.addClass(config.className);
            }

            if (config.titleAttr) {
                button.attr('title', text(config.titleAttr));
            }

            if (config.attr) {
                button.attr(config.attr);
            }

            if (!config.namespace) {
                config.namespace = '.dt-button-' + (_buttonCounter++);
            }

            var buttonContainer = this.c.dom.buttonContainer;
            var inserter;
            if (buttonContainer && buttonContainer.tag) {
                inserter = $('<' + buttonContainer.tag + '/>')
                    .addClass(buttonContainer.className)
                    .append(button);
            }
            else {
                inserter = button;
            }

            this._addKey(config);

            return {
                conf: config,
                node: button.get(0),
                inserter: inserter,
                buttons: [],
                inCollection: inCollection,
                collection: null
            };
        },

        /**
         * Get the button object from a node (recursive)
         * @param  {node} node Button node
         * @param  {array} [buttons] Button array, uses base if not defined
         * @return {object} Button object
         * @private
         */
        _nodeToButton: function (node, buttons) {
            if (!buttons) {
                buttons = this.s.buttons;
            }

            for (var i = 0, ien = buttons.length; i < ien; i++) {
                if (buttons[i].node === node) {
                    return buttons[i];
                }

                if (buttons[i].buttons.length) {
                    var ret = this._nodeToButton(node, buttons[i].buttons);

                    if (ret) {
                        return ret;
                    }
                }
            }
        },

        /**
         * Get container array for a button from a button node (recursive)
         * @param  {node} node Button node
         * @param  {array} [buttons] Button array, uses base if not defined
         * @return {array} Button's host array
         * @private
         */
        _nodeToHost: function (node, buttons) {
            if (!buttons) {
                buttons = this.s.buttons;
            }

            for (var i = 0, ien = buttons.length; i < ien; i++) {
                if (buttons[i].node === node) {
                    return buttons;
                }

                if (buttons[i].buttons.length) {
                    var ret = this._nodeToHost(node, buttons[i].buttons);

                    if (ret) {
                        return ret;
                    }
                }
            }
        },

        /**
         * Handle a key press - determine if any button's key configured matches
         * what was typed and trigger the action if so.
         * @param  {string} character The character pressed
         * @param  {object} e Key event that triggered this call
         * @private
         */
        _keypress: function (character, e) {
            // Check if this button press already activated on another instance of Buttons
            if (e._buttonsHandled) {
                return;
            }

            var run = function (conf, node) {
                if (!conf.key) {
                    return;
                }

                if (conf.key === character) {
                    e._buttonsHandled = true;
                    $(node).click();
                }
                else if ($.isPlainObject(conf.key)) {
                    if (conf.key.key !== character) {
                        return;
                    }

                    if (conf.key.shiftKey && !e.shiftKey) {
                        return;
                    }

                    if (conf.key.altKey && !e.altKey) {
                        return;
                    }

                    if (conf.key.ctrlKey && !e.ctrlKey) {
                        return;
                    }

                    if (conf.key.metaKey && !e.metaKey) {
                        return;
                    }

                    // Made it this far - it is good
                    e._buttonsHandled = true;
                    $(node).click();
                }
            };

            var recurse = function (a) {
                for (var i = 0, ien = a.length; i < ien; i++) {
                    run(a[i].conf, a[i].node);

                    if (a[i].buttons.length) {
                        recurse(a[i].buttons);
                    }
                }
            };

            recurse(this.s.buttons);
        },

        /**
         * Remove a key from the key listener for this instance (to be used when a
         * button is removed)
         * @param  {object} conf Button configuration
         * @private
         */
        _removeKey: function (conf) {
            if (conf.key) {
                var character = $.isPlainObject(conf.key) ?
                    conf.key.key :
                    conf.key;

                // Remove only one character, as multiple buttons could have the
                // same listening key
                var a = this.s.listenKeys.split('');
                var idx = $.inArray(character, a);
                a.splice(idx, 1);
                this.s.listenKeys = a.join('');
            }
        },

        /**
         * Resolve a button configuration
         * @param  {string|function|object} conf Button config to resolve
         * @return {object} Button configuration
         * @private
         */
        _resolveExtends: function (conf) {
            var dt = this.s.dt;
            var i, ien;
            var toConfObject = function (base) {
                var loop = 0;

                // Loop until we have resolved to a button configuration, or an
                // array of button configurations (which will be iterated
                // separately)
                while (!$.isPlainObject(base) && !$.isArray(base)) {
                    if (base === undefined) {
                        return;
                    }

                    if (typeof base === 'function') {
                        base = base(dt, conf);

                        if (!base) {
                            return false;
                        }
                    }
                    else if (typeof base === 'string') {
                        if (!_dtButtons[base]) {
                            throw 'Unknown button type: ' + base;
                        }

                        base = _dtButtons[base];
                    }

                    loop++;
                    if (loop > 30) {
                        // Protect against misconfiguration killing the browser
                        throw 'Buttons: Too many iterations';
                    }
                }

                return $.isArray(base) ?
                    base :
                    $.extend({}, base);
            };

            conf = toConfObject(conf);

            while (conf && conf.extend) {
                // Use `toConfObject` in case the button definition being extended
                // is itself a string or a function
                if (!_dtButtons[conf.extend]) {
                    throw 'Cannot extend unknown button type: ' + conf.extend;
                }

                var objArray = toConfObject(_dtButtons[conf.extend]);
                if ($.isArray(objArray)) {
                    return objArray;
                }
                else if (!objArray) {
                    // This is a little brutal as it might be possible to have a
                    // valid button without the extend, but if there is no extend
                    // then the host button would be acting in an undefined state
                    return false;
                }

                // Stash the current class name
                var originalClassName = objArray.className;

                conf = $.extend({}, objArray, conf);

                // The extend will have overwritten the original class name if the
                // `conf` object also assigned a class, but we want to concatenate
                // them so they are list that is combined from all extended buttons
                if (originalClassName && conf.className !== originalClassName) {
                    conf.className = originalClassName + ' ' + conf.className;
                }

                // Buttons to be added to a collection  -gives the ability to define
                // if buttons should be added to the start or end of a collection
                var postfixButtons = conf.postfixButtons;
                if (postfixButtons) {
                    if (!conf.buttons) {
                        conf.buttons = [];
                    }

                    for (i = 0, ien = postfixButtons.length; i < ien; i++) {
                        conf.buttons.push(postfixButtons[i]);
                    }

                    conf.postfixButtons = null;
                }

                var prefixButtons = conf.prefixButtons;
                if (prefixButtons) {
                    if (!conf.buttons) {
                        conf.buttons = [];
                    }

                    for (i = 0, ien = prefixButtons.length; i < ien; i++) {
                        conf.buttons.splice(i, 0, prefixButtons[i]);
                    }

                    conf.prefixButtons = null;
                }

                // Although we want the `conf` object to overwrite almost all of
                // the properties of the object being extended, the `extend`
                // property should come from the object being extended
                conf.extend = objArray.extend;
            }

            return conf;
        }
    });


    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Statics
 */

    /**
     * Show / hide a background layer behind a collection
     * @param  {boolean} Flag to indicate if the background should be shown or
     *   hidden
     * @param  {string} Class to assign to the background
     * @static
     */
    Buttons.background = function (show, className, fade, insertPoint) {
        if (fade === undefined) {
            fade = 400;
        }
        if (!insertPoint) {
            insertPoint = document.body;
        }

        if (show) {
            $('
') .addClass(className) .css('display', 'none') .insertAfter(insertPoint) .fadeIn(fade); } else { $('div.' + className) .fadeOut(fade, function () { $(this) .removeClass(className) .remove(); }); } }; /** * Instance selector - select Buttons instances based on an instance selector * value from the buttons assigned to a DataTable. This is only useful if * multiple instances are attached to a DataTable. * @param {string|int|array} Instance selector - see `instance-selector` * documentation on the DataTables site * @param {array} Button instance array that was attached to the DataTables * settings object * @return {array} Buttons instances * @static */ Buttons.instanceSelector = function (group, buttons) { if (!group) { return $.map(buttons, function (v) { return v.inst; }); } var ret = []; var names = $.map(buttons, function (v) { return v.name; }); // Flatten the group selector into an array of single options var process = function (input) { if ($.isArray(input)) { for (var i = 0, ien = input.length; i < ien; i++) { process(input[i]); } return; } if (typeof input === 'string') { if (input.indexOf(',') !== -1) { // String selector, list of names process(input.split(',')); } else { // String selector individual name var idx = $.inArray($.trim(input), names); if (idx !== -1) { ret.push(buttons[idx].inst); } } } else if (typeof input === 'number') { // Index selector ret.push(buttons[input].inst); } }; process(group); return ret; }; /** * Button selector - select one or more buttons from a selector input so some * operation can be performed on them. * @param {array} Button instances array that the selector should operate on * @param {string|int|node|jQuery|array} Button selector - see * `button-selector` documentation on the DataTables site * @return {array} Array of objects containing `inst` and `idx` properties of * the selected buttons so you know which instance each button belongs to. * @static */ Buttons.buttonSelector = function (insts, selector) { var ret = []; var nodeBuilder = function (a, buttons, baseIdx) { var button; var idx; for (var i = 0, ien = buttons.length; i < ien; i++) { button = buttons[i]; if (button) { idx = baseIdx !== undefined ? baseIdx + i : i + ''; a.push({ node: button.node, name: button.conf.name, idx: idx }); if (button.buttons) { nodeBuilder(a, button.buttons, idx + '-'); } } } }; var run = function (selector, inst) { var i, ien; var buttons = []; nodeBuilder(buttons, inst.s.buttons); var nodes = $.map(buttons, function (v) { return v.node; }); if ($.isArray(selector) || selector instanceof $) { for (i = 0, ien = selector.length; i < ien; i++) { run(selector[i], inst); } return; } if (selector === null || selector === undefined || selector === '*') { // Select all for (i = 0, ien = buttons.length; i < ien; i++) { ret.push({ inst: inst, node: buttons[i].node }); } } else if (typeof selector === 'number') { // Main button index selector ret.push({ inst: inst, node: inst.s.buttons[selector].node }); } else if (typeof selector === 'string') { if (selector.indexOf(',') !== -1) { // Split var a = selector.split(','); for (i = 0, ien = a.length; i < ien; i++) { run($.trim(a[i]), inst); } } else if (selector.match(/^\d+(\-\d+)*$/)) { // Sub-button index selector var indexes = $.map(buttons, function (v) { return v.idx; }); ret.push({ inst: inst, node: buttons[$.inArray(selector, indexes)].node }); } else if (selector.indexOf(':name') !== -1) { // Button name selector var name = selector.replace(':name', ''); for (i = 0, ien = buttons.length; i < ien; i++) { if (buttons[i].name === name) { ret.push({ inst: inst, node: buttons[i].node }); } } } else { // jQuery selector on the nodes $(nodes).filter(selector).each(function () { ret.push({ inst: inst, node: this }); }); } } else if (typeof selector === 'object' && selector.nodeName) { // Node selector var idx = $.inArray(selector, nodes); if (idx !== -1) { ret.push({ inst: inst, node: nodes[idx] }); } } }; for (var i = 0, ien = insts.length; i < ien; i++) { var inst = insts[i]; run(selector, inst); } return ret; }; /** * Buttons defaults. For full documentation, please refer to the docs/option * directory or the DataTables site. * @type {Object} * @static */ Buttons.defaults = { buttons: ['copy', 'excel', 'csv', 'pdf', 'print'], name: 'main', tabIndex: 0, dom: { container: { tag: 'div', className: 'dt-buttons' }, collection: { tag: 'div', className: 'dt-button-collection' }, button: { // Flash buttons will not work with `