# j-Directory

> It's similar component like j-Suggestion, but has improved design and supports more handy features.

Framework: jcomponent20
Product: jComponent 20 (jcomponent@20)
Language: en
Content-SHA256: 8995b6b7f349e33de32c69128dbac4c5e14ad1b985207dcbc865d0b0956b39cc
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: components@910ed1a86f6e72b4f031d3ad0dc7844f9fc5cb8e
Review: not-recorded

It's similar component like `j-Suggestion`, but has improved design and supports more handy features.

- singleton
- works with touches
- supports __dark mode__

> __IMPORTANT__: by default this component renders a value as a text from `name` property.


__Methods__:

Method: `component.show(options)`

- `options.element {Element/jQuery Element}`
- `options.items {Array/String/Function}` a list of items (`String` type means a link to data-source)
- `options.offsetX {Number}` optional, `x` offset (default: `0`)
- `options.offsetY {Number}` optional, `y` offset (default: `0`)
- `options.offsetWidth {Number}` optional, `width` offset (default: `0`)
- `options.placeholder {String}` optional, a placeholder for search field
- __NEW__ `options.height {Number}` optional, a height of the container (default: `180`)
- `options.render {Function}` optional, a function for customized render of item `function(item, text)` must return `HTML`
- `options.custom {Boolean/String}` optional, enables returning a value not defined in `options.items`, default: `false`
- `options.minwidth {Number}` optional, a minimal width, default `200`
- `options.maxwidth {Number}` optional, a maximal width, default `infinite`
- `options.callback(selected_item, element, iscustom, e) {Function}` is triggered when the user clicks on the item
- `options.key {String}` optional, a default `key` for `text` value (default: `name`)
- `options.empty {String}` optional, adds empty field
- `options.exclude {Function}` optional, can exclude items and must return a boolean `function(item) { return item.id !== 100 }`
- `options.close {Function}` optional, can determine closing of panel
- `options.search {Boolean/String}` optional, can hide search field (default: `true`) or `{String}` (key name) can map a value for searching
- `options.selected {Object}` optional, can contain a selected value (default: `undefined`)
- `options.align {String}` optional, `left` (default), `right` or `center`
- `options.position {String}` optional, `top` (default), `bottom`
- `options.raw {Boolean}` optional, this option disables escaping of characters (in other words: HTML content will be allowed in labels of items, default: `false`)
- `options.classname {String}` optional, a custom container class for all items
- absolute positioning works only if `options.element` is not defined
	- `options.x {Number}` absolute position X
	- `options.y {Number}` absolute position y
- `options.checkbox {Boolean}` optional, enables checkboxes
- `options.checked {Array String}` optional, identifiers of checked items
	- targeted for `options.items {Function(q, next)}`
	- the callback returns only raw identifiers `Array {String}`
- __NEW__ `options.template {String}` optional, a custom Tangular template e.g. `{{ name }}` (default: null)
- __NEW__ `options.fuzzy {Boolean}` optional, it can disable fuzzy search (default: `true`)

Method: `component.hide()`

__Configuration__:
- `placeholder` - a placeholder for the search input
- `create` - a placeholder for `Create` label (default: `Create`)

__Supported item fields__:

- `name {String}` a label name
- `template {String}` optional, a custom Tangular template
- `classname {String}` optional, adds additional classes into the `<li>` element
- `disabled {Boolean}` optional, it can disable item
- `selected {Boolean}` optional, it selects item

__Formatting via Tangular__:

```js
var opt = {};
opt.items = [];
opt.push({ name: 'Total.js', template: '<b>{{ name }}</b>' });
```

__Formatting via custom function__:

```js
var opt = {};
opt.items = [];
opt.push({ name: 'Total.js' });
opt.push({ name: 'Express.js' });
opt.push({ name: 'Koa.js' });
opt.render = function(item, name) {
	return '<b>' + name + '</b>';
};
```

__Adding of custom class__:

```js
var opt = {};
opt.items = [];
opt.push({ name: 'Total.js', classname: 'your_class_name' });
```

__Server-side searching__:

```js

var opt = {};

opt.element = your_element;

opt.items = function(search, next) {
	next([{ name: 'Item 1' }, { name: 'Item 2' }]);
};

opt.callback = function(selected) {
	console.log(selected);
};

SETTER('directory/show', opt);
```

__Good to know__:

- if `checkboxes:true` then the component extend items by adding a timestamp `selectedts {Number}` due to order

Use it with `<ui-component name="directory">`. When the component is not loaded yet, jComponent downloads it on first use from the address in `DEF.fallback` (the Componentator CDN by default). Author: Peter Širka. Source: the Componentator components repository, MIT license.

```html example.html
<style>
	body { background-color: #F0F0F0; }
</style>

<ui-component name="directory" config="placeholder:Search ..."></ui-component>

<div class="container">
	<div><a href="javascript:void(0)" data-name="classic">Open directory - classic</a></div>
	<div><a href="javascript:void(0)" data-name="checkboxes">Open directory - checkboxes</a></div>
</div>

<script>
	$(document).on('click', 'a', function() {


		var opt = {};
		opt.element = $(this);

		if (opt.element.attrd('name') === 'checkboxes') {
			opt.checkbox = true;
			opt.items = [{ name: 'Total.js', selected: true }, { name: 'Express.js', selected: true }, { name: 'Meteor.js' }, { name: 'Koa.js' }, { name: 'ASP.NET' }, { name: 'PHP' }, { name: 'Python' }, { name: 'Node.js' }];
		} else
			opt.items = [{ name: 'Total.js', template: '<b>{{ name }}</b>' }, { name: 'Express.js' }, { name: 'Meteor.js' }, { name: 'Koa.js' }, { name: 'ASP.NET' }, { name: 'PHP' }, { name: 'Python' }, { name: 'Node.js' }];

		opt.callback = function(value) {
			if (opt.checkbox)
				console.log('SELECTED:', value);
			else
				console.log('CLICKED:', value);
		};

		SETTER('directory/show', opt);
	});
</script>
```
