# EasyDropDown 4
[](https://travis-ci.org/patrickkunka/easydropdown)
[](https://coveralls.io/github/patrickkunka/easydropdown)
[](https://www.npmjs.com/package/easydropdown)
[](https://www.apache.org/licenses/)
EasyDropDown transforms the humble `<select>` element into a blank canvas for your design and brand. As a drop-in enhancement, EasyDropDown maintains all the functionality and accessibility of a standard single-option select menu, while exposing a semantic DOM-structure that's easy to style and customize to the needs of your design.
EasyDropDown comes bundled with three [ready-made themes](./demos/themes) which can be used as a starting point for custom styling.
Check out the **[demos](https://demos.kunkalabs.com/easydropdown/)** to see what's possible. The source code for the demos can be found in the [./demos/](./demos/) directory.
*NB: If you are viewing the demos on a mobile device, you will see the device's native select UI as per the [default configuration](#usenativeuionmobile).*
### Features
- Respects the native `<select>` element API*
- Full keyboard support (navigation, search and select)
- Emits native `change` events
- Enhanced placeholder support
- Form reset and validation support
- Collision detection
- Live updates
- Falls back to native UI on mobile devices
- CSS Modules support
- TypeScript/intellisense support
- ARIA-compliant-markup
- Support for IE9+, and all modern browsers.
- 9kb gzipped
- No third-party dependencies
**EasyDropDown [does not support](#multiple-attribute-support) the `multiple` attribute.*
#### Contents
- [Installation](#installation)
- [Usage](#usage)
- [Single-instance instantiation](#single-instance-instantiation)
- [Batch instantiation](#batch-instantiation)
- [Placeholder Functionality](#placeholder-functionality)
- [Reading and Writing Values](#reading-and-writing-values)
- [Anatomy of EasyDropDown](#anatomy-of-easydropdown)
- [Configuration Options](#configuration-options)
- [Available Options](#available-options)
- [API Methods](#api-methods)
- [React Example](#react-example)
- [CSS Modules Example](#css-modules-example)
- [TypeScript Support](#typescript-support)
- [Multiple Attribute Support](#multiple-attribute-support)
## Installation
Firstly, install the package using your package manager of choice.
```
npm install easydropdown --save
```
#### Module Import
You may then import the `easydropdown()` factory function into your project's modules.
```js
// ES Modules
import easydropdown from 'easydropdown';
// CommonJS
const easydropdown = require('easydropdown');
// AMD/RequireJS
define(['easydropdown/bundles/easydropdown.js'] , easydropdown => {
...
});
```
#### Script Tag
Alternatively, for basic projects without modular scoping or a build process, the most simple way to use EasyDropDown is via a `<script>` tag before your closing body tag. A pre-built "UMD" bundle is provided for this purpose which can be found at `./bundle/easydropdown.js`.
```html
...
<script src="./path/to/easydropdown.min.js"/>
</body>
```
This will attach the `easydropdown` factory function to the `window` as a global.
## Usage
Because EasyDropDown is an enhancement on top of native the `<select>` element, we must firstly create an underlying select element in our project's HTML, just as we normally would:
```html
<select name="foo" id="my-select">
<option value="">Select</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
...
</select>
```
Next, we instantiate EasyDropDown by passing a reference to the select element(s), or a selector string. We can either instantiate a single instance at a time, or a batch of instances.
#### Single-instance Instantiation
We can create an instance of EasyDropDown by passing a reference to a `<select>` element to the `easydropdown()` factory function:
```js
const selectElement = document.querySelector('#my-select');
const edd = easydropdown(selectElement);
```
Or, by passing a selector string directly:
```js
const edd = easydropdown('#my-select');
```
As shown above, a reference to the dropdown instance (`edd`) can be held onto in order to destroy it later, or interact with the dropdown programmatically. See [API Methods](#api-methods) for more information.
This approach is recommended for any component-based architecture where only the component is concerned with the dropdown instance.
The factory function also accepts an optional second parameter of configuration options. See [Configuration Options](#configuration-options) for more information.
#### Batch Instantiation
For simple static pages/applications, we can use the `.all()` static method of the factory function to crawl the DOM for *all* `<select>` elements found in the document, and then batch instantiate EasyDropDown on each one.
```js
easydropdown.all();
```
The `all()` method also accepts an optional parameter of configuration options to be passed to each instance. See [Configuration Options](#configuration-options) for more information.
### Placeholder Functionality
With the exception of the [multiple attribute](#multiple-attribute), EasyDropDown supports all the available attributes of the native `<select>` element, such as `disabled`, `required` and `selected`. In addition to these, EasyDropDown adds a new "placeholder" attribute.
A common pattern when working with `<select>` elements, is to use the first `<option>` element as a placeholder value by giving it an empty `""` value, as the first option will always be selected by default. For example:
```html
<select>
<option value="">Select an option</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
...
</select>
```
EasyDropDown enhances this pattern with the ability to add a `data-placeholder` attribute to this element to inform EasyDropDown that the option is a placeholder only and should *not* be an available selection once the user has selected a value.
```html
<select>
<option value="" data-placeholder>Select an option</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
...
</select>
```
Check out the [Basic List with Placeholder](https://demos.kunkalabs.com/easydropdown/02-basic-list-with-placeholder.html) demo to see an example of this feature.
*NB: This feature should not be used if you want the user to be able to leave the field blank.*
Additionally, EasyDropDown can be configured to reshow the placeholder value after a value has been selected as a hint to the user whenever the dropdown is open. This is available via the `behavior.showPlaceholderWhenOpen` configuration option, and can be seen in the [Show Placeholder When Open](https://demos.kunkalabs.com/easydropdown/11-show-placeholder-when-open.html) demo.
### Reading and Writing Values
As en enhancement on top of native `<select>` elements, EasyDropDown always keeps the underyling `<select>` element in sync with the current selection (emitting a `change` event on value change), and conversely, always updates itself in response to a programmatic change in value to the underlying select.
As such, you can read and write the `value` of the underlying select, just as you normally would.
```js
const selectElement = document.querySelector('#my-select');
const edd = easydropdown(selectElement);
selectElement.value = 'foo';
console.log(edd.value); // foo
```
> Writing a value to the select element
```js
const selectElement = docum