Компоненты. Пример

от автора

в начало заметок о компонентах

Выпадающий список

Создадим простую компоненту, выпадающий dropdown список. (Обратите внимание, в коде всех заметок не будет jQuery). Пусть у нас есть якорь (форма ввода), и пусть, когда она получает фокус, под ней возникает выпадающий список заранее определенных значений. При клике на элементе списка получим его значение в произвольной функции.

image text

Код примера доступен по адресу 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *