[yocto] [patchwork][PATCH 2/3] jquery.tablecheckbox: add plugin for multiselect functionality
Jose Lamego
jose.a.lamego at linux.intel.com
Tue Feb 28 15:07:33 PST 2017
Selecting multiple items in a patch list must be done manually,
one item at a time, resulting in a poor user experience.
This change adds the jquery.tablecheckbox.js plugin that allows
to select single / multiple / all table row(s) by clicking.
[YOCTO #10819]
Signed-off-by: Jose Lamego <jose.a.lamego at linux.intel.com>
---
htdocs/js/jquery.tablecheckbox.js | 165 ++++++++++++++++++++++++++++++++++++++
1 file changed, 165 insertions(+)
create mode 100644 htdocs/js/jquery.tablecheckbox.js
diff --git a/htdocs/js/jquery.tablecheckbox.js b/htdocs/js/jquery.tablecheckbox.js
new file mode 100644
index 0000000..8a50541
--- /dev/null
+++ b/htdocs/js/jquery.tablecheckbox.js
@@ -0,0 +1,165 @@
+(function($) {
+ /**
+ * A jQuery plugin that lets you easily enhance data tables with selectable rows.
+ *
+ *
+ * @author Marco Kerwitz <marco at kerwitz.com>
+ * @see https://github.com/kerwitz/jquery.tablecheckbox
+ */
+ $.fn.tablecheckbox = function(options) {
+ var _private = {
+ /**
+ * The configuration of this plugin.
+ *
+ * Overload with custom values when calling the plugin:
+ * $('table').tableCheckbox({selectedRowClass: 'selected-row'});
+ *
+ * @var object
+ */
+ config: $.extend({
+ // The class that will be applied to selected rows.
+ selectedRowClass: 'warning',
+ // The selector used to find the checkboxes on the table. You may customize this in
+ // order to match your table layout if it differs from the assumed one.
+ checkboxSelector: 'td:first-of-type input[type="checkbox"],th:first-of-type input[type="checkbox"]',
+ // A callback that is used to determine wether a checkbox is selected or not.
+ isChecked: function($checkbox) {
+ return $checkbox.is(':checked');
+ }
+ }, options),
+ /**
+ * Variables used across multiple tables.
+ *
+ * @var object
+ */
+ registry: {
+ shiftKeyIsPressed: false
+ },
+ helpers: {
+ /**
+ * Returns the selection methods available in the current browser.
+ *
+ * @author Grinn, http://stackoverflow.com/users/152648/grinn
+ * @author Gert Grenander, http://stackoverflow.com/users/339850/gert-grenander
+ * @see http://stackoverflow.com/questions/3169786/clear-text-selection-with-javascript
+ */
+ selection: window.getSelection ? window.getSelection() : document.selection ? document.selection : null,
+ /**
+ * Removes any text selection the user made.
+ *
+ * @author Marco Kerwitz <marco at kerwitz.com>
+ */
+ removeTextSelection: function() {
+ if (!!_private.helpers.selection) {
+ _private.helpers.selection.empty
+ ? _private.helpers.selection.empty()
+ : _private.helpers.selection.removeAllRanges();
+ }
+ },
+ /**
+ * Returns wether or not a text selection currently exists.
+ *
+ * @author Marco Kerwitz <marco at kerwitz.com>
+ * @todo This will return false positives when the user selected text outside of
+ * the table and then tries to select rows.
+ * @return {boolean}
+ */
+ hasSelection: function() {
+ return !!_private.helpers.selection && _private.helpers.selection.toString().length;
+ }
+ }
+ };
+ // Initiate a event callback that we can use to tell wether the user is pressing the shift
+ // key or not.
+ $(document).on('keydown.tsc keyup.tsc', function(e) {
+ _private.registry.shiftKeyIsPressed = e.shiftKey;
+ });
+ return this.each(function() {
+ var $table = $(this),
+ $headCheckbox = $table.find('thead tr ' + _private.config.checkboxSelector),
+ $checkboxes = $table.find('tr ' + _private.config.checkboxSelector).not($headCheckbox),
+ $lastRow = [];
+ // Listen for changes on the checkbox in the table header and apply its current state
+ // to all checkboxe on the table.
+ $headCheckbox.on('change', function(e) {
+ var $allRows = $table.find('tbody tr');
+ $checkboxes
+ .prop('checked', _private.config.isChecked($headCheckbox))
+ .trigger('change');
+ $table.trigger(
+ _private.config.isChecked($headCheckbox) ? 'multirowselect' : 'multirowdeselect',
+ {
+ $rows: $allRows,
+ $checkboxes: $allRows.find(_private.config.checkboxSelector),
+ rowCount: $allRows.length
+ }
+ );
+ });
+ // Cycle through each checkbox found on the table.
+ $checkboxes.each(function() {
+ var $checkbox = $(this),
+ $row = $checkbox.parents('tr'),
+ $inbetween,
+ $allRows;
+ $checkbox.on('change', function(e, isInternal) {
+ // When the user clicks directly on the rows he will unwillingly select
+ // the text of all rows inbetween. Remove that selection immediately.
+ _private.helpers.removeTextSelection();
+ if (!isInternal && _private.registry.shiftKeyIsPressed && $lastRow.length) {
+ // User held shift key while clicking on this checkbox and clicked another one
+ // prior. Get all checkboxes inbetween the two and check or uncheck them.
+ $inbetween = ($lastRow.index() < $row.index())
+ ? $row.prevUntil($lastRow)
+ : $row.nextUntil($lastRow);
+ $inbetween.find(_private.config.checkboxSelector)
+ .prop('checked', _private.config.isChecked($checkbox))
+ .trigger('change', [true]);
+ $allRows = $inbetween.add($row, $lastRow);
+ // Trigger table level event.
+ $table.trigger(
+ _private.config.isChecked($checkbox) ? 'multirowselect' : 'multirowdeselect',
+ {
+ $rows: $allRows,
+ $checkboxes: $allRows.find(_private.config.checkboxSelector),
+ rowCount: $allRows.length
+ }
+ );
+ }
+ $lastRow = $row;
+ $row.toggleClass(_private.config.selectedRowClass, _private.config.isChecked($checkbox));
+ // Trigger row level event.
+ $row.trigger(
+ _private.config.isChecked($checkbox) ? 'rowselect' : 'rowdeselect',
+ {$row: $row,$checkbox: $checkbox}
+ );
+ });
+ // Monitor the row and check the checkbox accordingly.
+ $row.on('click', function(e) {
+ if (_private.helpers.hasSelection()) {
+ // There was a text slection prior to this click. Chances are that the user
+ // simply wants to clear that instead of selecting this row - so do nothing.
+ return;
+ }
+ if ($.data($row, 'tc-timeout')) {
+ // There was a timeout running from a previous click event, this seems to be
+ // a double click. Cancel the first timeout before we create a new one.
+ window.clearTimeout($.data($row, 'tc-timeout'));
+ }
+ // We use a short timeout to wait for double-click selections that the user might
+ // have intended to make. If any selection is created withing this timespan we
+ // wont do anything to not interfere with the users intentions too much.
+ $.data($row, 'tc-timeout', window.setTimeout(function() {
+ // Do nothing if the user selected text on the row.
+ if (_private.helpers.hasSelection()) return;
+ // Make sure the user did not click on any clickable content in the row.
+ if (!$(e.target).is('a,input,button') && !$(e.target).parents('a,input,button').length) {
+ $checkbox
+ .prop('checked', !_private.config.isChecked($checkbox))
+ .trigger('change');
+ }
+ }, 50));
+ })
+ });
+ });
+ };
+}(jQuery));
--
1.9.1
More information about the yocto
mailing list