Usage

Initialisation

Explicit initialisation

Call dropulous() on any <select> or <input type="text"> element:

<select id="my-field">
  <option value="one">One</option>
  <option value="two" selected>Two</option>
  <option value="three">Three</option>
</select>

<script>
  dropulous(document.querySelector('#my-field'));
</script>

Pass an options object as a second argument:

dropulous(document.querySelector('#my-field'), {
  source: '/api/options/',
  canAdd: true,
});

Auto-initialisation

Add a data-dropulous attribute and Dropulous will initialise the element automatically on DOMContentLoaded:

<select data-dropulous data-source="/api/options/">
</select>

Calling dropulous() on an already-initialised element returns the existing instance.

Auto-initialisation runs Dropulous.init() on DOMContentLoaded. Call it yourself to initialise elements added to the page later, or to use a different selector:

Dropulous.init('.my-selector', { canAdd: true });

It accepts a CSS selector (default 'select[data-dropulous], input[data-dropulous]'), a single element, or a collection of elements, and returns an array of the Dropulous instances created.

Single vs multiple selection

Single selection is the default. Multiple selection is enabled by the multiple attribute on a <select>, or the data-multiple attribute on an <input>:

<!-- Multiple select -->
<select id="my-field" multiple>
  <option value="one">One</option>
  <option value="two" selected>Two</option>
  <option value="three" selected>Three</option>
</select>

<!-- Multiple input -->
<input
  id="my-field"
  type="text"
  value="two,three"
  data-multiple
  data-options='[{"value":"one","label":"One"},{"value":"two","label":"Two"},{"value":"three","label":"Three"}]'
>

In multiple mode, selected values are displayed as removable tags.

Custom parsing

For <input> elements, the field value is a comma-separated string, split by parseValue(str) and rejoined by formatValue(values).

You can override both in a subclass to use a different format:

class MyDropulous extends Dropulous {
  parseValue(str) {
    return str.split(';');
  }
  formatValue(values) {
    return values.join(';');
  }
}

Allowing new options (tagging)

Set data-can-add (or canAdd: true in the options object) to let users create options that aren’t in the list:

<select id="my-field" data-can-add>
  <option value="one">One</option>
</select>

When the user types a value that doesn’t match any option and presses Enter (or blurs the field), the new value is added and selected.

Field synchronisation

The original <select> or <input> element is kept hidden but stays in sync with the Dropulous control at all times.

Form submission, change event listeners, and any other code that reads from the original field will work without modification.

Keyboard navigation

  • Down arrow / Up arrow - move through options

  • Enter - select the highlighted option (or add a new one if canAdd is set)

  • Escape - close the dropdown

  • Backspace (multiple mode, empty input) - remove the last selected tag

Instance API

dropulous() returns a Dropulous instance with the following methods:

selectOption(value)

Select an option by value, and either replace the current selection in single mode. or add it to the selection in multiple mode,

deselectOption(value)

Remove a specific value from the selection.

addNewOption(value)

Create a new option and immediately select it.

open()

Open the dropdown.

close()

Close the dropdown.

getValue()

Return the selected value or null (single mode), or the selected values as an array (multiple mode),

setValue(value)

Replace the current selection. Accepts a single value, an array of values (multiple mode only), or null to clear.

setOptions(options)

Replace the available options with an array of {value, label} objects.

clearCache()

Discard cached remote results, so the next open or keystroke fetches fresh data from source. Use this if the data behind a remote source has changed.

destroy()

Remove the Dropulous control and restore the original field.

const field = dropulous(document.querySelector('#my-field'));
field.selectOption('two');