SimpleAutocomplete — различия между версиями

Материал из YourcmcWiki
Перейти к: навигация, поиск
м (Демонстрация)
м
 
(не показано 39 промежуточных версий этого же участника)
Строка 1: Строка 1:
[[en:SimpleAutocomplete/en]]
+
[[Category:Техактивы]][[en:SimpleAutocomplete/en]]
 
Простое автодополнение (autocomplete) в текстовых полях ввода. Поддерживает мультивыбор и управление с клавиатуры (вниз, вверх, enter = выбор).
 
Простое автодополнение (autocomplete) в текстовых полях ввода. Поддерживает мультивыбор и управление с клавиатуры (вниз, вверх, enter = выбор).
  
Исходники: [{{SVN|vitaphoto/js/hinter.js}} hinter.js], [{{SVN|vitaphoto/js/hinter.css}} hinter.css].
+
* Исходники: [{{SVN|vitaphoto/js/hinter.js}} hinter.js], [{{SVN|vitaphoto/js/hinter.css}} hinter.css].
 
+
* Минимизированный JS: [{{SVN|vitaphoto/js/hinter.min.js|co}} hinter.min.js]
Последнее обновление: {{/updatedate}}.
+
* Последнее обновление: {{/updatedate}}.
 +
* Лицензия: [http://www.mozilla.org/MPL/2.0/ Mozilla Public License версии 2.0] или более новой.
 +
*: В двух словах — «строгий файловый копилефт». Любой отдельный файл, включающий MPL-лицензированные куски кода, должен быть лицензирован под MPL2.0+, GPL2.0+, LGPL2.1+ или AGPL3.0+.
  
 
== Использование ==
 
== Использование ==
Строка 19: Строка 21:
  
 
; input: Поле ввода, в которое будем подсказывать, либо DOM-объект, либо его ID. ID, кстати, всегда необходимо.
 
; input: Поле ввода, в которое будем подсказывать, либо DOM-объект, либо его ID. ID, кстати, всегда необходимо.
; dataLoader(hint, value): Функция, которая должна загрузить опции для подсказки и вызвать <tt>hint.replaceItems([ [ name, value ], [ name, value ], ... ])</tt>. Первый параметр (hint) — объект автокомплита, на котором и надо вызывать replaceItems. Второй параметр — введённая пользователем строка, на основе которой надо предоставлять подсказки.
+
; dataLoader(hint, value, more): Функция, которая должна загрузить опции для подсказки и вызвать <tt>hint.replaceItems([ [ name, value ], [ name, value[, disabled[, checked]] ], ... ], more)</tt>.
 +
:* hint — объект автокомплита, на котором и надо вызывать replaceItems.
 +
:* value — введённая пользователем строка, на основе которой надо предоставлять подсказки.
 +
:* more — при использовании moreMarker «страница» подсказок, которую нужно загрузить (0 = первая страница).
 +
:: Параметры элементов: [ name, value[, disabled[, checked]] ]
 +
::* name — Название
 +
::* value — Значение (которое будет подставлено в поле ввода)
 +
::* disabled — «Выключена» ли эта опция — если да, то её будет невозможно выбрать
 +
::* checked — Отмечен ли изначально флажок этой опции (только при мультивыборе)
  
 
Необязательные параметры конструктора передаются в объекте <tt>params</tt>:
 
Необязательные параметры конструктора передаются в объекте <tt>params</tt>:
  
 
; multipleDelimiter: Чтобы включить мультивыбор, передайте сюда разделитель (например ',' или ';'), который не может входить в выбираемые значения. Также они не могут включать пробелы в начале и конце. Значение поля ввода будет установлено равным значениям всех выбранных элементов, соединённым через данный разделитель и один пробел (например «a, b»).
 
; multipleDelimiter: Чтобы включить мультивыбор, передайте сюда разделитель (например ',' или ';'), который не может входить в выбираемые значения. Также они не могут включать пробелы в начале и конце. Значение поля ввода будет установлено равным значениям всех выбранных элементов, соединённым через данный разделитель и один пробел (например «a, b»).
; onChangeListener(hint, index): Функция, которая будет вызвана при изменении значения через данный автокомплит. <tt>index</tt> — номер элемента, выделение которого изменилось. Её нужно использовать вместо обычного события «onchange» на поле ввода.
+
; multipleListener(hint, index, item): Для «мультивыбора с побочным эффектом» — когда поле ввода хочется использовать только для выбора значений в подсказке, а не для перечисления выбранных значений — можно передать в этот параметр callback, который будет реагировать на клики по элементам и где-то сохранять их статус. <tt>index</tt> — номер элемента, <tt>item = [ name, value, disabled, checked ]</tt>. Если задан multipleDelimiter и если callback вернёт true, то кроме вызова multipleListener всё-таки будет также затронуто и значение в поле ввода.
 +
: Также в этом режиме обретает смысл указание изначальной отмеченности флажков элементов при загрузке списка: <tt>hint.replaceItems([ [ name, value, disabled[, checked] ], ... ], more)</tt>.
 +
; onChangeListener(hint, index, item): Функция, которая будет вызвана при изменении значения через данный автокомплит. <tt>index</tt> — номер элемента, выделение которого изменилось. Её нужно использовать вместо обычного события «onchange» на поле ввода.
 
; maxHeight: Максимальная высота выпадающего списка в пикселах.
 
; maxHeight: Максимальная высота выпадающего списка в пикселах.
; emptyText: Текст, который нужно показать, если dataLoader вернёт пустой массив. По умолчанию «No items found». Если false, то при отсутствии элементов подсказка будет скрыта.
+
; emptyText: Текст (HTML-код), который нужно показать, если dataLoader вернёт пустой массив. Если пуст или false (по умолчанию), то при отсутствии элементов подсказка будет скрыта.
; allowHTML: Если true, то в названиях опций будет разрешён HTML-код.
+
; prompt: HTML-код «пояснения», показываемого перед ''непустым'' списком опций. По умолчанию — не задан.
 
; delay: Если установить в ненулевое целочисленное значение, то подсказки будут подгружаться с сервера не чаще, чем раз в delay миллисекунд. По умолчанию 300.
 
; delay: Если установить в ненулевое целочисленное значение, то подсказки будут подгружаться с сервера не чаще, чем раз в delay миллисекунд. По умолчанию 300.
 +
; moreMarker: Если выведенный список подсказок ограничен, но пользователю хочется всё-таки иметь возможность просмотреть их все без ввода дополнительных символов, вы можете добавить в список элемент со специальным значением, равным moreMarker (по умолчанию <tt><nowiki>"#MORE"</nowiki></tt>) в конце списка, обработать параметр more в dataLoader’е (см. выше) и подгрузить дополнительные значения в список.
 +
; persist: Если true, то список подсказок никогда не скрывается. Это можно использовать для создания интерактивных полей ввода, похожих на обычные мультиселекты (см. пример ниже).
 +
; className: Имя CSS-класса для списка подсказок. По умолчанию «hintLayer».
  
 
Если в какой-то момент объект ''SimpleAutocomplete'' вам станет более не нужен, его можно уничтожить:
 
Если в какой-то момент объект ''SimpleAutocomplete'' вам станет более не нужен, его можно уничтожить:
Строка 40: Строка 55:
  
 
<html>
 
<html>
Обычная подсказка: <input type="text" id="z" name="z" value="" /> Мультивыбор: <input type="text" id="x" name="x" value="" />
+
<p>Обычная подсказка: <input type="text" id="z" name="z" value="" /></p>
 +
<p>Мультивыбор с пояснением: <input type="text" id="x" name="x" value="" /></p>
 +
<p>Мультивыбор с побочным эффектом: <input type="text" id="y" name="y" value="" /></p>
 +
<p>Постоянно видимый мультивыбор:</p>
 +
<div class="wrapPersist">
 +
<input class="inputPersist" type="text" id="ms" value="" size="40" />
 +
</div>
 +
<div style="clear: both"></div>
 
<link rel="stylesheet" type="text/css" href="http://svn.yourcmc.ru/viewvc.py/vitaphoto/js/hinter.css?view=co" />
 
<link rel="stylesheet" type="text/css" href="http://svn.yourcmc.ru/viewvc.py/vitaphoto/js/hinter.css?view=co" />
 +
<style>
 +
.wrapPersist {
 +
    border-radius: 5px;
 +
    border: 1px solid rgb(82, 168, 236);
 +
    float: left;
 +
    -webkit-box-shadow: inset 0 1px 5px rgba(82, 168, 236, 0.6);
 +
    -moz-box-shadow: inset 0 1px 5px rgba(82, 168, 236, 0.6);
 +
    box-shadow: inset 0 1px 5px rgba(82, 168, 236, 0.6);
 +
}
 +
.wrapPersist .inputPersist {
 +
    margin: 5px;
 +
    border-width: 0 0 1px 0;
 +
    border-bottom-style: solid;
 +
    border-bottom-color: rgb(82, 168, 236);
 +
}
 +
.wrapPersist .hintActiveItem {
 +
    background: #7db9e8; /* Old browsers */
 +
    background: -moz-linear-gradient(top, #7db9e8 0%, #2989d8 83%, #7db9e8 100%); /* FF3.6+ */
 +
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7db9e8), color-stop(83%,#2989d8), color-stop(100%,#7db9e8)); /* Chrome,Safari4+ */
 +
    background: -webkit-linear-gradient(top, #7db9e8 0%,#2989d8 83%,#7db9e8 100%); /* Chrome10+,Safari5.1+ */
 +
    background: -o-linear-gradient(top, #7db9e8 0%,#2989d8 83%,#7db9e8 100%); /* Opera 11.10+ */
 +
    background: -ms-linear-gradient(top, #7db9e8 0%,#2989d8 83%,#7db9e8 100%); /* IE10+ */
 +
    background: linear-gradient(to bottom, #7db9e8 0%,#2989d8 83%,#7db9e8 100%); /* W3C */
 +
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7db9e8', endColorstr='#7db9e8',GradientType=0 ); /* IE6-9 */
 +
}
 +
.email { color: gray; }
 +
.wrapPersist .hintActiveItem .email { color: #e0e0e0; }
 +
.hintPersist {
 +
    height: 200px;
 +
    font-size: 85%;
 +
    overflow-y: scroll;
 +
}
 +
</style>
 
<script language="JavaScript" src="http://svn.yourcmc.ru/viewvc.py/vitaphoto/js/hinter.js?view=co"></script>
 
<script language="JavaScript" src="http://svn.yourcmc.ru/viewvc.py/vitaphoto/js/hinter.js?view=co"></script>
 
<script language="JavaScript">
 
<script language="JavaScript">
 +
<!--
 
function cb(h, v, m) {
 
function cb(h, v, m) {
     h.replaceItems([[ 'Вася Пупкин', 'Вася' ], [ 'Миша Метёлкин', 'Миша' ]], m);
+
     h.replaceItems([[ 'Вася Пупкин', 'Вася' ], [ 'Миша Метёлкин', 'Миша' ], [ 'НекроПедоЗоофил', 'x', 1 ] ], m);
 
}
 
}
function cb2(h, v, m) {
+
var sel = {};
     h.replaceItems([[ 'Вася Пупкин', 'Вася' ], [ 'Миша Метёлкин', 'Миша' ]], m);
+
function cb2(h, v) {
     var s = document.createElement('i');
+
     var i = [];
     s.style.color = 'gray';
+
    // Отключим Васю, когда Миша отмечен
     s.innerHTML = 'Можно задать предложение ко вводу';
+
    i.push([ 'Вася Пупкин'+(sel[1] ? ' выключен' : ''), 'Вася', sel[1], sel[0] ]);
    h.hintLayer.firstChild ? h.hintLayer.insertBefore(s, h.hintLayer.firstChild) : h.hintLayer.appendChild(s);
+
    i.push([ 'Миша Метёлкин', 'Миша', false, sel[1] ]);
 +
     h.replaceItems(i);
 +
}
 +
function clcb(h, i, item) {
 +
     sel[i] = item[3];
 +
     if (i == 1)
 +
        cb2(h, h.input.value);
 
}
 
}
new SimpleAutocomplete('x', cb2, { multipleDelimiter: ',' });
 
 
new SimpleAutocomplete('z', cb);
 
new SimpleAutocomplete('z', cb);
 +
new SimpleAutocomplete('x', cb, { multipleDelimiter: ',', prompt: 'Выберите дядек' });
 +
new SimpleAutocomplete('y', cb2, { multipleListener: clcb });
 +
 +
var users = [
 +
    [ 'vasya@oymorozmoroz.ru', 'Вася Пупкин' ],
 +
    [ 'misha@oymorozmoroz.ru', 'Миша Метёлкин' ],
 +
    [ 'alisa@oymorozmoroz.ru', 'Алиса Амосова' ],
 +
    [ 'zoya@oymorozmoroz.ru', 'Зоя Зотова' ],
 +
    [ 'pavel@oymorozmoroz.ru', 'Паша Косолапов' ]
 +
];
 +
var sel3 = { 'vasya@oymorozmoroz.ru': 1 };
 +
function cb3(h, v)
 +
{
 +
    var items = [];
 +
    for (var i = 0; i < users.length; i++)
 +
    {
 +
        if (!sel3[users[i][0]]) if (v.length) if (users[i][0].toLowerCase().indexOf(v.toLowerCase()) >= 0 ||
 +
            users[i][1].toLowerCase().indexOf(v.toLowerCase()) >= 0)
 +
        {
 +
            items.push([ users[i][1]+'<div class="email">'+users[i][0]+'</div>', users[i][0], false, sel3[users[i][0]] ]);
 +
        }
 +
    }
 +
    for (var i = 0; i < users.length; i++)
 +
    {
 +
        if (sel3[users[i][0]])
 +
        {
 +
            items.push([ users[i][1]+'<div class="email">'+users[i][0]+'</div>', users[i][0], false, sel3[users[i][0]] ]);
 +
        }
 +
    }
 +
    h.replaceItems(items);
 +
}
 +
function clcb3(h, i, item)
 +
{
 +
    sel3[item[1]] = item[3];
 +
}
 +
new SimpleAutocomplete('ms', cb3, {
 +
    multipleListener: clcb3,
 +
    persist: true,
 +
    className: 'hintPersist',
 +
    prompt: '<center style="color: gray">начните вводить имя пользователя</center>',
 +
    emptyText: '<center style="color: gray">пользователи не выбраны<br /><i>начните вводить имя пользователя</i></center>'
 +
});
 +
-->
 
</script>
 
</script>
 
</html>
 
</html>
 
== FIXME ==
 
 
* В Firefox слой подсказки не уменьшается меньше минимальной высоты скроллбара из установленного стиля. То есть, скроллбар виден всегда, даже если там только 1 элемент, и бывает так, что элемент один, а под ним пустое место.
 

Текущая версия на 13:12, 21 сентября 2017

Простое автодополнение (autocomplete) в текстовых полях ввода. Поддерживает мультивыбор и управление с клавиатуры (вниз, вверх, enter = выбор).

  • Исходники: hinter.js, hinter.css.
  • Минимизированный JS: hinter.min.js
  • Последнее обновление: 2014-09-04.
  • Лицензия: Mozilla Public License версии 2.0 или более новой.
    В двух словах — «строгий файловый копилефт». Любой отдельный файл, включающий MPL-лицензированные куски кода, должен быть лицензирован под MPL2.0+, GPL2.0+, LGPL2.1+ или AGPL3.0+.

Использование

Сначала включите на страницу hinter.js и hinter.css.

Для создания экземпляра SimpleAutocomplete используйте следующий JS-код:

var hint = new SimpleAutocomplete(input, dataLoader, params);

Обязательные параметры конструктора:

input
Поле ввода, в которое будем подсказывать, либо DOM-объект, либо его ID. ID, кстати, всегда необходимо.
dataLoader(hint, value, more)
Функция, которая должна загрузить опции для подсказки и вызвать hint.replaceItems([ [ name, value ], [ name, value[, disabled[, checked]] ], ... ], more).
  • hint — объект автокомплита, на котором и надо вызывать replaceItems.
  • value — введённая пользователем строка, на основе которой надо предоставлять подсказки.
  • more — при использовании moreMarker «страница» подсказок, которую нужно загрузить (0 = первая страница).
Параметры элементов: [ name, value[, disabled[, checked]] ]
  • name — Название
  • value — Значение (которое будет подставлено в поле ввода)
  • disabled — «Выключена» ли эта опция — если да, то её будет невозможно выбрать
  • checked — Отмечен ли изначально флажок этой опции (только при мультивыборе)

Необязательные параметры конструктора передаются в объекте params:

multipleDelimiter
Чтобы включить мультивыбор, передайте сюда разделитель (например ',' или ';'), который не может входить в выбираемые значения. Также они не могут включать пробелы в начале и конце. Значение поля ввода будет установлено равным значениям всех выбранных элементов, соединённым через данный разделитель и один пробел (например «a, b»).
multipleListener(hint, index, item)
Для «мультивыбора с побочным эффектом» — когда поле ввода хочется использовать только для выбора значений в подсказке, а не для перечисления выбранных значений — можно передать в этот параметр callback, который будет реагировать на клики по элементам и где-то сохранять их статус. index — номер элемента, item = [ name, value, disabled, checked ]. Если задан multipleDelimiter и если callback вернёт true, то кроме вызова multipleListener всё-таки будет также затронуто и значение в поле ввода.
Также в этом режиме обретает смысл указание изначальной отмеченности флажков элементов при загрузке списка: hint.replaceItems([ [ name, value, disabled[, checked] ], ... ], more).
onChangeListener(hint, index, item)
Функция, которая будет вызвана при изменении значения через данный автокомплит. index — номер элемента, выделение которого изменилось. Её нужно использовать вместо обычного события «onchange» на поле ввода.
maxHeight
Максимальная высота выпадающего списка в пикселах.
emptyText
Текст (HTML-код), который нужно показать, если dataLoader вернёт пустой массив. Если пуст или false (по умолчанию), то при отсутствии элементов подсказка будет скрыта.
prompt
HTML-код «пояснения», показываемого перед непустым списком опций. По умолчанию — не задан.
delay
Если установить в ненулевое целочисленное значение, то подсказки будут подгружаться с сервера не чаще, чем раз в delay миллисекунд. По умолчанию 300.
moreMarker
Если выведенный список подсказок ограничен, но пользователю хочется всё-таки иметь возможность просмотреть их все без ввода дополнительных символов, вы можете добавить в список элемент со специальным значением, равным moreMarker (по умолчанию "#MORE") в конце списка, обработать параметр more в dataLoader’е (см. выше) и подгрузить дополнительные значения в список.
persist
Если true, то список подсказок никогда не скрывается. Это можно использовать для создания интерактивных полей ввода, похожих на обычные мультиселекты (см. пример ниже).
className
Имя CSS-класса для списка подсказок. По умолчанию «hintLayer».

Если в какой-то момент объект SimpleAutocomplete вам станет более не нужен, его можно уничтожить:

hint.remove();
hint = null;

Демонстрация

Обычная подсказка:

Мультивыбор с пояснением:

Мультивыбор с побочным эффектом:

Постоянно видимый мультивыбор: