Configuration

Options can be passed in an object as the second argument to dropulous(target, options), or set via data-<option-name> attributes on the input or select element.

source

URL of an API endpoint to load options from.

Called with ?q=<query> on each keystroke.

Must return {"options": [{value, label}, ...]} - see From an API for the full response format.

  • Data attribute: data-source

canAdd

Allow the user to create new options not in the list.

  • Data attribute: data-can-add.

  • Default: false.

minQueryLength

Minimum number of characters the user must type before an API request is sent. Has no effect when options are loaded locally.

  • Data attribute: data-min-query-length.

  • Default: 0.

debounceTime

Milliseconds to wait after the last keystroke before sending an API request.

  • Data attribute: data-debounce-time.

  • Default: 300.

formatOption

Function called to render each option in the dropdown.

Receives a Dropulous.Option and must return an HTML string. See Custom formatters.

formatSelected

Function called to render each selected item.

Receives a Dropulous.Option and must return an HTML string. See Custom formatters.

templates

Object of HTML template strings to override the default markup.

See HTML templates.

Initial values

For <select> elements, pre-selected options are read from the selected attribute on <option> elements as normal.

For <input> elements, the initial value is read from the value attribute, or the data-value attribute (if set, takes priority over value). For multiple-selection inputs, supply a comma-separated string:

<input type="text" data-value="two,three" data-multiple ...>

When using an API source on a <select>, data-value can select values before the API loads:

<select data-source="/api/options/" data-value="two,three" multiple>
</select>

Custom formatters

formatOption and formatSelected are methods that receive a Dropulous.Option object and return an HTML string.

formatOption controls how options appear in the open dropdown; formatSelected controls how selected values appear in the control.

A Dropulous.Option has:

  • value - the option’s value string

  • label - the plain-text label, used for search matching and aria labels

  • html - optional pre-rendered markup to display instead of the escaped label

  • data - an object of extra data (from data-* attributes on <option> elements, or the data field in a data-options or API response)

Since a formatter’s return value is inserted directly as HTML, you can escape any values which are potentially unsafe with the helper function Dropulous.escapeHtml(text):

dropulous(document.querySelector('#my-field'), {
  formatOption: (option) => `<img src="${Dropulous.escapeHtml(option.data.icon)}"> ${Dropulous.escapeHtml(option.label)}`,
  formatSelected: (option) => `<img src="${Dropulous.escapeHtml(option.data.icon)}"> ${Dropulous.escapeHtml(option.label)}`,
});

When an API response includes html, that HTML is used directly and formatters are not called.

HTML templates

Every piece of Dropulous markup is defined as an HTML template string and can be overridden via the templates option. Templates use {key} placeholders.

field

The outer wrapper structure.

Contains the field area, display element, search input, clear button, dropdown panel, and options listbox.

No placeholders.

tag

A selected value in multiple mode.

Placeholders:

  • {value} - the option’s value

  • {label} - the rendered HTML label

  • {labelText} - the plain-text equivalent used in the remove button’s aria-label.

option

A row in the open dropdown list.

Placeholders:

  • {value} - the option’s value

  • {label} - the rendered HTML label

  • {highlighted} - expands to the attribute data-highlighted (or empty string) when the row has keyboard focus

  • {active} - expands to data-active (or empty string) when the value is already selected

{highlighted} and {active} are intended as HTML attribute insertions, not text content.

loading

Shown in the dropdown while an API request is in progress.

No placeholders.

noResults

Shown when no options match the current query.

No placeholders.

addNew

The “Add …” entry shown at the bottom of the list when canAdd is set and the current query does not exactly match any existing option.

Placeholders:

  • {query} - the current search query.

Example - replacing the loading indicator:

dropulous(document.querySelector('#my-field'), {
  source: '/api/options/',
  templates: {
    loading: '<div class="my-spinner">Loading...</div>',
  },
});

Example - custom option markup:

dropulous(document.querySelector('#my-field'), {
  templates: {
    option: '<div role="option" data-value="{value}"{highlighted}{active} class="my-option">{label}</div>',
  },
});

Customising the style

The default stylesheet uses CSS custom properties on :root for easy customisation. Override them on .dropulous (or :root) to restyle without touching the source:

.dropulous {
  --dropulous-border:      #d1d5db;   /* border colour */
  --dropulous-radius:      0.4rem;      /* border radius */
  --dropulous-focus:       #3b82f6;   /* focus and active border colour */
  --dropulous-z:           1000;        /* z-index for the dropdown panel */
  --dropulous-max-h:       16rem;       /* max-height of the options list */
  --dropulous-font:        sans-serif;
  --dropulous-size:        0.9rem;
  --dropulous-lh:          1.2rem;
  --dropulous-bg:          #ffffff;   /* control background */
  --dropulous-text:        #111827;   /* primary text */
  --dropulous-placeholder: #9ca3af;   /* placeholder and status-message text */
  --dropulous-hover:       #f3f4f6;   /* option row hover background */
  --dropulous-active:      #dbeafe;   /* already-selected option background */
  --dropulous-highlight:   #eff6ff;   /* keyboard-highlighted option background */

  /* Tags (multiple mode) */
  --dropulous-tag-bg:      #e5e7eb;   /* tag chip background */
  --dropulous-tag-text:    #1f2937;   /* tag chip text */
}