2017-04-19 11:16:58 -04:00
|
|
|
# DropLab
|
|
|
|
|
|
|
|
A generic dropdown for all of your custom dropdown needs.
|
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
DropLab can be used by simply adding a `data-dropdown-trigger` HTML attribute.
|
|
|
|
This attribute allows us to find the "trigger" _(toggle)_ for the dropdown,
|
|
|
|
whether that is a button, link or input.
|
|
|
|
|
|
|
|
The value of the `data-dropdown-trigger` should be a CSS selector that
|
|
|
|
DropLab can use to find the trigger's dropdown list.
|
|
|
|
|
|
|
|
You should also add the `data-dropdown` attribute to declare the dropdown list.
|
|
|
|
The value is irrelevant.
|
|
|
|
|
|
|
|
The DropLab class has no side effects, so you must always call `.init` when
|
|
|
|
the DOM is ready. `DropLab.prototype.init` takes the same arguments as `DropLab.prototype.addHook`.
|
|
|
|
If you do not provide any arguments, it will globally query and instantiate all droplab compatible dropdowns.
|
|
|
|
|
|
|
|
```html
|
|
|
|
<a href="#" data-dropdown-trigger="#list">Toggle</a>
|
|
|
|
|
|
|
|
<ul id="list" data-dropdown>
|
|
|
|
<!-- ... -->
|
|
|
|
<ul>
|
|
|
|
```
|
|
|
|
```js
|
|
|
|
const droplab = new DropLab();
|
|
|
|
droplab.init();
|
|
|
|
```
|
|
|
|
|
|
|
|
As you can see, we have a "Toggle" link, that is declared as a trigger.
|
|
|
|
It provides a selector to find the dropdown list it should control.
|
|
|
|
|
|
|
|
### Static data
|
|
|
|
|
|
|
|
You can add static list items.
|
|
|
|
|
|
|
|
```html
|
|
|
|
<a href="#" data-dropdown-trigger="#list">Toggle</a>
|
|
|
|
|
|
|
|
<ul id="list" data-dropdown>
|
|
|
|
<li>Static value 1</li>
|
|
|
|
<li>Static value 2</li>
|
|
|
|
<ul>
|
|
|
|
```
|
|
|
|
```js
|
|
|
|
const droplab = new DropLab();
|
|
|
|
droplab.init();
|
|
|
|
```
|
|
|
|
|
|
|
|
### Explicit instantiation
|
|
|
|
|
|
|
|
You can pass the trigger and list elements as constructor arguments to return
|
|
|
|
a non-global instance of DropLab using the `DropLab.prototype.init` method.
|
|
|
|
|
|
|
|
```html
|
|
|
|
<a href="#" id="trigger" data-dropdown-trigger="#list">Toggle</a>
|
|
|
|
|
|
|
|
<ul id="list" data-dropdown>
|
|
|
|
<!-- ... -->
|
|
|
|
<ul>
|
|
|
|
```
|
|
|
|
```js
|
|
|
|
const trigger = document.getElementById('trigger');
|
|
|
|
const list = document.getElementById('list');
|
|
|
|
|
|
|
|
const droplab = new DropLab();
|
|
|
|
droplab.init(trigger, list);
|
|
|
|
```
|
|
|
|
|
|
|
|
You can also add hooks to an existing DropLab instance using `DropLab.prototype.addHook`.
|
|
|
|
|
|
|
|
```html
|
|
|
|
<a href="#" data-dropdown-trigger="#auto-dropdown">Toggle</a>
|
|
|
|
<ul id="auto-dropdown" data-dropdown><!-- ... --><ul>
|
|
|
|
|
|
|
|
<a href="#" id="trigger" data-dropdown-trigger="#list">Toggle</a>
|
|
|
|
<ul id="list" data-dropdown><!-- ... --><ul>
|
|
|
|
```
|
|
|
|
```js
|
|
|
|
const droplab = new DropLab();
|
|
|
|
|
|
|
|
droplab.init();
|
|
|
|
|
|
|
|
const trigger = document.getElementById('trigger');
|
|
|
|
const list = document.getElementById('list');
|
|
|
|
|
|
|
|
droplab.addHook(trigger, list);
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Dynamic data
|
|
|
|
|
|
|
|
Adding `data-dynamic` to your dropdown element will enable dynamic list rendering.
|
|
|
|
|
|
|
|
You can template a list item using the keys of the data object provided.
|
|
|
|
Use the handlebars syntax `{{ value }}` to HTML escape the value.
|
|
|
|
Use the `<%= value %>` syntax to simply interpolate the value.
|
|
|
|
Use the `<%= value %>` syntax to evaluate the value.
|
|
|
|
|
|
|
|
Passing an array of objects to `DropLab.prototype.addData` will render that data
|
|
|
|
for all `data-dynamic` dropdown lists tracked by that DropLab instance.
|
|
|
|
|
|
|
|
```html
|
|
|
|
<a href="#" data-dropdown-trigger="#list">Toggle</a>
|
|
|
|
|
|
|
|
<ul id="list" data-dropdown data-dynamic>
|
|
|
|
<li><a href="#" data-id="{{id}}">{{text}}</a></li>
|
|
|
|
</ul>
|
|
|
|
```
|
|
|
|
```js
|
|
|
|
const droplab = new DropLab();
|
|
|
|
|
|
|
|
droplab.init().addData([{
|
|
|
|
id: 0,
|
|
|
|
text: 'Jacob',
|
|
|
|
}, {
|
|
|
|
id: 1,
|
|
|
|
text: 'Jeff',
|
|
|
|
}]);
|
|
|
|
```
|
|
|
|
|
|
|
|
Alternatively, you can specify a specific dropdown to add this data to but passing
|
|
|
|
the data as the second argument and and the `id` of the trigger element as the first argument.
|
|
|
|
|
|
|
|
```html
|
|
|
|
<a href="#" data-dropdown-trigger="#list" id="trigger">Toggle</a>
|
|
|
|
|
|
|
|
<ul id="list" data-dropdown data-dynamic>
|
|
|
|
<li><a href="#" data-id="{{id}}">{{text}}</a></li>
|
|
|
|
</ul>
|
|
|
|
```
|
|
|
|
```js
|
|
|
|
const droplab = new DropLab();
|
|
|
|
|
|
|
|
droplab.init().addData('trigger', [{
|
|
|
|
id: 0,
|
|
|
|
text: 'Jacob',
|
|
|
|
}, {
|
|
|
|
id: 1,
|
|
|
|
text: 'Jeff',
|
|
|
|
}]);
|
|
|
|
```
|
|
|
|
|
|
|
|
This allows you to mix static and dynamic content with ease, even with one trigger.
|
|
|
|
|
|
|
|
Note the use of scoping regarding the `data-dropdown` attribute to capture both
|
|
|
|
dropdown lists, one of which is dynamic.
|
|
|
|
|
|
|
|
```html
|
|
|
|
<input id="trigger" data-dropdown-trigger="#list">
|
|
|
|
<div id="list" data-dropdown>
|
|
|
|
<ul>
|
|
|
|
<li><a href="#">Static item 1</a></li>
|
|
|
|
<li><a href="#">Static item 2</a></li>
|
|
|
|
</ul>
|
|
|
|
<ul data-dynamic>
|
|
|
|
<li><a href="#" data-id="{{id}}">{{text}}</a></li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
```
|
|
|
|
```js
|
|
|
|
const droplab = new DropLab();
|
|
|
|
|
|
|
|
droplab.init().addData('trigger', [{
|
|
|
|
id: 0,
|
|
|
|
text: 'Jacob',
|
|
|
|
}, {
|
|
|
|
id: 1,
|
|
|
|
text: 'Jeff',
|
|
|
|
}]);
|
|
|
|
```
|
|
|
|
|
|
|
|
## Internal selectors
|
|
|
|
|
|
|
|
DropLab adds some CSS classes to help lower the barrier to integration.
|
|
|
|
|
|
|
|
For example,
|
|
|
|
|
|
|
|
* The `droplab-item-selected` css class is added to items that have been selected
|
|
|
|
either by a mouse click or by enter key selection.
|
|
|
|
* The `droplab-item-active` css class is added to items that have been selected
|
|
|
|
using arrow key navigation.
|
2017-04-20 03:38:28 -04:00
|
|
|
* You can add the `droplab-item-ignore` css class to any item that you do not want to be selectable. For example,
|
|
|
|
an `<li class="divider"></li>` list divider element that should not be interactive.
|
2017-04-19 11:16:58 -04:00
|
|
|
|
|
|
|
## Internal events
|
|
|
|
|
|
|
|
DropLab uses some custom events to help lower the barrier to integration.
|
|
|
|
|
|
|
|
For example,
|
|
|
|
|
|
|
|
* The `click.dl` event is fired when an `li` list item has been clicked. It is also
|
|
|
|
fired when a list item has been selected with the keyboard. It is also fired when a
|
|
|
|
`HookButton` button is clicked (a registered `button` tag or `a` tag trigger).
|
|
|
|
* The `input.dl` event is fired when a `HookInput` (a registered `input` tag trigger) triggers an `input` event.
|
|
|
|
* The `mousedown.dl` event is fired when a `HookInput` triggers a `mousedown` event.
|
|
|
|
* The `keyup.dl` event is fired when a `HookInput` triggers a `keyup` event.
|
|
|
|
* The `keydown.dl` event is fired when a `HookInput` triggers a `keydown` event.
|
|
|
|
|
|
|
|
These custom events add a `detail` object to the vanilla `Event` object that provides some potentially useful data.
|
|
|
|
|
|
|
|
## Plugins
|
|
|
|
|
|
|
|
Plugins are objects that are registered to be executed when a hook is added (when a droplab trigger and dropdown are instantiated).
|
|
|
|
|
|
|
|
If no modules API is detected, the library will fall back as it does with `window.DropLab` and will add `window.DropLab.plugins.PluginName`.
|
|
|
|
|
|
|
|
### Usage
|
|
|
|
|
|
|
|
To use plugins, you can pass them in an array as the third argument of `DropLab.prototype.init` or `DropLab.prototype.addHook`.
|
|
|
|
Some plugins require configuration values, the config object can be passed as the fourth argument.
|
|
|
|
|
|
|
|
```html
|
|
|
|
<a href="#" id="trigger" data-dropdown-trigger="#list">Toggle</a>
|
|
|
|
<ul id="list" data-dropdown><!-- ... --><ul>
|
|
|
|
```
|
|
|
|
```js
|
|
|
|
const droplab = new DropLab();
|
|
|
|
|
|
|
|
const trigger = document.getElementById('trigger');
|
|
|
|
const list = document.getElementById('list');
|
|
|
|
|
|
|
|
droplab.init(trigger, list, [droplabAjax], {
|
|
|
|
droplabAjax: {
|
|
|
|
endpoint: '/some-endpoint',
|
|
|
|
method: 'setData',
|
|
|
|
},
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
|
|
|
### Documentation
|
|
|
|
|
|
|
|
* [Ajax plugin](plugins/ajax.md)
|
|
|
|
* [Filter plugin](plugins/filter.md)
|
|
|
|
* [InputSetter plugin](plugins/input_setter.md)
|
|
|
|
|
|
|
|
### Development
|
|
|
|
|
|
|
|
When plugins are initialised for a droplab trigger+dropdown, DropLab will
|
|
|
|
call the plugins `init` function, so this must be implemented in the plugin.
|
|
|
|
|
|
|
|
```js
|
|
|
|
class MyPlugin {
|
|
|
|
static init() {
|
|
|
|
this.someProp = 'someProp';
|
|
|
|
this.someMethod();
|
|
|
|
}
|
|
|
|
|
|
|
|
static someMethod() {
|
|
|
|
this.otherProp = 'otherProp';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default MyPlugin;
|
|
|
|
```
|