Skip to content

unicef-polymer/etools-searchable-multiselection-menu

Repository files navigation

<etools-single-selection-menu> and <etools-multi-selection-menu>

etools-single-selection-menu dropdown menu with search and single selection option When the optionValue is Number (in the options array), the type is preserved, it's not converted to string

etools-multi-selection-menu is dropdown with multi selection. Most of the functionality it's common with etools-single-selection-menu

etools-single-selection-menu specific properties

  • selected - Number/Array - notifies - the id/optionValue of the selected item
  • selectedItem - Object - the selected item from the options array
  • notFoundOption - String value, populated in case selected is not found in the options
  • showEmptyValue - Boolean, default: false

etools-multi-selection-menu specific properties

  • selectedValues - Array - notifies - the id/optionValue of the selected items
  • selectedItems - Array - the selected items from the options array
  • notFoundOptions - Array - populated in case selectedValues are not found in the options
  • triggerValueChangeEvent - Boolean - default: false, it can be used to trigger etools-selected-items-changed event if needed

Common properties

  • label - String
  • optionLabel - String, default: 'label'
  • optionValue - String, default: 'value'
  • options - Array - the dataSource of the dropdown
  • shownOptions - Array - the displayed options, truncated by shownOptionsLimit
  • allowOutsideScroll - Boolean, default: false
  • autoValidate - Boolean
  • capitalizeInputShown - Boolean
  • disabled - Boolean, default: false
  • dynamicAlign - Boolean, default: false
  • errorMessage - string
  • hideSearch - Boolean, default: false
  • invalid - boolean
  • placeholder - string
  • readonly - Boolean, default: false
  • required - boolean
  • search - String
  • shownOptionsLimit - Number, default: 50 - Limit the number of displayed options
  • url - String, the url used to request selected missing options from server(one missing option someUrl?values=1, many missing options someUrl?values=1,2,3). The response of the missing options request should be an array with one or more objects with the same properties dropdown options have.
  • ajaxParams - Object(optional) used to set build query string for the URL of missing options request.
  • twoLinesLabel - Boolean, default: false

Usage

Examples:

Single/multi selection, with search

<etools-single-selection-menu
      label="Searchable menu"
      options="[[realOptions]]"
      selected="{{selectedId}}"></etools-single-selection-menu>

<etools-multi-selection-menu
    label="Searchable menu"
    options="[[realOptions]]"
    selected-values="{{selectedValuesArray}}"></etools-multi-selection-menu>

Single/multi selection, without search

<etools-single-selection-menu label="Options menu"
     options="[[realOptions]]"
     selected="{{selectedId}}"
     hide-search></etools-single-selection-menu>

<etools-multi-selection-menu
     label="Searchable menu"
     options="[[realOptions]]"
     selected-values="{{selectedValuesArray}}"
     hide-search></etools-multi-selection-menu>

Single selection, with search, limit of 3 elements

<etools-single-selection-menu
              label="Searchable menu"
              options="[[realOptions]]"
              shown-items-limit="3"
              selected="{{selectedId}}"></etools-single-selection-menu>

Single selection, with search, always display an empty value (-- None --). Note: etools-multi-selection-menu doesn't have show-empty-value.

<etools-single-selection-menu
              label="Searchable menu"
              options="[[realOptions]]"
              show-empty-value
              selected="{{selectedId}}"></etools-single-selection-menu>

Change event examples:

on-iron-activate - fires only when the selected value is changed manually by selecting a value from the dropdown

on-iron-select - fires whenever the selected value is changed from dropdown or from code

The event parameter of the method (_singleSelectionChanged) holds info about the item that was selected in: event.detail.item.item

etools-multi-selection-menu has etools-selected-items-changed event, fired if triggerValueChangeEvent = true, the event.details will contain selectedItems array

<etools-single-selection-menu
    label="Searchable menu"
    options="[[realOptions]]"
    on-iron-activate="_singleSelectionChanged"></etools-single-selection-menu>

<etools-single-selection-menu
    label="Single searchable menu"
    options="[[realOptions]]"
    on-iron-select="_singleSelectionChanged"></etools-single-selection-menu>

<etools-multi-selection-menu
    label="Multi searchable menu"
    options="[[realOptions]]"
    trigger-value-change-event
    on-etools-selected-items-changed="_selectedItemsChanged">
</etools-multi-selection-menu>

Error messages and validations. You can use invalid, auto-validate, required to validate your selection.

<etools-single-selection-menu
        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-single-selection-menu>

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: {
    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_propery: 'dummy propery for objIdx' + (i -1)
        });
      }
      return opt;
    }
}
<etools-single-selection-menu
        label="Searchable menu, custom objects"
        options="[[customObjOptions]]"
        option-value="option_key"
        option-label="option_label"></etools-single-selection-menu>

Styling

Use this css variables and mixins to style this element.

Custom property Description Default
--esmm-option-list-color Multiple selected options color #212121
--esmm-list-item-selected-color Selected options bg color #DCDCDC
--esmm-external-wrapper Mixin applied to element wrapper {}
--esmm-readonly-input-container Mixin applied to paper-input-container, readonly {}
--esmm-readonly-input-container-underline Mixin applied to paper-input-container underline, readonly {}
--esmm-readonly-input-container-label Mixin applied to the label in readonly state {}
--esmm-readonly-input-container-label-focus Mixin applied to the label in readonly state with focus {}
--esmm-list-wrapper Mixin applied to list wrapper, can be used to controll list height {}
--esmm-delete-icon-color Color applied to the multi select dropdown 'x' button , which deselects a selected option #dd2c00
--esmm-search-input-label Mixin aplied to the search input label {}

<etools-searchable-multiselection-menu> - DEPRECATED

Dropdown menu with search and multiple options selection

Element properties

  • ajaxParams - Object(optional) used to set build query string for the URL of missing options request.
  • allowOutsideScroll - Boolean, default: false
  • autoValidate - Boolean
  • capitalizeInputShown - Boolean
  • customObjectOptions - Boolean, default: false
  • disabled - Boolean, default: false
  • dynamicAlign - Boolean, default: false
  • emptyValue - Boolean, default: false
  • errorMessage - string
  • falseValue - Boolean, default: false
  • hideSearch - Boolean, default: false
  • invalid - boolean
  • label - String
  • menuOpened - Boolean, default: false – notifies
  • multi - Boolean, default: false
  • noChangeEvent - Boolean, default: false
  • noOptionsAvailable - Boolean, default: false
  • notFoundValues - Array
  • optionLabel - String, default: label
  • options - Array
  • optionValue - String, default: 'value'
  • placeholder - string
  • readonly - Boolean, default: false
  • required - boolean
  • search - String
  • selected - Number/Array - notifies
  • selectedRequiresValidOptions - Boolean, default: false; using this and selected will ensure selected values will be set only if the options are not empty
  • selectedValues - Object notifies
  • showLimitWarning - Boolean
  • shownItems - Array
  • shownItemsLimit - Number, default: 50
  • twoLinesLabel - Boolean, default: false
  • updateSelected - Boolean, default: false
  • url - String, the url used to request selected missing options from server(one missing option someUrl?values=1, many missing options someUrl?values=1,2,3). This can be used only with selected and updateSelected properties. The response of the missing options request should be an array with one or more objects with the same properties dropdown options have.
  • value - String
  • disableOnFocusHandling - Boolean, default: false. Set to true to disable onFocus handling on the dropdown (more specifically the contained paper-input-container). We set this to true when the dropdown is in a modal, to avoid a bug that consists of the dropdown overlay closing and opening again and remaining opened , when clicking outside the dropdown or after selecting an item
  • fitInto - Element, default: undefined. To not overlap your app header or any other elements you can set this property to an element. The dropdown will not overflow this element margins.
  • viewportEdgeMargin - Number, default: 20. In case dropdown is downwards opened and reach the viewport edge, this value will be added as a bottom margin.

Usage

Examples:

Single selection, with search

<etools-searchable-multiselection-menu
      label="Searchable menu"
      options="[[realOptions]]"
      value="{{selectedValues}}"></etools-searchable-multiselection-menu>

Single selection, without search

<etools-searchable-multiselection-menu label="Options menu"
     options="[[realOptions]]"
     value="{{selectedValues}}"
     hide-search></etools-searchable-multiselection-menu>

Multi selection, with search

<etools-searchable-multiselection-menu label="Multiselection Searchable menu"
     options="[[realOptions]]"
     value="{{selectedValues}}"
     multi></etools-searchable-multiselection-menu>

Single selection, with search, limit of 3 elements

<etools-searchable-multiselection-menu
              label="Searchable menu"
              options="[[realOptions]]"
              shown-items-limit="3"
              value="{{selectedValues}}"></etools-searchable-multiselection-menu>

Single selection, with search, always display an empty value (-- None --)

<etools-searchable-multiselection-menu
              label="Searchable menu"
              options="[[realOptions]]"
              empty-value
              value="{{selectedValues}}"></etools-searchable-multiselection-menu>

Change event('value-change') examples

<etools-searchable-multiselection-menu
    label="Searchable menu"
    options="[[realOptions]]"
    on-value-change="_singleSelectionChanged"></etools-searchable-multiselection-menu>

<etools-searchable-multiselection-menu
    label="Multi searchable menu"
    options="[[realOptions]]"
    on-value-change="_multiSelectionChanged"
    multi></etools-searchable-multiselection-menu>

Error messages and validations. You can use invalid, auto-validate, required to validate your selection.

<etools-searchable-multiselection-menu
        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-searchable-multiselection-menu>

<etools-searchable-multiselection-menu
        id="dropdownElementMulti"
        label="Multi searchable menu with validation manually triggered (in 3s)"
        options="[[realOptions]]"
        placeholder="Select your options"
        error-message="You must select at least an option"
        auto-validate required
        multi></etools-searchable-multiselection-menu>

Validation triggered from javascript:

this.$.dropdownElement.validate();
// or
this.$.dropdownElementMulti.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: {
    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_propery: 'dummy propery for objIdx' + (i -1)
        });
      }
      return opt;
    }
}
<etools-searchable-multiselection-menu
        label="Searchable menu, custom objects"
        options="[[customObjOptions]]"
        custom-object-options
        option-value="option_key"
        option-label="option_label"
        on-value-change="_singleSelectionChanged"></etools-searchable-multiselection-menu>

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:

<p>SelectedID: [[selectedId]]</p>
<etools-searchable-multiselection-menu
    label="Searchable menu, custom objects"
    options="[[customObjOptions]]"
    custom-object-options
    option-value="id"
    option-label="option_label"
    selected="{{selectedId}}"
    update-selected
    url="http://some-url-to-get-missing-selected-options">
</etools-searchable-multiselection-menu>

Install

$ bower install --save etools-searchable-multiselection-menu

Preview element locally

Install needed dependencies by running: $ bower install. Make sure you have the Polymer CLI installed. Then run $ polymer serve to serve your element application locally.

Linting the code

Innstall local npm packages (run npm install) Then just run the linting task

$ npm run lint

You should also use polylint. If you don't have Polylint installed run npm install -g polylint. Then just run the linter on each file you wish to check like so

$ polylint -i filename.html

At the moment polylint crashes if it encounters a missing import. If that happens, temporarily comment out such imports and run the command again.

Running Tests

You need to have web-component-tester installed (if not run npm install -g web-component-tester)

$ wct

or

$ wct -p