Научный консалтинг
Главная
Контакты
Номер телефона
Как мы работаем
Гарантии
Условия
Цены

Редактируемый раскрывающийся список select для html (аналог)

Раскрывающиеся списки на страницах html бывают нужны, в частности, когда необходимо на форме (отправляющей данные на сервер) выбрать одно из заданных значений. Однако, иногда бывает нужно отредактировать выбранное значение. Или - вовсе указать какое-то свое. Стандартный тег select тега form это сделать не позволяет. Ибо редактировать предлагаемые значения в нем невозможно. Как быть? Как сделать раскрывающийся список, чтобы можно было его редактировать?

Существуют реализации раскрывающегося списка с возможностью редактирования вводимых параметров на jQuery. Шде-то в сети нам встречалась соответствующая разработка, вот только ссылка, к сожалению, уже потерялась. Но, наверное, при помощи Яндекс или Google ее вполне можно будет найти.

Вот, к примеру, в окружении VBA для Microsoft Excel и Word имеется возможность создавать как редактируемые, так и нередактируемые списки. А вот в html, насколько нам известно, представлены лишь нередактируемые их варианты.

Расширяем возможности списков

Надо сказать сразу, что без помощи javascript (т.е. только средствами html и CSS) здесь не обойтись. Правда, все не настолько сложно. Базовая концепция такова:

  1. Моделируем список (тег select) при помощи блоков div. Т.е. вместо тегов option будут соответствующие теги div.
  2. Список должен раскрываться при наведении мыши и закрываться при отведении ее.
  3. Если мышь наведена на список, при нажатии ее кнопки на списке он поочередно должен то открываться, то раскрываться, если ни один из заданных элементов списка не выбран и если в основном поле ничего нет.
  4. Если в основном поле напечатан хотя бы один символ, то нажитие левой кнопки мыши не должно приводить к открытию/закрытию списка.
  5. Должна быть возможность ввода пользовательских значений в основное поле списка.

Вот такое вот техническое задание. Сразу приведем пример кода, где это реализовано. Вначале приводится обычный нередактируемый список select. Затем, немного ниже - его редактируемый аналог.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<title>РЕДАКТИРУЕМЫЙ раскрывающийся список (типа списка select)</title>

<meta http-equiv="Content-Type" content="text/html; charset=windows-1251"/>

<style type="text/css">
.s2{width: 100px; height: 20px; border: solid 1px; display: none}
div.s2:hover{background-color: darkblue; color: white; height: 20px; }
.s1{width: 100px; height: 20px; border: solid 1px;}
.s1:hover {background-color: darkblue; color: white}
</style>

</head>
<body>
<p>Это - обычный список select тега form:</p>

<form>
<select>
<option value=''></option>
<option value=''>Пункт 1</option> <option value=''>Пункт 2</option> <option value=''>Пункт 3</option> </select>
</form>

Вот он, обычный список select, в действии:

А ниже - редактируемый список, типа списка select для формы на странице html. Нажмите на пустой прямоугольник (можно несколько раз). Выберите один из пунктов - он появится в пустом поле.

Пункт 1
Пункт 2
Пункт 3

Кроме того, в пустом поле можно набрать какой-нибудь свой текст. После того, как будет введен хоть один символ, открыть/закрыть список путем кликания кнопки мыши уже не получится до тех пор, пока прямоугольник вновь не станет ПУСТЫМ:

<div id="s1all__" style="display: inline-block; border: solid 2px green;" onmouseleave ="close_('s2')">
<div contenteditable="true" id="s1" class="s1" style="" onclick="open_close('s2'); return(false)" onmouseover="open_('s2')"></div>
<div id="s1__" class="s2" onclick="funct(this.id)">Пункт 1</div>
<div id="s2__" class="s2" onclick="funct(this.id)">Пункт 2</div>
<div id="s3__" class="s2" onclick="funct(this.id)">Пункт 3</div>
</div>

<script type="text/javascript"><!--//<![CDATA[
// Скрипт, открывающий и закрывающий раскрывающийся раскрывающийся список (редактируемый select)
function funct(identif) {
// Вставка содержимого выбранного пункта раскрывающегося списка в верхний (первоначальный) пункт
document.getElementById('s1').textContent = document.getElementById(identif).textContent;
close_('s2');
}

function open_close(identif) {
// Раскрыть или закрыть раскрывающийся список, в зависимости от того, закрыт он или раскрыт
document.getElementById('s1').style.backgroundColor = "white";
document.getElementById('s1').style.color = "black";
if ((document.getElementById('s1').textContent == ""))
{for (var i = 0; i < document.getElementsByClassName(identif).length; i++) {
if (document.getElementsByClassName(identif)[i].style.display == "none")
{document.getElementsByClassName(identif)[i].style.display = "block";}
else {document.getElementsByClassName(identif)[i].style.display = "none";}
}}}

function open_(identif){// Раскрыть раскрывающийся список
for (var i = 0; i < document.getElementsByClassName(identif).length; i++)
{document.getElementsByClassName(identif)[i].style.display = "block";}
}

function close_(identif) {// Закрыть раскрывающийся список
for (var i = 0; i < document.getElementsByClassName(identif).length; i++)
{document.getElementsByClassName(identif)[i].style.display = "none";}}
//]]>-->
</script>
</body></html>

Обсуждение

Таким образом, разработанный нами список работает практически также, как стандартный select. Даже лучше, на наш взгляд. При этом он позволяет редактировать выбранные значения. Например, Вы выбрали значение "Пункт 2". Кликнув мышью в основном поле списка, можно изменить это значнеие на то, которое необходимо. Или же вообще стереть его, сделав основное поле пустым. В этом случае при кликах мышью на этом поле список будет поочередно - то открываться, то закрываться.

Возможность редактирования обеспечивается применением свойства contenteditable, установленного как true. Вот, кстати, интересный пример применения этого свойства, совсем неожиданный. Ведь оно, как правило, применяется для создания визуальных html редакторов (что и рекомендует W3C). А здесь - позволяет реализовать редактируемый список. Немного доработав код, можно также реализовать добавление элементов в список. Т.е. значения, введенные пользователем, будут сохраняться в списке заданных значений.

Кроме того, если в верхнее поле списка вводить достаточно длинную строку, содержащую пробел, то она частично выйдет из зеленого окна списка и будет перенесена на другую строчку. Следовательно, здесь тоже не мешало бы соответствующим образом оптимизировать список. Например, сделав его ширину динамически зависимой от длины контента. Однако, это уже другой вопрос.

Следующее усовершенствование могло бы касаться оптимизиции кода javascript. В самом деле, судя по строчкам HTML-кода, для каждого div назначается свой обработчик onclick. Т.е. сколько будет блоков div (соответственно, сколько пунктов списка), столько же будет и обработчиков. Вообще, подобный способ назначения обработчиков является, в некотором смысле, устаревшим. В том плане, что он требует прописывать их вызовы в КАЖДОЙ соответствующей строчке (т.е. для каждого div). Конечно, если это осуществляется сервером (например, при помощи РНР или С++), то это проще; там вся работа возлагается не на верстальщика, а на сервер. Но, в любом случае, в ситуации, когда список будет большим, этих самых обработчиков будет "навешано" немереное количество.

Поэтому целесообразно бы устанавливать обработчики динамически, в цикле. Например, при помощи чего-то типа

setAttribute("onclick", "f(x); return false;")

При этом верстальщику не потребуется в каждую строчку кода HTML в соответствующий div вписывать обработчик. Достаточно будет где-нибудь разместить небольшой код javascript, который, после загрузки страницы, и пропишет обработчики в нужные блоки (пункты списка - аналога select). Однако, повторимся, если страница формируется сервером, то, видимо, без особой разницы - как будут прописаны обработчики: то ли заранее, т.е. в HTML-коде в каждой соответствующей строчке, но зато не понадобится работа javascript. То ли они в HTML-коде изначально не будут прописываться, но будут назначаться в результате работы javascript. Здесь, строго гоовря, необходим научно обоснованный анализ скорости окончательной загрузки страницы и удобства для пользователя. И уже исходя из этого можно сделать вывод, какой подключение обработчиков применять: "устаревшее" или какое иное.

С уважением к Вам.

Вот что мы можем сделать для Вас:
Интересная и полезная
информация
Изменить размер шрифта:
?