slickgrid
Version:
A lightning fast JavaScript grid/spreadsheet
224 lines (192 loc) • 7.86 kB
JavaScript
/***
* 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'>×</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);