Выпадающий список
Создадим простую компоненту, выпадающий dropdown список. (Обратите внимание, в коде всех заметок не будет jQuery). Пусть у нас есть якорь (форма ввода), и пусть, когда она получает фокус, под ней возникает выпадающий список заранее определенных значений. При клике на элементе списка получим его значение в произвольной функции.
Код примера доступен по адресу https://github.com/mbykov/component-dropdown-example. Клонируйте его и откройте в браузере файл test/example.html
, кликните на input
.
Создадим скелет компоненты этого примера:
$ component create dropdown-example repo (username/project): mbykov/component-dropdown-example description: simple dropdown example . . .
в components.json нужно указать необходимые нам компоненты:
"dependencies": { "component/domify": "*", "component/each": "*", "component/classes": "*" },
И выполняем $ make
. В файле Makefile
вы увидите, в частности (о формате makefile в заметке makefile vs. grunt):
build: components index.js dropdown.css @component build --dev components: component.json @component install --dev
Это означает, что component
установит все зависимости и создаст файлы build/build.js и build/build.css
. (я переименовал исходный dd-example.css в dropdown.css, и соответственно исправил Makefile).
создание примера
Теперь создадим пример. Создаем директорию test
и в ней файл example.html
, суть которого
<p><input type="text" id="anchor"><p> <script> var anchor = document.querySelector('#anchor'); var Dropdown = require('dd-example'); var dd = new Dropdown(anchor); </script>
А в файле index.js
компоненты добавим основное содержание:
var domify = require('domify'); var classes = require('classes'); var each = require('each'); module.exports = Dropdown; function Dropdown(anchor) { console.log(anchor); return this; }
Обратите внимание на return this
— это важно. Теперь мы можем создать цепочку методов для нашей компоненты. Каждый следующий метод получает все тот же this.
Теперь снова make, и релоад тестовой страницы (пока мы не используем watch, поэтому make вручную). В Фаейрбаге видим, что все идет как нужно, видим якорь.
Напишем собственно компоненту dropdown
.
function Dropdown(anchor) { var _div = domify('<div class="dropdown-div"></div>'); var _list = domify('<ul class="dropdown-list"></ul>'); _div.appendChild(_list); this.list = _list; this.div = _div; this.anchor = anchor; anchor.parentNode.insertBefore(_div, anchor.nextSibling); anchor.focus(); return this; }
Что здесь происходит?
Мы создаем два объекта, _div
и _list
. Подчеркиванием мне удобно выделять DOM-объекты (underscore нам больше не нужен, а знак $ как-то не смотрится, но дело вкуса). В реальной жизни нужно, конечно, поместить html в template.html, и вызвать его require('template')
. Не делаю здесь для наглядности кода.
В строках this.list = _list
сохраняем эти объекты как атрибуты объекта this, это пригодится в цепочке методов. И добавляем новый объект на страницу.
$ make
Но ничего не изменилось? Правильно, теперь нужно показать список с предопределенными значениями при клике на якорь. Добавим в _div и файл .css класс hidden, и в функцию Dropdow клик на якорь, и метод toggle():
var self = this; anchor.onclick = function(e){ self.toggle(); classes(this.div).remove('hidden'); return false; }
и создадим метод, который покажет значения
Dropdown.prototype.render = function(values) { var self = this; values.each(function(value){ var added = domify('<li class="dropdown-line"></li>'); added.textContent = value; self.list.appendChild(added); }); return this; }
добавим в текст примера example.html вызов метода render
c предопреденными значениями: var values = ['Асафий Аскольдович'...
dd.render(values)
Здесь нет точки с запятой после строки. Это не ошибка, на следующей строчке будет вызван следующий метод компоненты — .select().
Теперь выведем значение при клике по строке списка в произвольном колбеке к нашей компоненте (Колбек в примере — будет просто console.log).
Dropdown.prototype.select = function(cb){ var self = this; this.list.onclick = function(e) { var value = e.target.textContent; anchor.value = value; self.hide(); cb(value); }; }
здесь нам не нужно возвращать return this
в конце функции, потому что это конец цепочки. Вызовем метод .select
в example.html
, в котором выведем значение на консоль. Voila.
заключение
Совсем уже последнее, и не имеющее прямого отношения к примеру — список выводится не под якорем, а в начале строки. Но для красоты выравняем список — это одна строчка в главной функции:
_div.style.left = getOffset(anchor).left +'px';
функцию getOffset я позаимствовал у Mathew Muellera, спасибо ему.
При создании этого примера и своей «взрослой» компоненты dropdown я ориентировался на примеры старших товарищей: component/dropdown
, stagas/dropdown
, bmcmahen/dropdown
, matthewmueller/autocomplete
. Они, правда, все используют jQuery, из-за чего я и написал свой mbykov/dropdown
— он рассчитан на json-данные, получаемые из couchdb
, поэтому имеет свои особенности.
Теперь можно использовать этот выпадающий список сколько угодно раз, с любыми предопределенными значениями, на одной странице или на многих.
продолжение следует
ссылка на оригинал статьи http://habrahabr.ru/post/209354/
Добавить комментарий