From 37babbe3155021b1e2a6522f7b63c921917a53fe Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Sat, 10 Dec 2016 09:32:25 -0500 Subject: [PATCH 1/2] Add helper functions --- iron-list.html | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/iron-list.html b/iron-list.html index 27b92725..b49f007b 100644 --- a/iron-list.html +++ b/iron-list.html @@ -1630,6 +1630,49 @@ return; } this.toggleSelectionForItem(model[this.as]); + /** + * Updates the models of all physical items + */ + _updatePhysicalItemModels: function() { + this._physicalItems.map(function(el) { + return this.modelForElement(el); + }.bind(this)).forEach(function(model) { + model[this.selectedAs] = (this.$.selector).isSelected(this.items[model[this.indexAs]]); + }.bind(this)); + }, + + /** + * UnSelect all items in a certain range (inclusive of both start and end) + */ + _deselectRange: function(start, end) { + this.items.slice(start, end + 1) + .map(function(item) { + return this._getNormalizedItem(item); + }.bind(this)) + .filter(function(item) { + return (this.$.selector).isSelected(item); + }.bind(this)) + .forEach(function(item) { + this.$.selector.deselect(item); + }.bind(this)); + this._updatePhysicalItemModels(); + }, + + /** + * Select all items in a certain range (inclusive of both start and end) + */ + _selectRange: function(start, end) { + this.items.slice(start, end + 1) + .map(function(item) { + return this._getNormalizedItem(item); + }.bind(this)) + .filter(function(item) { + return !(this.$.selector).isSelected(item); + }.bind(this)) + .forEach(function(item) { + this.$.selector.select(item); + }.bind(this)); + this._updatePhysicalItemModels(); }, _multiSelectionChanged: function(multiSelection) { From e739c9f85b92cdb770b9e7060169c97c5773b6c3 Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Sat, 10 Dec 2016 09:32:54 -0500 Subject: [PATCH 2/2] Add shift select handler function --- iron-list.html | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/iron-list.html b/iron-list.html index b49f007b..f36603f7 100644 --- a/iron-list.html +++ b/iron-list.html @@ -1629,7 +1629,44 @@ if (activeEl && physicalItem !== activeEl && physicalItem.contains(activeEl) && activeElTabIndex !== SECRET_TABINDEX) { return; } - this.toggleSelectionForItem(model[this.as]); + + var sourceEvent = e && e.detail && e.detail.sourceEvent; + + // Handle `shift` click scenario + if (this.multiSelection && this.selectedItems.length && sourceEvent.shiftKey) { + this._shiftSelectHandler(model[this.as]); + } else { + this.toggleSelectionForItem(model[this.as]); + } + }, + + _shiftSelectHandler: function(selectedItem) { + var selectedIndex = this.items.indexOf(selectedItem); + var _selectedItemIndexes = this.selectedItems.map(function(item) { + return this.items.indexOf(item); + }.bind(this)); + + var firstSelectedIndex = _selectedItemIndexes.reduce(function(currentIndex, itemIndex) { + return Math.min(currentIndex, itemIndex); + }); + + var lastSelectedIndex = _selectedItemIndexes.reduce(function(currentIndex, itemIndex) { + return Math.max(currentIndex, itemIndex); + }); + + var startIndex = Math.min(selectedIndex, firstSelectedIndex); + var lastIndex = Math.max(selectedIndex, lastSelectedIndex); + + // Select the range created with the shift select + this._selectRange(startIndex, lastIndex); + + // Deselect everything outside of the shift select range (will only occur + // if a user shift selects in the middle of a range) + if (selectedIndex > firstSelectedIndex && selectedIndex < lastSelectedIndex) { + this._deselectRange(selectedIndex + 1, lastSelectedIndex); + } + }, + /** * Updates the models of all physical items */