UNPKG

slickgrid

Version:

A lightning fast JavaScript grid/spreadsheet

224 lines (192 loc) 7.86 kB
/*** * A control to add a Column Picker (right+click on any column header to reveal the column picker) * * USAGE: * * Add the slick.columnpicker.(js|css) files and register it with the grid. * * Available options, by defining a columnPicker object: * * var options = { * enableCellNavigation: true, * columnPicker: { * columnTitle: "Columns", // default to empty string * * // the last 2 checkboxes titles * hideForceFitButton: false, // show/hide checkbox near the end "Force Fit Columns" (default:false) * hideSyncResizeButton: false, // show/hide checkbox near the end "Synchronous Resize" (default:false) * forceFitTitle: "Force fit columns", // default to "Force fit columns" * syncResizeTitle: "Synchronous resize", // default to "Synchronous resize" * } * }; * * @class Slick.Controls.ColumnPicker * @constructor */ 'use strict'; (function ($) { function SlickColumnPicker(columns, grid, options) { var _grid = grid; var $list; var $menu; var columnCheckboxes; var onColumnsChanged = new Slick.Event(); var defaults = { fadeSpeed: 250, // the last 2 checkboxes titles hideForceFitButton: false, hideSyncResizeButton: false, forceFitTitle: "Force fit columns", syncResizeTitle: "Synchronous resize" }; function init(grid) { grid.onHeaderContextMenu.subscribe(handleHeaderContextMenu); grid.onColumnsReordered.subscribe(updateColumnOrder); options = $.extend({}, defaults, options); $menu = $("<div class='slick-columnpicker' style='display:none' />").appendTo(document.body); var $close = $("<button type='button' class='close' data-dismiss='slick-columnpicker' aria-label='Close'><span class='close' aria-hidden='true'>&times;</span></button>").appendTo($menu); // user could pass a title on top of the columns list if(options.columnPickerTitle || (options.columnPicker && options.columnPicker.columnTitle)) { var columnTitle = options.columnPickerTitle || options.columnPicker.columnTitle; var $title = $("<div class='title'/>").append(columnTitle); $title.appendTo($menu); } $menu.on("click", updateColumn); $list = $("<span class='slick-columnpicker-list' />"); // Hide the menu on outside click. $(document.body).on("mousedown", handleBodyMouseDown); // destroy the picker if user leaves the page $(window).on("beforeunload", destroy); } function destroy() { _grid.onHeaderContextMenu.unsubscribe(handleHeaderContextMenu); _grid.onColumnsReordered.unsubscribe(updateColumnOrder); $(document.body).off("mousedown", handleBodyMouseDown); $("div.slick-columnpicker").hide(options.fadeSpeed); $menu.remove(); } function handleBodyMouseDown(e) { if (($menu && $menu[0] != e.target && !$.contains($menu[0], e.target)) || e.target.className == "close") { $menu.hide(options.fadeSpeed); } } function handleHeaderContextMenu(e, args) { e.preventDefault(); $list.empty(); updateColumnOrder(); columnCheckboxes = []; var $li, $input; for (var i = 0; i < columns.length; i++) { $li = $("<li />").appendTo($list); $input = $("<input type='checkbox' />").data("column-id", columns[i].id); columnCheckboxes.push($input); if (_grid.getColumnIndex(columns[i].id) != null) { $input.attr("checked", "checked"); } $("<label />") .html(columns[i].name) .prepend($input) .appendTo($li); } if (options.columnPicker && (!options.columnPicker.hideForceFitButton || !options.columnPicker.hideSyncResizeButton)) { $("<hr/>").appendTo($list); } if (!(options.columnPicker && options.columnPicker.hideForceFitButton)) { var forceFitTitle = (options.columnPicker && options.columnPicker.forceFitTitle) || options.forceFitTitle; $li = $("<li />").appendTo($list); $input = $("<input type='checkbox' />").data("option", "autoresize"); $("<label />") .text(forceFitTitle) .prepend($input) .appendTo($li); if (_grid.getOptions().forceFitColumns) { $input.attr("checked", "checked"); } } if (!(options.columnPicker && options.columnPicker.hideSyncResizeButton)) { var syncResizeTitle = (options.columnPicker && options.columnPicker.syncResizeTitle) || options.syncResizeTitle; $li = $("<li />").appendTo($list); $input = $("<input type='checkbox' />").data("option", "syncresize"); $("<label />") .text(syncResizeTitle) .prepend($input) .appendTo($li); if (_grid.getOptions().syncColumnCellResize) { $input.attr("checked", "checked"); } } $menu .css("top", e.pageY - 10) .css("left", e.pageX - 10) .css("max-height", $(window).height() - e.pageY -10) .fadeIn(options.fadeSpeed); $list.appendTo($menu); } function updateColumnOrder() { // Because columns can be reordered, we have to update the `columns` // to reflect the new order, however we can't just take `grid.getColumns()`, // as it does not include columns currently hidden by the picker. // We create a new `columns` structure by leaving currently-hidden // columns in their original ordinal position and interleaving the results // of the current column sort. var current = _grid.getColumns().slice(0); var ordered = new Array(columns.length); for (var i = 0; i < ordered.length; i++) { if ( _grid.getColumnIndex(columns[i].id) === undefined ) { // If the column doesn't return a value from getColumnIndex, // it is hidden. Leave it in this position. ordered[i] = columns[i]; } else { // Otherwise, grab the next visible column. ordered[i] = current.shift(); } } columns = ordered; } function updateColumn(e) { if ($(e.target).data("option") == "autoresize") { if (e.target.checked) { _grid.setOptions({forceFitColumns:true}); _grid.autosizeColumns(); } else { _grid.setOptions({forceFitColumns:false}); } return; } if ($(e.target).data("option") == "syncresize") { if (e.target.checked) { _grid.setOptions({syncColumnCellResize:true}); } else { _grid.setOptions({syncColumnCellResize:false}); } return; } if ($(e.target).is(":checkbox")) { var visibleColumns = []; $.each(columnCheckboxes, function (i, e) { if ($(this).is(":checked")) { visibleColumns.push(columns[i]); } }); if (!visibleColumns.length) { $(e.target).attr("checked", "checked"); return; } _grid.setColumns(visibleColumns); onColumnsChanged.notify({columns: visibleColumns, grid: _grid}); } } function getAllColumns() { return columns; } init(_grid); return { "init": init, "getAllColumns": getAllColumns, "destroy": destroy, "onColumnsChanged": onColumnsChanged }; } // Slick.Controls.ColumnPicker $.extend(true, window, { Slick:{ Controls:{ ColumnPicker:SlickColumnPicker }}}); })(jQuery);