<etools-dropdown> and <etools-dropdown-multi>
Dropdown menu with search and single/multiple option(s) selection.
For documentation details see component demo (npm i
, polymer serve
)
etools-dropdown specific properties
-
selected: number, notify
- the id/optionValue of the selected item
-
selectedItem: Object = null, notify.
- Selected option object
-
notFoundOption: string
- Selected value not found in options
etools-dropdown-multi specific properties
-
selectedValues - Array, notify
- the id/optionValue of the selected items
-
selectedItems: Array = [], notify
- Selected options objects
-
notFoundOptions - Array = []
- populated in case
selectedValues
are not found in the options
- populated in case
-
triggerValueChangeEvent - Boolean, default:
false
- it can be used to trigger
etools-selected-items-changed
event if needed
- it can be used to trigger
Common properties
-
ajaxParams: Object
- Inherited from EsmmMixins.MissingOptions
-
allowOutsideScroll: boolean
- Inherited from EsmmMixins.CommonFunctionality
- Allows scroll outside opened dropdown
-
alwaysFloatLabel: boolean = true
- Inherited from EsmmMixins.CommonFunctionality
-
autoValidate: boolean
- Inherited from EsmmMixins.CommonFunctionality
-
capitalize: boolean = false
- Inherited from EsmmMixins.ListItemUtils
- Capitalize selected values/option, UI only
-
disabled: boolean = false
- Inherited from EsmmMixins.CommonFunctionality
-
disableOnFocusHandling: boolean
- Inherited from EsmmMixins.CommonFunctionality
- Stop autofocus from paper-dialog
-
noDynamicAlign: boolean = false
- Inherited from EsmmMixins.CommonFunctionality
- By default, dropdown is shown top or bottom where it will fit better. This flag can disable this behavior.
-
enableNoneOption: boolean = false
- Inherited from EsmmMixins.CommonFunctionality
- Flag to show None option (first dropdown option) Used to reset single selection dropdown selected value
-
errorMessage: string = "This field is required"
- Inherited from EsmmMixins.CommonFunctionality
-
fitInto: Object
- Inherited from EsmmMixins.CommonFunctionality
- Element that will prevent dropdown to overflow outside it's margins
-
hideSearch: boolean = false
- Inherited from EsmmMixins.CommonFunctionality
-
invalid: boolean = false
- Inherited from EsmmMixins.CommonFunctionality
-
label: string
- Inherited from EsmmMixins.CommonFunctionality
- Dropdown label
-
noLabelFloat: boolean
- Inherited from EsmmMixins.CommonFunctionality
-
noneOptionLabel: string = "-- NONE --"
- Inherited from EsmmMixins.ListItemUtils
- None option label
-
noOptionsAvailable: boolean = truereadOnly
- Inherited from EsmmMixins.CommonFunctionality
- Flag to show a no options avaliable warning
-
optionLabel: string = "label"
- Inherited from EsmmMixins.ListItemUtils
- Option object property to use as label
-
options: Array
- Inherited from EsmmMixins.CommonFunctionality
- Array of objects, dropdowns options used to compute shownOptions
-
optionValue: string = "value"
- Inherited from EsmmMixins.ListItemUtils
- Option object property to use as value for selection
-
placeholder: string = "—"
- Inherited from EsmmMixins.CommonFunctionality
-
preserveSearchOnClose : Boolean
- By default the search string is reset when the dropdown closes; this flag allows the search value to persist after the dropdown is closed
-
readonly: boolean = false
- Inherited from EsmmMixins.CommonFunctionality
-
required: boolean
- Inherited from EsmmMixins.CommonFunctionality
-
search: string
- Inherited from EsmmMixins.CommonFunctionality
-
showLimitWarning: boolean = falsereadOnly
- Inherited from EsmmMixins.CommonFunctionality
- Flag to show the limit of options shown in dropdown
-
shownOptions: ArrayreadOnly
- Inherited from EsmmMixins.CommonFunctionality
- Options seen by user
-
shownOptionsLimit: number = 50
- Inherited from EsmmMixins.CommonFunctionality
- Limit displayed options
-
showNoSearchResultsWarning: boolean = falsereadOnly
- Inherited from EsmmMixins.CommonFunctionality
- Flag used to show no search result found warning
-
title: stringreadOnly
- Element title attribute
-
twoLinesLabel: boolean = false
- Inherited from EsmmMixins.ListItemUtils
- Show option label on 2 lines
-
url: string
- Inherited from EsmmMixins.MissingOptions
-
viewportEdgeMargin: number = 20
- Inherited from EsmmMixins.CommonFunctionality
- Margin added if dropdown bottom is too close to the viewport bottom margin
Internationalization
-
language
property is initialized from window.EtoolsLAnguage || 'en'. - The component handles the
language-changed
event fired by the parent app -
assets/translations.js
contains the translations file.
Usage
Examples:
Single/multi selection, with search
<etools-dropdown label="Searchable menu" options="[[realOptions]]" selected="{{selectedId}}"></etools-dropdown>
<etools-dropdown-multi
label="Searchable menu"
options="[[realOptions]]"
selected-values="{{selectedValuesArray}}"
></etools-dropdown-multi>
Single/multi selection, without search
<etools-dropdown label="Options menu" options="[[realOptions]]" selected="{{selectedId}}" hide-search></etools-dropdown>
<etools-dropdown-multi
label="Searchable menu"
options="[[realOptions]]"
selected-values="{{selectedValuesArray}}"
hide-search
></etools-dropdown-multi>
Single selection, with search, limit of 3 elements
<etools-dropdown
label="Searchable menu"
options="[[realOptions]]"
shown-items-limit="3"
selected="{{selectedId}}"
></etools-dropdown>
Single selection, with search, always display an empty value (-- None --).
Note: etools-dropdown-multi
cannot use enableNoneOption
.
<etools-dropdown
label="Searchable menu"
options="[[realOptions]]"
enable-none-option
selected="{{selectedId}}"
></etools-dropdown>
Change event examples:
etools-dropdown
has etools-selected-item-changed
event, fired if triggerValueChangeEvent = true
,
the event.details
will contain the selectedItem
object
etools-dropdown-multi
has etools-selected-items-changed
event, fired if triggerValueChangeEvent = true
,
the event.details
will contain selectedItems
array
<etools-dropdown
label="Single searchable menu"
options="[[realOptions]]"
trigger-value-change-event
on-etools-selected-item-changed="_selectedItemChanged"
></etools-dropdown>
<etools-dropdown-multi
label="Multi searchable menu"
options="[[realOptions]]"
trigger-value-change-event
on-etools-selected-items-changed="_selectedItemsChanged"
>
</etools-dropdown-multi>
Error messages and validations. You can use invalid
, auto-validate
, required
to validate your selection.
<etools-dropdown
id="dropdownElement"
label="Searchable menu with validation manually triggered (in 5s)"
error-message="You must select an option"
auto-validate
required
options="[[realOptions]]"
dynamic-align
></etools-dropdown>
Validation triggered from javascript:
this.$.dropdownElement.validate();
If the options array where objects of this model: {value: someIntegerValue, label: someLabel}
is not what you need you can use any type of objects. You have to set some properties on the element to tell
that you have custom options and which properties to be used as values and labels.
// options example(used in the demo), in properties object
customObjOptions = [
{
option_key: 'option_identifier',
option_label: 'Option label'
}
];
<etools-dropdown
label="Searchable menu, custom objects"
options="[[customObjOptions]]"
option-value="option_key"
option-label="option_label"
></etools-dropdown>
Styling
Use paper-input
(and related elements) style properties and mixins.
Specific css variables and mixins of this element:
Custom property | Description | Default |
---|---|---|
--esmm-select-cursor |
CSS cursor property | pointer |
--esmm-icons |
Mixin applied to element icons | {color: var(--secondary-text-color); cursor: pointer;} |
--esmm-search-input-label |
Mixin aplied to the search input label | {} |
--esmm-list-item-selected-color |
Selected options bg color | #DCDCDC |
--esmm-multi-placeholder-color |
Multiselection dropdown placeholder color | rgba(0, 0, 0, 0.54) |
--esmm-bg-color |
Dropdown background color | #ffffff |
etools-dropdown::part(esmm-label-container) |
Mixin for Dropdown label container | #ffffff |
etools-dropdown::part(esmm-label) |
Mixin for Dropdown label | #ffffff |
etools-dropdown::part(esmm-label-suffix) |
Mixin for Dropdown label suffix | #ffffff |
etools-dropdown::part(esmm-dropdown-content) |
Mixin for Dropdown content | #ffffff |
Dynamically loading data
When the data source of the dropdown is voluminous, you can resort to loading just the first page of the data. The rest of the data will be loaded on request - when user scrolls down or searches in the dropdown.
Requirements for this functionality:
- The endpoint used to populate the dropdown has to support pagination and search
- After the selected value/s are saved, the API has to return more that just the saved id. Has to return all the details needed to populate the dropdown with the saved selected item. This is to cover cases like:
- the saved item is not on the first page of the data source (on page refresh for ex)
- after search, if the saved item is not in the results from bk it has to be re-added to the dropdown options, otherwise it will dissapear as selected from UI
Implementation example:
- In your page/component define the method that will handle the dynamic retrival of dropdown data source
public connectedCallback() {
super.connectedCallback();
this.loadUsersDropdownOptions = this._loadUsersDropdownOptions.bind(this);
}
_loadUsersDropdownOptions(search: string, page: number, shownOptionsLimit: number) {
const endpoint = clone(endpointsList.users);
endpoint.url += `?page_size=${shownOptionsLimit}&page=${page}&search=${search || ''}`;
sendRequest({
method: 'GET',
endpoint: {
url: endpoint.url
}
}).then((resp: GenericObject) => {
const data = page > 1 ? [...this.users, ...resp.results] : resp.results;
this.handleUsersNoLongerAssignedToCurrentCountry( // Re-add previously selected and saved item
data,
this.editedItem.assigned_to ? [this.editedItem.assigned_to] : []
);
this.set('users', data);
});
}
- Bind it to the dropdown
<etools-dropdown
load-data-method="[[loadUsersDropdownOptions]]" ....
<etools-dropdown
.loadDdataMethod="${this.loadUsersDropdownOptions}" ....
Install
$ npm i --save @unicef-polymer/etools-dropdown
Install the Polymer-CLI
$ npm install
First, make sure you have the Polymer CLI installed. Then run polymer serve
to serve your element locally.
Running Tests
TODO: improve and add more tests
$ polymer test
Circle CI
Package will be automatically published after tag push. Tag name must correspond SemVer (Semantic Versioning) rules. Examples:
Version match | Result |
---|---|
1.2.3 |
match |
1.2.3-pre |
match |
1.2.3+build |
match |
1.2.3-pre+build |
match |
v1.2.3-pre+build |
match |
1.2 |
no match |
You can see more details here