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

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

There is a newer version: 0.66.0.1
Show newest version
/*! KeyTable 2.4.1
 * ©2009-2018 SpryMedia Ltd - datatables.net/license
 */

/**
 * @summary     KeyTable
 * @description Spreadsheet like keyboard navigation for DataTables
 * @version     2.4.1
 * @file        dataTables.keyTable.js
 * @author      SpryMedia Ltd (www.sprymedia.co.uk)
 * @contact     www.sprymedia.co.uk/contact
 * @copyright   Copyright 2009-2018 SpryMedia Ltd.
 *
 * This source file is free software, available under the following license:
 *   MIT license - http://datatables.net/license/mit
 *
 * This source file is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
 *
 * For details please refer to: http://www.datatables.net
 */

(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;


    var KeyTable = function (dt, opts) {
        // Sanity check that we are using DataTables 1.10 or newer
        if (!DataTable.versionCheck || !DataTable.versionCheck('1.10.8')) {
            throw 'KeyTable requires DataTables 1.10.8 or newer';
        }

        // User and defaults configuration object
        this.c = $.extend(true, {},
            DataTable.defaults.keyTable,
            KeyTable.defaults,
            opts
        );

        // Internal settings
        this.s = {
            /** @type {DataTable.Api} DataTables' API instance */
            dt: new DataTable.Api(dt),

            enable: true,

            /** @type {bool} Flag for if a draw is triggered by focus */
            focusDraw: false,

            /** @type {bool} Flag to indicate when waiting for a draw to happen.
             *   Will ignore key presses at this point
             */
            waitingForDraw: false,

            /** @type {object} Information about the last cell that was focused */
            lastFocus: null
        };

        // DOM items
        this.dom = {};

        // Check if row reorder has already been initialised on this table
        var settings = this.s.dt.settings()[0];
        var exisiting = settings.keytable;
        if (exisiting) {
            return exisiting;
        }

        settings.keytable = this;
        this._constructor();
    };


    $.extend(KeyTable.prototype, {
        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         * API methods for DataTables API interface
         */

        /**
         * Blur the table's cell focus
         */
        blur: function () {
            this._blur();
        },

        /**
         * Enable cell focus for the table
         *
         * @param  {string} state Can be `true`, `false` or `-string navigation-only`
         */
        enable: function (state) {
            this.s.enable = state;
        },

        /**
         * Focus on a cell
         * @param  {integer} row    Row index
         * @param  {integer} column Column index
         */
        focus: function (row, column) {
            this._focus(this.s.dt.cell(row, column));
        },

        /**
         * Is the cell focused
         * @param  {object} cell Cell index to check
         * @returns {boolean} true if focused, false otherwise
         */
        focused: function (cell) {
            var lastFocus = this.s.lastFocus;

            if (!lastFocus) {
                return false;
            }

            var lastIdx = this.s.lastFocus.cell.index();
            return cell.row === lastIdx.row && cell.column === lastIdx.column;
        },


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

        /**
         * Initialise the KeyTable instance
         *
         * @private
         */
        _constructor: function () {
            this._tabInput();

            var that = this;
            var dt = this.s.dt;
            var table = $(dt.table().node());

            // Need to be able to calculate the cell positions relative to the table
            if (table.css('position') === 'static') {
                table.css('position', 'relative');
            }

            // Click to focus
            $(dt.table().body()).on('click.keyTable', 'th, td', function (e) {
                if (that.s.enable === false) {
                    return;
                }

                var cell = dt.cell(this);

                if (!cell.any()) {
                    return;
                }

                that._focus(cell, null, false, e);
            });

            // Key events
            $(document).on('keydown.keyTable', function (e) {
                that._key(e);
            });

            // Click blur
            if (this.c.blurable) {
                $(document).on('mousedown.keyTable', function (e) {
                    // Click on the search input will blur focus
                    if ($(e.target).parents('.dataTables_filter').length) {
                        that._blur();
                    }

                    // If the click was inside the DataTables container, don't blur
                    if ($(e.target).parents().filter(dt.table().container()).length) {
                        return;
                    }

                    // Don't blur in Editor form
                    if ($(e.target).parents('div.DTE').length) {
                        return;
                    }

                    // Or an Editor date input
                    if ($(e.target).parents('div.editor-datetime').length) {
                        return;
                    }

                    //If the click was inside the fixed columns container, don't blur
                    if ($(e.target).parents().filter('.DTFC_Cloned').length) {
                        return;
                    }

                    that._blur();
                });
            }

            if (this.c.editor) {
                var editor = this.c.editor;

                // Need to disable KeyTable when the main editor is shown
                editor.on('open.keyTableMain', function (e, mode, action) {
                    if (mode !== 'inline' && that.s.enable) {
                        that.enable(false);

                        editor.one('close.keyTable', function () {
                            that.enable(true);
                        });
                    }
                });

                if (this.c.editOnFocus) {
                    dt.on('key-focus.keyTable key-refocus.keyTable', function (e, dt, cell, orig) {
                        that._editor(null, orig);
                    });
                }

                // Activate Editor when a key is pressed (will be ignored, if
                // already active).
                dt.on('key.keyTable', function (e, dt, key, cell, orig) {
                    that._editor(key, orig);
                });
            }

            // Stave saving
            if (dt.settings()[0].oFeatures.bStateSave) {
                dt.on('stateSaveParams.keyTable', function (e, s, d) {
                    d.keyTable = that.s.lastFocus ?
                        that.s.lastFocus.cell.index() :
                        null;
                });
            }

            // Redraw - retain focus on the current cell
            dt.on('draw.keyTable', function (e) {
                if (that.s.focusDraw) {
                    return;
                }

                var lastFocus = that.s.lastFocus;

                if (lastFocus && lastFocus.node && $(lastFocus.node).closest('body') === document.body) {
                    var relative = that.s.lastFocus.relative;
                    var info = dt.page.info();
                    var row = relative.row + info.start;

                    if (info.recordsDisplay === 0) {
                        return;
                    }

                    // Reverse if needed
                    if (row >= info.recordsDisplay) {
                        row = info.recordsDisplay - 1;
                    }

                    that._focus(row, relative.column, true, e);
                }
            });

            // Clipboard support
            if (this.c.clipboard) {
                this._clipboard();
            }

            dt.on('destroy.keyTable', function () {
                dt.off('.keyTable');
                $(dt.table().body()).off('click.keyTable', 'th, td');
                $(document)
                    .off('keydown.keyTable')
                    .off('click.keyTable')
                    .off('copy.keyTable')
                    .off('paste.keyTable');
            });

            // Initial focus comes from state or options
            var state = dt.state.loaded();

            if (state && state.keyTable) {
                // Wait until init is done
                dt.one('init', function () {
                    var cell = dt.cell(state.keyTable);

                    // Ensure that the saved cell still exists
                    if (cell.any()) {
                        cell.focus();
                    }
                });
            }
            else if (this.c.focus) {
                dt.cell(this.c.focus).focus();
            }
        },


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

        /**
         * Blur the control
         *
         * @private
         */
        _blur: function () {
            if (!this.s.enable || !this.s.lastFocus) {
                return;
            }

            var cell = this.s.lastFocus.cell;

            $(cell.node()).removeClass(this.c.className);
            this.s.lastFocus = null;

            this._updateFixedColumns(cell.index().column);

            this._emitEvent('key-blur', [this.s.dt, cell]);
        },


        /**
         * Clipboard interaction handlers
         *
         * @private
         */
        _clipboard: function () {
            var dt = this.s.dt;
            var that = this;

            // IE8 doesn't support getting selected text
            if (!window.getSelection) {
                return;
            }

            $(document).on('copy.keyTable', function (ejq) {
                var e = ejq.originalEvent;
                var selection = window.getSelection().toString();
                var focused = that.s.lastFocus;

                // Only copy cell text to clipboard if there is no other selection
                // and there is a focused cell
                if (!selection && focused) {
                    e.clipboardData.setData(
                        'text/plain',
                        focused.cell.render(that.c.clipboardOrthogonal)
                    );
                    e.preventDefault();
                }
            });

            $(document).on('paste.keyTable', function (ejq) {
                var e = ejq.originalEvent;
                var focused = that.s.lastFocus;
                var activeEl = document.activeElement;
                var editor = that.c.editor;
                var pastedText;

                if (focused && (!activeEl || activeEl.nodeName.toLowerCase() === 'body')) {
                    e.preventDefault();

                    if (window.clipboardData && window.clipboardData.getData) {
                        // IE
                        pastedText = window.clipboardData.getData('Text');
                    }
                    else if (e.clipboardData && e.clipboardData.getData) {
                        // Everything else
                        pastedText = e.clipboardData.getData('text/plain');
                    }

                    if (editor) {
                        // Got Editor - need to activate inline editing,
                        // set the value and submit
                        editor
                            .inline(focused.cell.index())
                            .set(editor.displayed()[0], pastedText)
                            .submit();
                    }
                    else {
                        // No editor, so just dump the data in
                        focused.cell.data(pastedText);
                        dt.draw(false);
                    }
                }
            });
        },


        /**
         * Get an array of the column indexes that KeyTable can operate on. This
         * is a merge of the user supplied columns and the visible columns.
         *
         * @private
         */
        _columns: function () {
            var dt = this.s.dt;
            var user = dt.columns(this.c.columns).indexes();
            var out = [];

            dt.columns(':visible').every(function (i) {
                if (user.indexOf(i) !== -1) {
                    out.push(i);
                }
            });

            return out;
        },


        /**
         * Perform excel like navigation for Editor by triggering an edit on key
         * press
         *
         * @param  {integer} key Key code for the pressed key
         * @param  {object} orig Original event
         * @private
         */
        _editor: function (key, orig) {
            var that = this;
            var dt = this.s.dt;
            var editor = this.c.editor;

            // Do nothing if there is already an inline edit in this cell
            if ($('div.DTE', this.s.lastFocus.cell.node()).length) {
                return;
            }

            // Don't activate Editor on control key presses
            if (
                (key >= 0x00 && key <= 0x09) ||
                key === 0x0b ||
                key === 0x0c ||
                (key >= 0x0e && key <= 0x1f) ||
                (key >= 0x70 && key <= 0x7b) ||
                (key >= 0x7f && key <= 0x9f)
            ) {
                return;
            }

            orig.stopPropagation();

            // Return key should do nothing - for textareas it would empty the
            // contents
            if (key === 13) {
                orig.preventDefault();
            }

            var editInline = function () {
                editor
                    .one('open.keyTable', function () {
                        // Remove cancel open
                        editor.off('cancelOpen.keyTable');

                        // Excel style - select all text
                        if (that.c.editAutoSelect) {
                            $('div.DTE_Field_InputControl input, div.DTE_Field_InputControl textarea').select();
                        }

                        // Reduce the keys the Keys listens for
                        dt.keys.enable(that.c.editorKeys);

                        // On blur of the navigation submit
                        dt.one('key-blur.editor', function () {
                            if (editor.displayed()) {
                                editor.submit();
                            }
                        });

                        // Restore full key navigation on close
                        editor.one('close', function () {
                            dt.keys.enable(true);
                            dt.off('key-blur.editor');
                        });
                    })
                    .one('cancelOpen.keyTable', function () {
                        // `preOpen` can cancel the display of the form, so it
                        // might be that the open event handler isn't needed
                        editor.off('open.keyTable');
                    })
                    .inline(that.s.lastFocus.cell.index());
            };

            // Editor 1.7 listens for `return` on keyup, so if return is the trigger
            // key, we need to wait for `keyup` otherwise Editor would just submit
            // the content triggered by this keypress.
            if (key === 13) {
                $(document).one('keyup', function () { // immediately removed
                    editInline();
                });
            }
            else {
                editInline();
            }
        },


        /**
         * Emit an event on the DataTable for listeners
         *
         * @param  {string} name Event name
         * @param  {array} args Event arguments
         * @private
         */
        _emitEvent: function (name, args) {
            this.s.dt.iterator('table', function (ctx, i) {
                $(ctx.nTable).triggerHandler(name, args);
            });
        },


        /**
         * Focus on a particular cell, shifting the table's paging if required
         *
         * @param  {DataTables.Api|integer} row Can be given as an API instance that
         *   contains the cell to focus or as an integer. As the latter it is the
         *   visible row index (from the whole data set) - NOT the data index
         * @param  {integer} [column] Not required if a cell is given as the first
         *   parameter. Otherwise this is the column data index for the cell to
         *   focus on
         * @param {boolean} [shift=true] Should the viewport be moved to show cell
         * @private
         */
        _focus: function (row, column, shift, originalEvent) {
            var that = this;
            var dt = this.s.dt;
            var pageInfo = dt.page.info();
            var lastFocus = this.s.lastFocus;

            if (!originalEvent) {
                originalEvent = null;
            }

            if (!this.s.enable) {
                return;
            }

            if (typeof row !== 'number') {
                // Its an API instance - check that there is actually a row
                if (!row.any()) {
                    return;
                }

                // Convert the cell to a row and column
                var index = row.index();
                column = index.column;
                row = dt
                    .rows({filter: 'applied', order: 'applied'})
                    .indexes()
                    .indexOf(index.row);

                // For server-side processing normalise the row by adding the start
                // point, since `rows().indexes()` includes only rows that are
                // available at the client-side
                if (pageInfo.serverSide) {
                    row += pageInfo.start;
                }
            }

            // Is the row on the current page? If not, we need to redraw to show the
            // page
            if (pageInfo.length !== -1 && (row < pageInfo.start || row >= pageInfo.start + pageInfo.length)) {
                this.s.focusDraw = true;
                this.s.waitingForDraw = true;

                dt
                    .one('draw', function () {
                        that.s.focusDraw = false;
                        that.s.waitingForDraw = false;
                        that._focus(row, column, undefined, originalEvent);
                    })
                    .page(Math.floor(row / pageInfo.length))
                    .draw(false);

                return;
            }

            // In the available columns?
            if ($.inArray(column, this._columns()) === -1) {
                return;
            }

            // De-normalise the server-side processing row, so we select the row
            // in its displayed position
            if (pageInfo.serverSide) {
                row -= pageInfo.start;
            }

            // Get the cell from the current position - ignoring any cells which might
            // not have been rendered (therefore can't use `:eq()` selector).
            var cells = dt.cells(null, column, {search: 'applied', order: 'applied'}).flatten();
            var cell = dt.cell(cells[row]);

            if (lastFocus) {
                // Don't trigger a refocus on the same cell
                if (lastFocus.node === cell.node()) {
                    this._emitEvent('key-refocus', [this.s.dt, cell, originalEvent || null]);
                    return;
                }

                // Otherwise blur the old focus
                this._blur();
            }

            var node = $(cell.node());
            node.addClass(this.c.className);

            this._updateFixedColumns(column);

            // Shift viewpoint and page to make cell visible
            if (shift === undefined || shift === true) {
                this._scroll($(window), $(document.body), node, 'offset');

                var bodyParent = dt.table().body().parentNode;
                if (bodyParent !== dt.table().header().parentNode) {
                    var parent = $(bodyParent.parentNode);

                    this._scroll(parent, parent, node, 'position');
                }
            }

            // Event and finish
            this.s.lastFocus = {
                cell: cell,
                node: cell.node(),
                relative: {
                    row: dt.rows({page: 'current'}).indexes().indexOf(cell.index().row),
                    column: cell.index().column
                }
            };

            this._emitEvent('key-focus', [this.s.dt, cell, originalEvent || null]);
            dt.state.save();
        },


        /**
         * Handle key press
         *
         * @param  {object} e Event
         * @private
         */
        _key: function (e) {
            // If we are waiting for a draw to happen from another key event, then
            // do nothing for this new key press.
            if (this.s.waitingForDraw) {
                e.preventDefault();
                return;
            }

            var enable = this.s.enable;
            var navEnable = enable === true || enable === 'navigation-only';
            if (!enable) {
                return;
            }

            if ((e.keyCode === 0 || e.ctrlKey || e.metaKey || e.altKey) && !(e.ctrlKey && e.altKey)) {
                return;
            }

            // If not focused, then there is no key action to take
            var lastFocus = this.s.lastFocus;
            if (!lastFocus) {
                return;
            }

            var that = this;
            var dt = this.s.dt;
            var scrolling = this.s.dt.settings()[0].oScroll.sY ? true : false;

            // If we are not listening for this key, do nothing
            if (this.c.keys && $.inArray(e.keyCode, this.c.keys) === -1) {
                return;
            }

            switch (e.keyCode) {
                case 9: // tab
                    // `enable` can be tab-only
                    this._shift(e, e.shiftKey ? 'left' : 'right', true);
                    break;

                case 27: // esc
                    if (this.s.blurable && enable === true) {
                        this._blur();
                    }
                    break;

                case 33: // page up (previous page)
                case 34: // page down (next page)
                    if (navEnable && !scrolling) {
                        e.preventDefault();

                        dt
                            .page(e.keyCode === 33 ? 'previous' : 'next')
                            .draw(false);
                    }
                    break;

                case 35: // end (end of current page)
                case 36: // home (start of current page)
                    if (navEnable) {
                        e.preventDefault();
                        var indexes = dt.cells({page: 'current'}).indexes();
                        var colIndexes = this._columns();

                        this._focus(dt.cell(
                            indexes[e.keyCode === 35 ? indexes.length - 1 : colIndexes[0]]
                        ), null, true, e);
                    }
                    break;

                case 37: // left arrow
                    if (navEnable) {
                        this._shift(e, 'left');
                    }
                    break;

                case 38: // up arrow
                    if (navEnable) {
                        this._shift(e, 'up');
                    }
                    break;

                case 39: // right arrow
                    if (navEnable) {
                        this._shift(e, 'right');
                    }
                    break;

                case 40: // down arrow
                    if (navEnable) {
                        this._shift(e, 'down');
                    }
                    break;

                default:
                    // Everything else - pass through only when fully enabled
                    if (enable === true) {
                        this._emitEvent('key', [dt, e.keyCode, this.s.lastFocus.cell, e]);
                    }
                    break;
            }
        },


        /**
         * Scroll a container to make a cell visible in it. This can be used for
         * both DataTables scrolling and native window scrolling.
         *
         * @param  {jQuery} container Scrolling container
         * @param  {jQuery} scroller  Item being scrolled
         * @param  {jQuery} cell      Cell in the scroller
         * @param  {string} posOff    `position` or `offset` - which to use for the
         *   calculation. `offset` for the document, otherwise `position`
         * @private
         */
        _scroll: function (container, scroller, cell, posOff) {
            var offset = cell[posOff]();
            var height = cell.outerHeight();
            var width = cell.outerWidth();

            var scrollTop = scroller.scrollTop();
            var scrollLeft = scroller.scrollLeft();
            var containerHeight = container.height();
            var containerWidth = container.width();

            // If Scroller is being used, the table can be `position: absolute` and that
            // needs to be taken account of in the offset. If no Scroller, this will be 0
            if (posOff === 'position') {
                offset.top += parseInt(cell.closest('table').css('top'), 10);
            }

            // Top correction
            if (offset.top < scrollTop) {
                scroller.scrollTop(offset.top);
            }

            // Left correction
            if (offset.left < scrollLeft) {
                scroller.scrollLeft(offset.left);
            }

            // Bottom correction
            if (offset.top + height > scrollTop + containerHeight && height < containerHeight) {
                scroller.scrollTop(offset.top + height - containerHeight);
            }

            // Right correction
            if (offset.left + width > scrollLeft + containerWidth && width < containerWidth) {
                scroller.scrollLeft(offset.left + width - containerWidth);
            }
        },


        /**
         * Calculate a single offset movement in the table - up, down, left and
         * right and then perform the focus if possible
         *
         * @param  {object}  e           Event object
         * @param  {string}  direction   Movement direction
         * @param  {boolean} keyBlurable `true` if the key press can result in the
         *   table being blurred. This is so arrow keys won't blur the table, but
         *   tab will.
         * @private
         */
        _shift: function (e, direction, keyBlurable) {
            var that = this;
            var dt = this.s.dt;
            var pageInfo = dt.page.info();
            var rows = pageInfo.recordsDisplay;
            var currentCell = this.s.lastFocus.cell;
            var columns = this._columns();

            if (!currentCell) {
                return;
            }

            var currRow = dt
                .rows({filter: 'applied', order: 'applied'})
                .indexes()
                .indexOf(currentCell.index().row);

            // When server-side processing, `rows().indexes()` only gives the rows
            // that are available at the client-side, so we need to normalise the
            // row's current position by the display start point
            if (pageInfo.serverSide) {
                currRow += pageInfo.start;
            }

            var currCol = dt
                .columns(columns)
                .indexes()
                .indexOf(currentCell.index().column);

            var
                row = currRow,
                column = columns[currCol]; // row is the display, column is an index

            if (direction === 'right') {
                if (currCol >= columns.length - 1) {
                    row++;
                    column = columns[0];
                }
                else {
                    column = columns[currCol + 1];
                }
            }
            else if (direction === 'left') {
                if (currCol === 0) {
                    row--;
                    column = columns[columns.length - 1];
                }
                else {
                    column = columns[currCol - 1];
                }
            }
            else if (direction === 'up') {
                row--;
            }
            else if (direction === 'down') {
                row++;
            }

            if (row >= 0 && row < rows && $.inArray(column, columns) !== -1
            ) {
                e.preventDefault();

                this._focus(row, column, true, e);
            }
            else if (!keyBlurable || !this.c.blurable) {
                // No new focus, but if the table isn't blurable, then don't loose
                // focus
                e.preventDefault();
            }
            else {
                this._blur();
            }
        },


        /**
         * Create a hidden input element that can receive focus on behalf of the
         * table
         *
         * @private
         */
        _tabInput: function () {
            var that = this;
            var dt = this.s.dt;
            var tabIndex = this.c.tabIndex !== null ?
                this.c.tabIndex :
                dt.settings()[0].iTabIndex;

            if (tabIndex == -1) {
                return;
            }

            var div = $('
') .css({ position: 'absolute', height: 1, width: 0, overflow: 'hidden' }) .insertBefore(dt.table().node()); div.children().on('focus', function (e) { if (dt.cell(':eq(0)', {page: 'current'}).any()) { that._focus(dt.cell(':eq(0)', '0:visible', {page: 'current'}), null, true, e); } }); }, /** * Update fixed columns if they are enabled and if the cell we are * focusing is inside a fixed column * @param {integer} column Index of the column being changed * @private */ _updateFixedColumns: function (column) { var dt = this.s.dt; var settings = dt.settings()[0]; if (settings._oFixedColumns) { var leftCols = settings._oFixedColumns.s.iLeftColumns; var rightCols = settings.aoColumns.length - settings._oFixedColumns.s.iRightColumns; if (column < leftCols || column >= rightCols) { dt.fixedColumns().update(); } } } }); /** * KeyTable default settings for initialisation * * @namespace * @name KeyTable.defaults * @static */ KeyTable.defaults = { /** * Can focus be removed from the table * @type {Boolean} */ blurable: true, /** * Class to give to the focused cell * @type {String} */ className: 'focus', /** * Enable or disable clipboard support * @type {Boolean} */ clipboard: true, /** * Orthogonal data that should be copied to clipboard * @type {string} */ clipboardOrthogonal: 'display', /** * Columns that can be focused. This is automatically merged with the * visible columns as only visible columns can gain focus. * @type {String} */ columns: '', // all /** * Editor instance to automatically perform Excel like navigation * @type {Editor} */ editor: null, /** * Option that defines what KeyTable's behaviour will be when used with * Editor's inline editing. Can be `navigation-only` or `tab-only`. * @type {String} */ editorKeys: 'navigation-only', /** * Set if Editor should automatically select the text in the input * @type {Boolean} */ editAutoSelect: true, /** * Control if editing should be activated immediately upon focus * @type {Boolean} */ editOnFocus: false, /** * Select a cell to automatically select on start up. `null` for no * automatic selection * @type {cell-selector} */ focus: null, /** * Array of keys to listen for * @type {null|array} */ keys: null, /** * Tab index for where the table should sit in the document's tab flow * @type {integer|null} */ tabIndex: null }; KeyTable.version = "2.4.1"; $.fn.dataTable.KeyTable = KeyTable; $.fn.DataTable.KeyTable = KeyTable; DataTable.Api.register('cell.blur()', function () { return this.iterator('table', function (ctx) { if (ctx.keytable) { ctx.keytable.blur(); } }); }); DataTable.Api.register('cell().focus()', function () { return this.iterator('cell', function (ctx, row, column) { if (ctx.keytable) { ctx.keytable.focus(row, column); } }); }); DataTable.Api.register('keys.disable()', function () { return this.iterator('table', function (ctx) { if (ctx.keytable) { ctx.keytable.enable(false); } }); }); DataTable.Api.register('keys.enable()', function (opts) { return this.iterator('table', function (ctx) { if (ctx.keytable) { ctx.keytable.enable(opts === undefined ? true : opts); } }); }); // Cell selector DataTable.ext.selector.cell.push(function (settings, opts, cells) { var focused = opts.focused; var kt = settings.keytable; var out = []; if (!kt || focused === undefined) { return cells; } for (var i = 0, ien = cells.length; i < ien; i++) { if ((focused === true && kt.focused(cells[i])) || (focused === false && !kt.focused(cells[i])) ) { out.push(cells[i]); } } return out; }); // Attach a listener to the document which listens for DataTables initialisation // events so we can automatically initialise $(document).on('preInit.dt.dtk', function (e, settings, json) { if (e.namespace !== 'dt') { return; } var init = settings.oInit.keys; var defaults = DataTable.defaults.keys; if (init || defaults) { var opts = $.extend({}, defaults, init); if (init !== false) { new KeyTable(settings, opts); } } }); return KeyTable; }));




© 2015 - 2025 Weber Informatics LLC | Privacy Policy