File Manager Lite
Dir:
/home/u540325668/domains/sostabazar.in/public_html/public/admin/plugins/datatables-buttons/js
Upload
[..]
buttons.bootstrap4.min.js (1.02 KB)
Edit
Rename
Del
buttons.colVis.js (5.28 KB)
Edit
Rename
Del
buttons.colVis.min.js (2.73 KB)
Edit
Rename
Del
buttons.flash.js (45.09 KB)
Edit
Rename
Del
buttons.flash.min.js (25.43 KB)
Edit
Rename
Del
buttons.print.js (4.95 KB)
Edit
Rename
Del
buttons.print.min.js (2.16 KB)
Edit
Rename
Del
dataTables.buttons.js (48.24 KB)
Edit
Rename
Del
dataTables.buttons.min.js (19.05 KB)
Edit
Rename
Del
Edit: dataTables.buttons.js
/*! Buttons for DataTables 1.6.1 * ©2016-2019 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 not created with a `new` keyword then we return a wrapper function that // will take the settings object for a DT. This allows easy use of new instances // with the `layout` option - e.g. `topLeft: $.fn.dataTable.Buttons( ... )`. if ( !(this instanceof Buttons) ) { return function (settings) { return new Buttons( settings, dt ).container(); }; } // 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, base !== undefined, 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 of the buttons container if no button is given * @param {node} [node] Button node * @return {jQuery} Button element, or container */ node: function ( node ) { if ( ! node ) { return this.dom.container; } var button = this._nodeToButton( node ); return $(button.node); }, /** * Set / get a processing class on the selected button * @param {element} node Triggering button node * @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 dt = this.s.dt; var button = this._nodeToButton( node ); if ( flag === undefined ) { return $(button.node).hasClass( 'processing' ); } $(button.node).toggleClass( 'processing', flag ); $(dt.table().node()).triggerHandler( 'buttons-processing.dt', [ flag, dt.button( node ), dt, $(node), button.conf ] ); 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 ) { built.collection = $('<'+this.c.dom.collection.tag+'/>'); 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 clickBlurs = config.clickBlurs === undefined ? true : config.clickBlurs 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 ); } if( clickBlurs ) { 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 ); // Style integration callback for DOM manipulation // Note that this is _not_ documented. It is currently // for style integration only if( this.c.buttonCreated ) { inserter = this.c.buttonCreated( config, inserter ); } 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; }, /** * Display (and replace if there is an existing one) a popover attached to a button * @param {string|node} content Content to show * @param {DataTable.Api} hostButton DT API instance of the button * @param {object} inOpts Options (see object below for all options) */ _popover: function ( content, hostButton, inOpts ) { var dt = hostButton; var buttonsSettings = this.c; var options = $.extend( { align: 'button-left', // button-right, dt-container autoClose: false, background: true, backgroundClassName: 'dt-button-background', contentClassName: buttonsSettings.dom.collection.className, collectionLayout: '', collectionTitle: '', dropup: false, fade: 400, rightAlignClassName: 'dt-button-right', tag: buttonsSettings.dom.collection.tag }, inOpts ); var hostNode = hostButton.node(); var close = function () { $('.dt-button-collection').stop().fadeOut( options.fade, function () { $(this).detach(); } ); $(dt.buttons( '[aria-haspopup="true"][aria-expanded="true"]' ).nodes()) .attr('aria-expanded', 'false'); $('div.dt-button-background').off( 'click.dtb-collection' ); Buttons.background( false, options.backgroundClassName, options.fade, hostNode ); $('body').off( '.dtb-collection' ); dt.off( 'buttons-action.b-internal' ); }; if (content === false) { close(); } var existingExpanded = $(dt.buttons( '[aria-haspopup="true"][aria-expanded="true"]' ).nodes()); if ( existingExpanded.length ) { hostNode = existingExpanded.eq(0); close(); } var display = $('<div/>') .addClass('dt-button-collection') .addClass(options.collectionLayout) .css('display', 'none'); content = $(content) .addClass(options.contentClassName) .attr('role', 'menu') .appendTo(display); hostNode.attr( 'aria-expanded', 'true' ); if ( hostNode.parents('body')[0] !== document.body ) { hostNode = document.body.lastChild; } if ( options.collectionTitle ) { display.prepend('<div class="dt-button-collection-title">'+options.collectionTitle+'</div>'); } display .insertAfter( hostNode ) .fadeIn( options.fade ); var tableContainer = $( hostButton.table().container() ); var position = display.css( 'position' ); if ( options.align === 'dt-container' ) { hostNode = hostNode.parent(); display.css('width', tableContainer.width()); } if ( position === 'absolute' ) { var hostPosition = hostNode.position(); display.css( { top: hostPosition.top + hostNode.outerHeight(), left: hostPosition.left } ); // calculate overflow when positioned beneath var collectionHeight = display.outerHeight(); var collectionWidth = display.outerWidth(); var tableBottom = tableContainer.offset().top + tableContainer.height(); var listBottom = hostPosition.top + hostNode.outerHeight() + collectionHeight; var bottomOverflow = listBottom - tableBottom; // calculate overflow when positioned above var listTop = hostPosition.top - collectionHeight; var tableTop = tableContainer.offset().top; var topOverflow = tableTop - listTop; // if bottom overflow is larger, move to the top because it fits better, or if dropup is requested var moveTop = hostPosition.top - collectionHeight - 5; if ( (bottomOverflow > topOverflow || options.dropup) && -moveTop < tableTop ) { display.css( 'top', moveTop); } // Right alignment is enabled on a class, e.g. bootstrap: // $.fn.dataTable.Buttons.defaults.dom.collection.className += " dropdown-menu-right"; if ( display.hasClass( options.rightAlignClassName ) || options.align === 'button-right' ) { display.css( 'left', hostPosition.left + hostNode.outerWidth() - collectionWidth ); } // Right alignment in table container var listRight = hostPosition.left + collectionWidth; var tableRight = tableContainer.offset().left + tableContainer.width(); if ( listRight > tableRight ) { display.css( 'left', hostPosition.left - ( listRight - tableRight ) ); } // Right alignment to window var listOffsetRight = hostNode.offset().left + collectionWidth; if ( listOffsetRight > $(window).width() ) { display.css( 'left', hostPosition.left - (listOffsetRight-$(window).width()) ); } } else { // Fix position - centre on screen var top = display.height() / 2; if ( top > $(window).height() / 2 ) { top = $(window).height() / 2; } display.css( 'marginTop', top*-1 ); } if ( options.background ) { Buttons.background( true, options.backgroundClassName, options.fade, hostNode ); } // This is bonkers, but if we don't have a click listener on the // background element, iOS Safari will ignore the body click // listener below. An empty function here is all that is // required to make it work... $('div.dt-button-background').on( 'click.dtb-collection', function () {} ); $('body') .on( 'click.dtb-collection', function (e) { // andSelf is deprecated in jQ1.8, but we want 1.7 compat var back = $.fn.addBack ? 'addBack' : 'andSelf'; if ( ! $(e.target).parents()[back]().filter( content ).length ) { close(); } } ) .on( 'keyup.dtb-collection', function (e) { if ( e.keyCode === 27 ) { close(); } } ); if ( options.autoClose ) { setTimeout( function () { dt.on( 'buttons-action.b-internal', function (e, btn, dt, node) { if ( node[0] === hostNode[0] ) { return; } close(); } ); }, 0); } } } ); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 ) { $('<div/>') .addClass( className ) .css( 'display', 'none' ) .insertAfter( insertPoint ) .stop() .fadeIn( fade ); } else { $('div.'+className) .stop() .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 === undefined || group === null ) { 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: '' }, button: { // Flash buttons will not work with `<button>` in IE - it has to be `<a>` tag: 'ActiveXObject' in window ? 'a' : 'button', className: 'dt-button', active: 'active', disabled: 'disabled' }, buttonLiner: { tag: 'span', className: '' } } }; /** * Version information * @type {string} * @static */ Buttons.version = '1.6.1'; $.extend( _dtButtons, { collection: { text: function ( dt ) { return dt.i18n( 'buttons.collection', 'Collection' ); }, className: 'buttons-collection', init: function ( dt, button, config ) { button.attr( 'aria-expanded', false ); }, action: function ( e, dt, button, config ) { e.stopPropagation(); if ( config._collection.parents('body').length ) { this.popover(false, config); } else { this.popover(config._collection, config); } }, attr: { 'aria-haspopup': true } // Also the popover options, defined in Buttons.popover }, copy: function ( dt, conf ) { if ( _dtButtons.copyHtml5 ) { return 'copyHtml5'; } if ( _dtButtons.copyFlash && _dtButtons.copyFlash.available( dt, conf ) ) { return 'copyFlash'; } }, csv: function ( dt, conf ) { // Common option that will use the HTML5 or Flash export buttons if ( _dtButtons.csvHtml5 && _dtButtons.csvHtml5.available( dt, conf ) ) { return 'csvHtml5'; } if ( _dtButtons.csvFlash && _dtButtons.csvFlash.available( dt, conf ) ) { return 'csvFlash'; } }, excel: function ( dt, conf ) { // Common option that will use the HTML5 or Flash export buttons if ( _dtButtons.excelHtml5 && _dtButtons.excelHtml5.available( dt, conf ) ) { return 'excelHtml5'; } if ( _dtButtons.excelFlash && _dtButtons.excelFlash.available( dt, conf ) ) { return 'excelFlash'; } }, pdf: function ( dt, conf ) { // Common option that will use the HTML5 or Flash export buttons if ( _dtButtons.pdfHtml5 && _dtButtons.pdfHtml5.available( dt, conf ) ) { return 'pdfHtml5'; } if ( _dtButtons.pdfFlash && _dtButtons.pdfFlash.available( dt, conf ) ) { return 'pdfFlash'; } }, pageLength: function ( dt ) { var lengthMenu = dt.settings()[0].aLengthMenu; var vals = $.isArray( lengthMenu[0] ) ? lengthMenu[0] : lengthMenu; var lang = $.isArray( lengthMenu[0] ) ? lengthMenu[1] : lengthMenu; var text = function ( dt ) { return dt.i18n( 'buttons.pageLength', { "-1": 'Show all rows', _: 'Show %d rows' }, dt.page.len() ); }; return { extend: 'collection', text: text, className: 'buttons-page-length', autoClose: true, buttons: $.map( vals, function ( val, i ) { return { text: lang[i], className: 'button-page-length', action: function ( e, dt ) { dt.page.len( val ).draw(); }, init: function ( dt, node, conf ) { var that = this; var fn = function () { that.active( dt.page.len() === val ); }; dt.on( 'length.dt'+conf.namespace, fn ); fn(); }, destroy: function ( dt, node, conf ) { dt.off( 'length.dt'+conf.namespace ); } }; } ), init: function ( dt, node, conf ) { var that = this; dt.on( 'length.dt'+conf.namespace, function () { that.text( conf.text ); } ); }, destroy: function ( dt, node, conf ) { dt.off( 'length.dt'+conf.namespace ); } }; } } ); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DataTables API * * For complete documentation, please refer to the docs/api directory or the * DataTables site */ // Buttons group and individual button selector DataTable.Api.register( 'buttons()', function ( group, selector ) { // Argument shifting if ( selector === undefined ) { selector = group; group = undefined; } this.selector.buttonGroup = group; var res = this.iterator( true, 'table', function ( ctx ) { if ( ctx._buttons ) { return Buttons.buttonSelector( Buttons.instanceSelector( group, ctx._buttons ), selector ); } }, true ); res._groupSelector = group; return res; } ); // Individual button selector DataTable.Api.register( 'button()', function ( group, selector ) { // just run buttons() and truncate var buttons = this.buttons( group, selector ); if ( buttons.length > 1 ) { buttons.splice( 1, buttons.length ); } return buttons; } ); // Active buttons DataTable.Api.registerPlural( 'buttons().active()', 'button().active()', function ( flag ) { if ( flag === undefined ) { return this.map( function ( set ) { return set.inst.active( set.node ); } ); } return this.each( function ( set ) { set.inst.active( set.node, flag ); } ); } ); // Get / set button action DataTable.Api.registerPlural( 'buttons().action()', 'button().action()', function ( action ) { if ( action === undefined ) { return this.map( function ( set ) { return set.inst.action( set.node ); } ); } return this.each( function ( set ) { set.inst.action( set.node, action ); } ); } ); // Enable / disable buttons DataTable.Api.register( ['buttons().enable()', 'button().enable()'], function ( flag ) { return this.each( function ( set ) { set.inst.enable( set.node, flag ); } ); } ); // Disable buttons DataTable.Api.register( ['buttons().disable()', 'button().disable()'], function () { return this.each( function ( set ) { set.inst.disable( set.node ); } ); } ); // Get button nodes DataTable.Api.registerPlural( 'buttons().nodes()', 'button().node()', function () { var jq = $(); // jQuery will automatically reduce duplicates to a single entry $( this.each( function ( set ) { jq = jq.add( set.inst.node( set.node ) ); } ) ); return jq; } ); // Get / set button processing state DataTable.Api.registerPlural( 'buttons().processing()', 'button().processing()', function ( flag ) { if ( flag === undefined ) { return this.map( function ( set ) { return set.inst.processing( set.node ); } ); } return this.each( function ( set ) { set.inst.processing( set.node, flag ); } ); } ); // Get / set button text (i.e. the button labels) DataTable.Api.registerPlural( 'buttons().text()', 'button().text()', function ( label ) { if ( label === undefined ) { return this.map( function ( set ) { return set.inst.text( set.node ); } ); } return this.each( function ( set ) { set.inst.text( set.node, label ); } ); } ); // Trigger a button's action DataTable.Api.registerPlural( 'buttons().trigger()', 'button().trigger()', function () { return this.each( function ( set ) { set.inst.node( set.node ).trigger( 'click' ); } ); } ); // Button resolver to the popover DataTable.Api.register( 'button().popover()', function (content, options) { return this.map( function ( set ) { return set.inst._popover( content, this.button(this[0].node), options ); } ); } ); // Get the container elements DataTable.Api.register( 'buttons().containers()', function () { var jq = $(); var groupSelector = this._groupSelector; // We need to use the group selector directly, since if there are no buttons // the result set will be empty this.iterator( true, 'table', function ( ctx ) { if ( ctx._buttons ) { var insts = Buttons.instanceSelector( groupSelector, ctx._buttons ); for ( var i=0, ien=insts.length ; i<ien ; i++ ) { jq = jq.add( insts[i].container() ); } } } ); return jq; } ); DataTable.Api.register( 'buttons().container()', function () { // API level of nesting is `buttons()` so we can zip into the containers method return this.containers().eq(0); } ); // Add a new button DataTable.Api.register( 'button().add()', function ( idx, conf ) { var ctx = this.context; // Don't use `this` as it could be empty - select the instances directly if ( ctx.length ) { var inst = Buttons.instanceSelector( this._groupSelector, ctx[0]._buttons ); if ( inst.length ) { inst[0].add( conf, idx ); } } return this.button( this._groupSelector, idx ); } ); // Destroy the button sets selected DataTable.Api.register( 'buttons().destroy()', function () { this.pluck( 'inst' ).unique().each( function ( inst ) { inst.destroy(); } ); return this; } ); // Remove a button DataTable.Api.registerPlural( 'buttons().remove()', 'buttons().remove()', function () { this.each( function ( set ) { set.inst.remove( set.node ); } ); return this; } ); // Information box that can be used by buttons var _infoTimer; DataTable.Api.register( 'buttons.info()', function ( title, message, time ) { var that = this; if ( title === false ) { this.off('destroy.btn-info'); $('#datatables_buttons_info').fadeOut( function () { $(this).remove(); } ); clearTimeout( _infoTimer ); _infoTimer = null; return this; } if ( _infoTimer ) { clearTimeout( _infoTimer ); } if ( $('#datatables_buttons_info').length ) { $('#datatables_buttons_info').remove(); } title = title ? '<h2>'+title+'</h2>' : ''; $('<div id="datatables_buttons_info" class="dt-button-info"/>') .html( title ) .append( $('<div/>')[ typeof message === 'string' ? 'html' : 'append' ]( message ) ) .css( 'display', 'none' ) .appendTo( 'body' ) .fadeIn(); if ( time !== undefined && time !== 0 ) { _infoTimer = setTimeout( function () { that.buttons.info( false ); }, time ); } this.on('destroy.btn-info', function () { that.buttons.info(false); }); return this; } ); // Get data from the table for export - this is common to a number of plug-in // buttons so it is included in the Buttons core library DataTable.Api.register( 'buttons.exportData()', function ( options ) { if ( this.context.length ) { return _exportData( new DataTable.Api( this.context[0] ), options ); } } ); // Get information about the export that is common to many of the export data // types (DRY) DataTable.Api.register( 'buttons.exportInfo()', function ( conf ) { if ( ! conf ) { conf = {}; } return { filename: _filename( conf ), title: _title( conf ), messageTop: _message(this, conf.message || conf.messageTop, 'top'), messageBottom: _message(this, conf.messageBottom, 'bottom') }; } ); /** * Get the file name for an exported file. * * @param {object} config Button configuration * @param {boolean} incExtension Include the file name extension */ var _filename = function ( config ) { // Backwards compatibility var filename = config.filename === '*' && config.title !== '*' && config.title !== undefined && config.title !== null && config.title !== '' ? config.title : config.filename; if ( typeof filename === 'function' ) { filename = filename(); } if ( filename === undefined || filename === null ) { return null; } if ( filename.indexOf( '*' ) !== -1 ) { filename = $.trim( filename.replace( '*', $('head > title').text() ) ); } // Strip characters which the OS will object to filename = filename.replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g, ""); var extension = _stringOrFunction( config.extension ); if ( ! extension ) { extension = ''; } return filename + extension; }; /** * Simply utility method to allow parameters to be given as a function * * @param {undefined|string|function} option Option * @return {null|string} Resolved value */ var _stringOrFunction = function ( option ) { if ( option === null || option === undefined ) { return null; } else if ( typeof option === 'function' ) { return option(); } return option; }; /** * Get the title for an exported file. * * @param {object} config Button configuration */ var _title = function ( config ) { var title = _stringOrFunction( config.title ); return title === null ? null : title.indexOf( '*' ) !== -1 ? title.replace( '*', $('head > title').text() || 'Exported data' ) : title; }; var _message = function ( dt, option, position ) { var message = _stringOrFunction( option ); if ( message === null ) { return null; } var caption = $('caption', dt.table().container()).eq(0); if ( message === '*' ) { var side = caption.css( 'caption-side' ); if ( side !== position ) { return null; } return caption.length ? caption.text() : ''; } return message; }; var _exportTextarea = $('<textarea/>')[0]; var _exportData = function ( dt, inOpts ) { var config = $.extend( true, {}, { rows: null, columns: '', modifier: { search: 'applied', order: 'applied' }, orthogonal: 'display', stripHtml: true, stripNewlines: true, decodeEntities: true, trim: true, format: { header: function ( d ) { return strip( d ); }, footer: function ( d ) { return strip( d ); }, body: function ( d ) { return strip( d ); } }, customizeData: null }, inOpts ); var strip = function ( str ) { if ( typeof str !== 'string' ) { return str; } // Always remove script tags str = str.replace( /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '' ); // Always remove comments str = str.replace( /<!\-\-.*?\-\->/g, '' ); if ( config.stripHtml ) { str = str.replace( /<[^>]*>/g, '' ); } if ( config.trim ) { str = str.replace( /^\s+|\s+$/g, '' ); } if ( config.stripNewlines ) { str = str.replace( /\n/g, ' ' ); } if ( config.decodeEntities ) { _exportTextarea.innerHTML = str; str = _exportTextarea.value; } return str; }; var header = dt.columns( config.columns ).indexes().map( function (idx) { var el = dt.column( idx ).header(); return config.format.header( el.innerHTML, idx, el ); } ).toArray(); var footer = dt.table().footer() ? dt.columns( config.columns ).indexes().map( function (idx) { var el = dt.column( idx ).footer(); return config.format.footer( el ? el.innerHTML : '', idx, el ); } ).toArray() : null; // If Select is available on this table, and any rows are selected, limit the export // to the selected rows. If no rows are selected, all rows will be exported. Specify // a `selected` modifier to control directly. var modifier = $.extend( {}, config.modifier ); if ( dt.select && typeof dt.select.info === 'function' && modifier.selected === undefined ) { if ( dt.rows( config.rows, $.extend( { selected: true }, modifier ) ).any() ) { $.extend( modifier, { selected: true } ) } } var rowIndexes = dt.rows( config.rows, modifier ).indexes().toArray(); var selectedCells = dt.cells( rowIndexes, config.columns ); var cells = selectedCells .render( config.orthogonal ) .toArray(); var cellNodes = selectedCells .nodes() .toArray(); var columns = header.length; var rows = columns > 0 ? cells.length / columns : 0; var body = []; var cellCounter = 0; for ( var i=0, ien=rows ; i<ien ; i++ ) { var row = [ columns ]; for ( var j=0 ; j<columns ; j++ ) { row[j] = config.format.body( cells[ cellCounter ], i, j, cellNodes[ cellCounter ] ); cellCounter++; } body[i] = row; } var data = { header: header, footer: footer, body: body }; if ( config.customizeData ) { config.customizeData( data ); } return data; }; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DataTables interface */ // Attach to DataTables objects for global access $.fn.dataTable.Buttons = Buttons; $.fn.DataTable.Buttons = Buttons; // DataTables creation - check if the buttons have been defined for this table, // they will have been if the `B` option was used in `dom`, otherwise we should // create the buttons instance here so they can be inserted into the document // using the API. Listen for `init` for compatibility with pre 1.10.10, but to // be removed in future. $(document).on( 'init.dt plugin-init.dt', function (e, settings) { if ( e.namespace !== 'dt' ) { return; } var opts = settings.oInit.buttons || DataTable.defaults.buttons; if ( opts && ! settings._buttons ) { new Buttons( settings, opts ).container(); } } ); function _init ( settings ) { var api = new DataTable.Api( settings ); var opts = api.init().buttons || DataTable.defaults.buttons; return new Buttons( api, opts ).container(); } // DataTables `dom` feature option DataTable.ext.feature.push( { fnInit: _init, cFeature: "B" } ); // DataTables 2 layout feature if ( DataTable.ext.features ) { DataTable.ext.features.register( 'buttons', _init ); } return Buttons; }));
Simpan