From fcda7b99ede6ab6fe1d7e523a89ce43951d453e6 Mon Sep 17 00:00:00 2001 From: Adrian Hangan Date: Sun, 26 Feb 2017 18:06:13 +0200 Subject: [PATCH 1/3] functionality improvement using selected property --- demo/demo-custom-objects-as-options.html | 98 +++++++----------- demo/index.html | 8 +- etools-searchable-multiselection-menu.html | 109 +++++++++++++++++---- 3 files changed, 132 insertions(+), 83 deletions(-) diff --git a/demo/demo-custom-objects-as-options.html b/demo/demo-custom-objects-as-options.html index 92559ec..cc6a0b1 100644 --- a/demo/demo-custom-objects-as-options.html +++ b/demo/demo-custom-objects-as-options.html @@ -3,13 +3,13 @@ @@ -108,48 +87,29 @@

A few options selected by default example

customObjOptions: { type: Array, - value: function() { - var opt = []; - for(var i = 1; i <= 100; i++) { - opt.push({ - id: i, - option_key: 'opt' + i, - option_label: 'Option ' + i, - some_other_property: 'dummy propery for objIdx' + (i -1) - }); - } - return opt; - } - }, - - selectedObjOptions: { - type: Array, - value: function() { - var opt = []; - for(var i = 3; i <= 5; i++) { - opt.push({ - id: i, - option_key: 'opt' + i, - option_label: 'Option ' + i, - some_other_property: 'dummy propery for objIdx' + (i -1) - }); - } - return opt; - } + value: [] }, selectedId: { - type: Number, value: null }, selectedIds: { type: Array, - value: [] + value: [3, 5, '7'] } }, ready: function() { -// this.set('selectedValues', [{value: 2, label: 'Option 2'}]); + // this.set('selectedValues', [{value: 2, label: 'Option 2'}]); + this.set('selectedId', 3); + + setTimeout(function() { + this.set('customObjOptions', this.generateOptions()); + }.bind(this), 3000); + + // setTimeout(function() { + // this.set('selectedId', 3); + // }.bind(this), 3000); }, _returnIdsString: function(vals) { @@ -162,6 +122,18 @@

A few options selected by default example

_multiSelectionChanged: function(event) { console.log('_multiSelectionChanged', event.detail); + }, + generateOptions: function() { + var opt = []; + for(var i = 1; i <= 100; i++) { + opt.push({ + id: i, + option_key: 'opt' + i, + option_label: 'Option ' + i, + some_other_property: 'dummy propery for objIdx' + (i -1) + }); + } + return opt; } }); diff --git a/demo/index.html b/demo/index.html index a0a5915..9f6e6df 100644 --- a/demo/index.html +++ b/demo/index.html @@ -27,7 +27,7 @@

etools-searchable-multiselection-menu demo

- +

Custom objects as options. You can specify value and label properties from object option to be used.

@@ -140,13 +142,13 @@

Custom objects as options. You can specify value and label properties from o -

Readonly state

+
diff --git a/etools-searchable-multiselection-menu.html b/etools-searchable-multiselection-menu.html index 68e779f..9a5131c 100644 --- a/etools-searchable-multiselection-menu.html +++ b/etools-searchable-multiselection-menu.html @@ -429,21 +429,23 @@ value: 'label' }, selected: { - // this will be populated with integer value, in case of single selection, - // or will be an Array of integer values (example: you may need an array of integer values selected, IDs, - // without having the need to map the selectedValues in parent and convert to integer values) - // it will work only if optionValue is set to 'id' notify: true }, updateSelected: { type: Boolean, - value: false + value: false, + observer: '_updateSelectedFlagChanged' }, noChangeEvent: { type: Boolean, value: false } }, + + observers: [ + '_selectedChanged(selected, options)' + ], + ready: function() { if (this.autoValidate === true && this.multi === true) { // autoValidate for multi selection will not work, we will use a new flag in this case @@ -517,6 +519,7 @@ } }, _valueChanged: function(value) { + console.log('value changed', value); if (!value) { // empty value/reset selection this.set('selectedValues', null); @@ -625,23 +628,95 @@ return itemValue; }, - _updateSelected: function(selectedValues) { - if (!this.updateSelected || this.optionValue !== 'id' - || !selectedValues || Array.isArray(selectedValues) && selectedValues.length === 0) { - // do not update selected value - return; + _updateSelectedFlagChanged: function(updateSelected) { + if (updateSelected) { + // disable change events if this flag is `true` + this.set('noChangeEvent', true); } + }, - if (this.multi && Array.isArray(selectedValues) && selectedValues.length > 0) { - var selectedVals = selectedValues.map(function(s) { - return parseInt(s, 10); - }); - this.set('selected', selectedVals); + _selectedChanged: function(selected, options) { + if (!this.updateSelected) { + return; } + if (this.multi) { + var multiSelectedValues = []; + if (selected instanceof Array && selected.length > 0) { + if (options instanceof Array && options.length > 0) { + selected.forEach(function(selectedVal) { + for (var i = 0; i <= options.length; i++) { + if (this._prepareValue(options[i][this.optionValue]) === this._prepareValue(selectedVal)) { + multiSelectedValues.push(options[i]); + break; + } + } + }.bind(this)); + } + } + this.set('value', multiSelectedValues); + } else { + var singleSelectedValue = null; + if ((selected && (typeof selected === 'string' || typeof selected === 'number')) && + options instanceof Array && options.length > 0) { + for (var i = 0; i <= options.length; i++) { + var selectedVal = this._prepareValue(selected); + if (this._prepareValue(options[i][this.optionValue]) === selectedVal) { + singleSelectedValue = options[i]; + break; + } + } + } + this.set('value', singleSelectedValue); + } + console.log('selected changed, update value to:', this.value); + }, - if (!this.multi) { - this.set('selected', parseInt(selectedValues, 10)); + _updateSelected: function(selectedValues) { + this.debounce('updateSelectedValue', function() { + if (!this.updateSelected || !selectedValues || + Array.isArray(selectedValues) && selectedValues.length === 0) { + // do not update selected value + return; + } + + if (this.multi && Array.isArray(selectedValues)) { + // multiselection + // selected will be empty array if selectedValues.length === 0 + var selectedVals = []; + if (selectedValues.length > 0) { + selectedVals = selectedValues.map(function(s) { + return this._prepareValue(s); + }.bind(this)); + } + this.set('selected', selectedVals); + } + + if (!this.multi) { + // single selection + if (!selectedValues || (typeof selectedValues === 'string' && selectedValues === '')) { + // empty string, false, null or undefined + this.set('selected', null); + } else { + this.set('selected', this._prepareValue(selectedValues)); + } + } + console.log('selected updated: ', this.selected); + }.bind(this), 50); + }, + + _prepareValue: function(value) { + if (typeof value === 'number') { + return value; + } + if (typeof value === 'string') { + var val = parseInt(value, 10); + if (isNaN(val)) { + return value; + } else { + return val; + } } + return value; }, _removeItem: function(event, details) { From 7e7d01ba58e81e21356e5e2c0e18741ee3ed5480 Mon Sep 17 00:00:00 2001 From: Adrian Hangan Date: Mon, 27 Feb 2017 15:04:45 +0200 Subject: [PATCH 2/3] selection improvement --- README.md | 8 +- bower.json | 2 +- demo/demo-custom-objects-as-options.html | 34 ++---- demo/index.html | 7 +- etools-searchable-multiselection-menu.html | 128 ++++++++++++++++----- 5 files changed, 117 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 25a1c3d..102b305 100644 --- a/README.md +++ b/README.md @@ -159,9 +159,9 @@ customObjOptions: { on-value-change="_singleSelectionChanged"> ``` -If you need only select an option and get option ID (most use cases) or an array of IDs(for multiselection) -you can use `selected` property of the element. It only works for integer values, for other types use `selectedValues` property. -Additionally you can chose to block the change event. Example: +If you need only to bind a custom element property to the esmm dropdown use `selected` property +to update dropdown's selection or get selected value(s). +In this case change event is automatically disabled. Example: ```html

SelectedID: [[selectedId]]

@@ -172,7 +172,7 @@ Additionally you can chose to block the change event. Example: option-value="id" option-label="option_label" selected="{{selectedId}}" - update-selected no-change-event> + update-selected> ``` diff --git a/bower.json b/bower.json index 35d0e7e..05e0d74 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "etools-searchable-multiselection-menu", "description": "Dropdown menu with search and multiple options selection", - "version": "1.0.26", + "version": "1.0.27", "license": "https://github.com/unicef-polymer/etools-searchable-multiselection-menu/blob/master/LICENSE.md", "main": "etools-searchable-multiselection-menu.html", "dependencies": { diff --git a/demo/demo-custom-objects-as-options.html b/demo/demo-custom-objects-as-options.html index cc6a0b1..c89f5cd 100644 --- a/demo/demo-custom-objects-as-options.html +++ b/demo/demo-custom-objects-as-options.html @@ -3,30 +3,17 @@