Class

Select

kiss.ui.Select(config, optionsFilteropt)

The Select derives from Component.

It's a multi-purpose select field, also known as "dropdown" or "combobox". It can have a single or multiple values. When multiple values, the field value returns an Array.

Features:

  • auto-generation of options with templates like "time" | "weekday" | "month"...
  • possible to use labels, to display something different than the field values
  • single or multiple values
  • auto-complete
  • possible to disable some options (they are hidden, but it could be easily extended to be visible, using a different class name)
  • possible to update the list of options afterward
  • keyboard navigation up and down within options
  • selection with mouse or Enter
  • can delete existing entries with Backspace
  • can sort values asc or desc
  • option to add values which are not in list
  • option to prevent duplicates
  • option to add entries using a separator, comma by default (useful for email-like inputs)
  • option to have a custom renderer for options
  • option to have a custom renderer for values
  • option to delete values by clicking on them
  • option to switch a value on/off by clicking on it in the dropdown list
  • option to hide or show the input (search) field
  • option to position the input (search) field after the values (default) or before
  • option to display values stacked one on another

To do

  • option to sort the list of options
  • option to reorder the field values with drag & drop
  • possibility to navigate the current values / delete them hitting the del key
  • other templates like range, weekday, month

Usage

To define the list of options, you can use a simple array of strings:

const listOfOptions = ["France", "Great Britain"]

Or an array of objects:

const listOfOptions = [
 {value: "France"},
 {value: "Great Britain"}
]

Or a function that returns the list of options:

const listOfOptions = () => {
 let options = []
 for (let i = 0; i < 10; i++) options.push({label: "Option " + i, value: i})
 return options
}

If you used a function to generate the options, you can also combine it with a filtering function:

const optionsFilter = (optionItem) => optionItem.value > 5

createSelect({
 label: "Select field with generated options",
 multiple: true,
 options: listOfOptions,
 optionsFilter // Will keep only the option items which value is > 5
})

You can use labels that are different from the values:

const listOfOptions = [
 {value: "FR", label: "France"},
 {value: "GB", label: "Great Britain"}
]

You can also set a color per option:

const listOfOptions = [
 {value: "FR", color: "#00aaee"},
 {value: "GB", color: "#a1ed00"}
]

You can disable some options:

const listOfOptions = [
 {value: "FR", color: "#00aaee"},
 {value: "GB", color: "#a1ed00"},
 {value: "USA", color: "#ff0000", disabled: true}
]

You can select one or multiple values thanks to the "multiple" parameter:

createSelect({
 label: "Countries",
 multiple: true,
 options: listOfOptions
})

You can define a custom renderer to display the field values. The default renderer is a function like this:

// Default renderer for field values
const valueRenderer = (option) =>
 `<div class="field-select-value" value="${option.value}" ${(option.color || this.optionsColor) ? `style="background: ${option.color || this.optionsColor}"` : ""}>
     ${option.label || option.value}
     ${(this.allowClickToDelete == true) ? `<span class="field-select-value-delete fas fa-times"></span>` : ""}
 </div>`

You can define a custom renderer for each option of the list. The default renderer is a function like this:

// Default renderer for the list of options
const optionRenderer = (option) => option.label || option.value

// It could be like:
const optionRenderer = (option) => "Label: " + option.label + " - Value: " + option.value
Constructor

# new Select(config, optionsFilteropt)

Its a Custom Web Component. Do not use the constructor directly with the new keyword. Instead, use one of the 3 following methods:

Create the Web Component and call its init method:

const mySelect = document.createElement("a-select").init(config)

Or use the shorthand for it:

const mySelect = createSelect({
  label: "Countries",
  options: [
      {value: "France"},
      {value: "Great Britain"}
  ]
})

mySelect.render()

Or directly declare the config inside a container component:

const myPanel = createPanel({
  title: "My panel",
  items: [
      {
          type: "select",
          options: [
              {value: "France"},
              {value: "Great Britain"}
          ]
      }
  ]
})
myPanel.render()
Parameters:
Name Type Attributes Description
config object
template object

"time" - TODO: other template like "range" | "weekday" | "month" | ...

options Array.<string> | Array.<object> | function

List of options or function that returns a list of options, where each option must a string, or an object like:
{value: "France"} or {label: "France", value: "FR"} or {label: "France", value: "FR", color: "#00aaee"}.

optionsFilter function <optional>

When the options are defined by a function, you can provide a filtering function that will be executed at runtime to filter only a specific set of options, depending on the context

config.multiple boolean <optional>

True to enable multi-select

config.value string | Array.<string> <optional>

Default value

config.optionsColor string <optional>

Default color for all options

config.valueSeparator string <optional>

Character used to display multiple values

config.inputSeparator string <optional>

Character used to input multiple values

config.stackValues boolean <optional>

True to render the values one on another

config.hideInput boolean <optional>

true (default) to automatically hide the input field after a completed search

config.allowValuesNotInList boolean <optional>

Allow to input a value which is not in the list of options

config.allowDuplicates boolean <optional>

Allow to input duplicate values. Default to false.

config.allowClickToDelete boolean <optional>

Add a "cross" icon over the values to delete them. Default to false.

config.allowSwitchOnOff boolean <optional>

Allow to click on a value to switch it on/off

config.optionRenderer function <optional>

Custom function to render each option in the list of options

config.valueRenderer function <optional>

Custom function to render the actual field values

config.label string <optional>
config.fieldWidth string <optional>
config.labelWidth string <optional>
config.labelPosition string <optional>

left | right | top | bottom

config.labelAlign string <optional>

left | right

config.autocomplete boolean <optional>

Set "off" to disable

config.readOnly boolean <optional>
config.disabled boolean <optional>
config.required boolean <optional>
config.validationFunction function <optional>

Async function that must return true if the value is valid, false otherwise

config.margin string <optional>
config.padding string <optional>
config.display string <optional>

flex | inline flex

config.width string | number <optional>
config.height string | number <optional>

View Source client/ui/fields/select.js, line 178

this

Generated markup

The field is a composition of various elements:

  • a div for the field label
  • a div that renders the existing values (as chips, by default)
  • an input field, used to filter options
  • a div to display and select the options
<a-select class="a-select">
 <label class="field-label"></label>

 <div class="field-select">
     <span class="field-select-values"></span>
 </div>

 <div class="field-select-options">
     <span class="field-select-input"></span>

     <!-- For each option -->
     <div class="field-option"></div>
 </div>

</a-select>

Methods

# async addValue(newValue)

Add a value to the Select field. This method does a few things:

  • check for duplicate entries (and remove if not allowed)
  • check for multiple entries (and exit if not allowed)
  • update the field value
  • reset the input field then give it focus
Parameters:
Name Type Description
newValue string

Value to add

View Source client/ui/fields/select.js, line 632

# focus()

Give focus to the input field

View Source client/ui/fields/select.js, line 967

this

# getLabel() → {string}

Get the field label

View Source client/ui/fields/select.js, line 852

string

# getLabelPosition() → {string}

Get the label position

View Source client/ui/fields/select.js, line 911

"left" | "right" | "top"

string

# getSelection() → {object|Array.<object>}

Get the selected option(s)

View Source client/ui/fields/select.js, line 780

A single option or an array of options if multiple values are selected

object | Array.<object>

# getValue() → {string|Array.<string>}

Get the field value

View Source client/ui/fields/select.js, line 765

  • Returns an array of strings if the "multiple" option is true. Returns a string otherwise.
string | Array.<string>

# isEmpty() → {boolean}

Check if the field is empty

View Source client/ui/fields/select.js, line 721

boolean

# resetValue()

Reset the field value

View Source client/ui/fields/select.js, line 795

this

# setClickToDelete(state)

Allow/forbid to click on field values to delete them

Parameters:
Name Type Default Description
state boolean true

View Source client/ui/fields/select.js, line 958

# setFieldWidth(width)

Set the input field width

Parameters:
Name Type Description
width *

View Source client/ui/fields/select.js, line 888

this

# setInvalid()

Change the style when the field is invalid

View Source client/ui/fields/select.js, line 708

this

# setLabel(newLabel)

Set the field label

Parameters:
Name Type Description
newLabel string

View Source client/ui/fields/select.js, line 862

this

# setLabelPosition(position)

Set label position

Parameters:
Name Type Description
position string

"left" (default) | "right" | "top" | "bottom"

View Source client/ui/fields/select.js, line 921

this

# setLabelWidth(width)

Set the label width

Parameters:
Name Type Description
width *

View Source client/ui/fields/select.js, line 900

this

# setMultiple(state)

Allow/forbid to select multiple values

Parameters:
Name Type Default Description
state boolean true

View Source client/ui/fields/select.js, line 949

# setValid()

Remove the invalid style

View Source client/ui/fields/select.js, line 697

this

# setValue(newValue, rawUpdateopt)

Set the field value

Parameters:
Name Type Attributes Description
newValue string | Array.<string>

The new field value

rawUpdate boolean <optional>

If true, it doesn't update the associated record and doesn't trigger "change" event

View Source client/ui/fields/select.js, line 576

this

# setWidth(width)

Set the field container width

Parameters:
Name Type Description
width *

View Source client/ui/fields/select.js, line 876

this

# sort(order)

Sort values

Parameters:
Name Type Default Description
order string asc

"asc" or "desc"

View Source client/ui/fields/select.js, line 733

this

# sortByLabel(order)

Sort values according to their corresponding label

Parameters:
Name Type Default Description
order string asc

"asc" or "desc"

View Source client/ui/fields/select.js, line 747

this

# updateOptions(newOptions)

Update the list of options

Parameters:
Name Type Description
newOptions array

An array of object defining the field options

View Source client/ui/fields/select.js, line 815

Example
mySelectField.updateOptions([
     {
         value: "firstName",
         disabled: false,
         color: "#00aaee"
     },
     {...}
])

# validate() → {boolean}

Validate the field value against validation rules

View Source client/ui/fields/select.js, line 681

boolean