/* * tablesaw: A set of plugins for responsive tables * Column Toggle: allows the user to toggle which columns are visible. * Copyright (c) 2013 Filament Group, Inc. * MIT License */ (function() { var data = { key: "tablesaw-coltoggle" }; var ColumnToggle = function(element) { this.$table = $(element); if (!this.$table.length) { return; } this.tablesaw = this.$table.data("tablesaw"); this.attributes = { btnTarget: "data-tablesaw-columntoggle-btn-target", set: "data-tablesaw-columntoggle-set" }; this.classes = { columnToggleTable: "tablesaw-columntoggle", columnBtnContain: "tablesaw-columntoggle-btnwrap tablesaw-advance", columnBtn: "tablesaw-columntoggle-btn tablesaw-nav-btn down", popup: "tablesaw-columntoggle-popup", priorityPrefix: "tablesaw-priority-" }; this.set = []; this.$headers = this.tablesaw._getPrimaryHeaderCells(); this.$table.data(data.key, this); }; // Column Toggle Sets (one column chooser can control multiple tables) ColumnToggle.prototype.initSet = function() { var set = this.$table.attr(this.attributes.set); if (set) { // Should not include the current table var table = this.$table[0]; this.set = $("table[" + this.attributes.set + "='" + set + "']") .filter(function() { return this !== table; }) .get(); } }; ColumnToggle.prototype.init = function() { if (!this.$table.length) { return; } var tableId, id, $menuButton, $popup, $menu, $btnContain, self = this; var cfg = this.tablesaw.getConfig({ getColumnToggleLabelTemplate: function(text) { return ""; } }); this.$table.addClass(this.classes.columnToggleTable); tableId = this.$table.attr("id"); id = tableId + "-popup"; $btnContain = $("
"); // TODO next major version: remove .btn $menuButton = $( "" + "" + Tablesaw.i18n.columnToggleButton + "" ); $popup = $(""); $menu = $(""); this.$popup = $popup; var hasNonPersistentHeaders = false; this.$headers.each(function() { var $this = $(this), priority = $this.attr("data-tablesaw-priority"), $cells = self.tablesaw._$getCells(this); if (priority && priority !== "persist") { $cells.addClass(self.classes.priorityPrefix + priority); $(cfg.getColumnToggleLabelTemplate($this.text())) .appendTo($menu) .find('input[type="checkbox"]') .data("tablesaw-header", this); hasNonPersistentHeaders = true; } }); if (!hasNonPersistentHeaders) { $menu.append(""); } $menu.appendTo($popup); function onToggleCheckboxChange(checkbox) { var checked = checkbox.checked; var header = self.getHeaderFromCheckbox(checkbox); var $cells = self.tablesaw._$getCells(header); $cells[!checked ? "addClass" : "removeClass"]("tablesaw-toggle-cellhidden"); $cells[checked ? "addClass" : "removeClass"]("tablesaw-toggle-cellvisible"); self.updateColspanCells(header, checked); self.$table.trigger("tablesawcolumns"); } // bind change event listeners to inputs - TODO: move to a private method? $menu.find('input[type="checkbox"]').on("change", function(e) { onToggleCheckboxChange(e.target); if (self.set.length) { var index; $(self.$popup) .find("input[type='checkbox']") .each(function(j) { if (this === e.target) { index = j; return false; } }); $(self.set).each(function() { var checkbox = $(this) .data(data.key) .$popup.find("input[type='checkbox']") .get(index); if (checkbox) { checkbox.checked = e.target.checked; onToggleCheckboxChange(checkbox); } }); } }); $menuButton.appendTo($btnContain); // Use a different target than the toolbar var $btnTarget = $(this.$table.attr(this.attributes.btnTarget)); $btnContain.appendTo($btnTarget.length ? $btnTarget : this.tablesaw.$toolbar); function closePopup(event) { // Click came from inside the popup, ignore. if (event && $(event.target).closest("." + self.classes.popup).length) { return; } $(document).off("click." + tableId); $menuButton.removeClass("up").addClass("down"); $btnContain.removeClass("visible"); } var closeTimeout; function openPopup() { $btnContain.addClass("visible"); $menuButton.removeClass("down").addClass("up"); $(document).off("click." + tableId, closePopup); window.clearTimeout(closeTimeout); closeTimeout = window.setTimeout(function() { $(document).on("click." + tableId, closePopup); }, 15); } $menuButton.on("click.tablesaw", function(event) { event.preventDefault(); if (!$btnContain.is(".visible")) { openPopup(); } else { closePopup(); } }); $popup.appendTo($btnContain); this.$menu = $menu; // Fix for iOS not rendering shadows correctly when using `-webkit-overflow-scrolling` var $overflow = this.$table.closest(".tablesaw-overflow"); if ($overflow.css("-webkit-overflow-scrolling")) { var timeout; $overflow.on("scroll", function() { var $div = $(this); window.clearTimeout(timeout); timeout = window.setTimeout(function() { $div.css("-webkit-overflow-scrolling", "auto"); window.setTimeout(function() { $div.css("-webkit-overflow-scrolling", "touch"); }, 0); }, 100); }); } $(window).on(Tablesaw.events.resize + "." + tableId, function() { self.refreshToggle(); }); this.initSet(); this.refreshToggle(); }; ColumnToggle.prototype.getHeaderFromCheckbox = function(checkbox) { return $(checkbox).data("tablesaw-header"); }; ColumnToggle.prototype.refreshToggle = function() { var self = this; var invisibleColumns = 0; this.$menu.find("input").each(function() { var header = self.getHeaderFromCheckbox(this); this.checked = self.tablesaw ._$getCells(header) .eq(0) .css("display") === "table-cell"; }); this.updateColspanCells(); }; ColumnToggle.prototype.updateColspanCells = function(header, userAction) { this.tablesaw.updateColspanCells("tablesaw-toggle-cellhidden", header, userAction); }; ColumnToggle.prototype.destroy = function() { this.$table.removeClass(this.classes.columnToggleTable); this.$table.find("th, td").each(function() { var $cell = $(this); $cell.removeClass("tablesaw-toggle-cellhidden").removeClass("tablesaw-toggle-cellvisible"); this.className = this.className.replace(/\bui\-table\-priority\-\d\b/g, ""); }); }; // on tablecreate, init $(document).on(Tablesaw.events.create, function(e, tablesaw) { if (tablesaw.mode === "columntoggle") { var table = new ColumnToggle(tablesaw.table); table.init(); } }); $(document).on(Tablesaw.events.destroy, function(e, tablesaw) { if (tablesaw.mode === "columntoggle") { $(tablesaw.table) .data(data.key) .destroy(); } }); $(document).on(Tablesaw.events.refresh, function(e, tablesaw) { if (tablesaw.mode === "columntoggle") { $(tablesaw.table) .data(data.key) .refreshToggle(); } }); Tablesaw.ColumnToggle = ColumnToggle; })();