diff default/node_modules/tablesaw/src/tables.columntoggle.js @ 0:1d038bc9b3d2 default tip

Up:default
author Liny <dev@neowd.com>
date Sat, 31 May 2025 09:21:51 +0800
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/default/node_modules/tablesaw/src/tables.columntoggle.js	Sat May 31 09:21:51 2025 +0800
@@ -0,0 +1,287 @@
+/*
+* 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 "<label><input type='checkbox' checked>" + text + "</label>";
+			}
+		});
+
+		this.$table.addClass(this.classes.columnToggleTable);
+
+		tableId = this.$table.attr("id");
+		id = tableId + "-popup";
+		$btnContain = $("<div class='" + this.classes.columnBtnContain + "'></div>");
+		// TODO next major version: remove .btn
+		$menuButton = $(
+			"<a href='#" +
+				id +
+				"' class='btn tablesaw-btn btn-micro " +
+				this.classes.columnBtn +
+				"' data-popup-link>" +
+				"<span>" +
+				Tablesaw.i18n.columnToggleButton +
+				"</span></a>"
+		);
+		$popup = $("<div class='" + this.classes.popup + "' id='" + id + "'></div>");
+		$menu = $("<div class='btn-group'></div>");
+
+		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("<label>" + Tablesaw.i18n.columnToggleError + "</label>");
+		}
+
+		$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)
+				.refreshPriority();
+		}
+	});
+
+	Tablesaw.ColumnToggle = ColumnToggle;
+})();