середу, 24 березня 2010 р.

JavaScript и выпадающие списки (тег SELECT)

В языке HTML есть такой тег – SELECTSELECT состоит из элементов OPTION, которые представляют собой элементы списка. Сами элементы OPTION состоят из текстовой метки заключенной между тегами option и атрибута value в котором содержится значение соответствующее текстовой метке. Текстовая метка видна пользователю в списке, тогда как значение value не отображается на экране, а передается на сервер при отправке формы (на сервер передаются только value-значения выделенных элементов списка). Таким образом, для изменения элемента SELECT, мы должны воздействовать на элементы OPTION. Ниже указан пример кода такого элемента.

Вот как будет выглядеть фрагмент html-кода на страничке

Как же взаимодействовать с SELECT из Javascript?

В DOM (Document Object Model / объектная модель документа) есть такой интересный метод getElementById объекта document. Вот с его помощью мы и будем обращаться к элементам списка. Смотрим ниже код вызова такого метода в JavaScript:

var objSel = document.getElementById("mySelectId");

В случае, если список находится внутри формы, то к нему можно обратиться и через форму:

var objSel = document.myForm.mySelect;

где, myForm имя формы заданное через атрибут name в теге FORM, а mySelect имя элемента формы, заданное через атрибут name в теге SELECT.

Как добавить новый элемент в список SELECT?

Все HTML элементы OPTION доступны в javascript-скрипте через свойство options объекта Select, которое является коллекцией элементов (т.е. массивом) элементов Option:

var objSel = document.getElementById("mySelect");
//Создаем новый объект Option и заносим его в коллекцию options
objSel.options[0] = new Option("1-ая строка списка", "str0");
objSel.options[1] = new Option("2-ая строка списка", "str1");
objSel.options[2] = new Option("3-ая строка списка", "str2");

Если нужно добавить элемент в конец списка, то удобней это сделать следующим образом:

objSel.options[objSel.options.length] = new Option("текст", "значение");

Свойство length объекта options содержит количество элементов в списке. Данное свойство доступно как для чтения, так и для записи. Если установить свойству length значение больше чем текущее количество элементов, то в список будут добавлены пустые элементы. Если же установленное значение меньше текущего количества элементов списка, то список будет усечен до указанного количества элементов (лишние элементы будут удалены). Таким образом, добавить новый элемент в список можно и так (допустим у нас есть пустой список, добавим первый элемент):

objSel.options.length=1; //добавляем в конец списка пустой элемент
objSel.options[0].text = "1-ая строка списка";
objSel.options[0].value = "str0";

Вернемся к функции-конструктору Option(). Помимо указания текста и значения можно указать является ли элемент выделенным по умолчанию (defaultSelected), т.е. будет ли элемент выделенным при сбросе формы методом reset() и является ли элемент выделенным в данный момент (selected). Полный синтаксис функции конструктора объекта Option имеет следующий вид:

var newOpt = new Option("text", "value", isDefaultSelected, isSelected);

где первые два аргумента – это строки, а третий и червертый булевы аргументы и принимают значения true или false.

До сих пор для добавления элемента мы использовали BOM (Browser Object Model / объектная модель браузера), однако лучше, во всех отношениях, использовать методы DOM (Document Object Model / объектная модель документа), и реализовывать добавление элемента так:

function addOption (oListbox, text, value, isDefaultSelected, isSelected)
{
  var oOption = document.createElement("option");
  oOption.appendChild(document.createTextNode(text));
  oOption.setAttribute("value", value);

  if (isDefaultSelected) oOption.defaultSelected = true;
  else if (isSelected) oOption.selected = true;

  oListbox.appendChild(oOption);
}

Пример использования:

var objSel = document.getElementById("mySelect");
addOption(objSel, "текст", "значение", true);

Некоторые особенности браузера IE : В IE 5+ исключена (ввиду нестабильной работы) возможность добавления элемента списка через new Option(), когда сам список SELECT находится в одном документе (окне, фрейме), а элементы добавляются из другого документа (окна, фрейма), например, если SELECT в родительском окне, а добавить элементы нужно из дочернего окна, открытого через window.open(). Используя DOM-методы вы сможете обойти данную проблему.

Доступ к элементам списка

var text  = objSel.options[2].text;
var value = objSel.options[2].value;

Элементы списка в массиве options индексируются с нуля, поэтому первый элемент списка имеет индекс 0:

  • objSel.options[0] – первый элемент списка
  • objSel.options[objSel.options.length-1] – последний элемент списка

Изменение элемента списка

objSel.options[1].text = "Новый текст";
objSel.options[1].value = "новое значение";
//полная замена элемента на новый
objSel.options[2] = new Option("Новый текст", "новое значение");

Как узнать какой элемент выбран и как выбрать нужный элемент?

У объекта элемента SELECT существует свойство selectedIndex, которое содержит индекс выделенного элемента, или -1 если нет выделенных элементов.

if ( objSel.selectedIndex != -1)
{
  //Если есть выбранный элемент, отобразить его значение (свойство value)
  alert(objSel.options[objSel.selectedIndex].value);
}

Следует отметить, что возможен выбор нескольких значений в списке, для этого нужно указать свойство multiple в теге SELECT и указать количество видимых без прокрутки списка элементов через атрибут size (т.е. установить высоту списка измеряемую в видимых элементах), например, разметка <select size=”3″ multiple>…</select> создаст список высотой в 3 элемента, в котором разрешено выбирать несколько элементов сразу. Если вы указываете size больше 1, то список перестает быть выпадающим, а изменяет вид на обычный блок с полосой прокрутки (она доступка при необходимоти). Свойство size можно указывать и без multiple.

В случае когда доступен множественный выбор элементов, данное свойство содержит индекс первого выделенного в списке элемента (т.е. того элемента который в списке находиться выше). Чтобы в данном случае найти все выделенные элементы нужно перебрать в цикле все элементы массива options и проверить их свойство selected, которое равно true у выделенных элементов:

function getSelectedIndexes (oListbox)
{
  var arrIndexes = new Array;
  for (var i=0; i < oListbox.options.length; i++)
  {
      if (oListbox.options[i].selected) arrIndexes.push(i);
  }
  return arrIndexes;
};

Функция getSelectedIndexes() принимает в качестве аргумента объект списка и возвращает массив индексов выделенных элементов.

Пример использования (отображение индексов выделеных элементов):

var objSel = document.getElementById("mySelect");
alert ( getSelectedIndexes(objSel) );

Описанные свойства selectedIndex и selected являются свойствами как для чтения так и для записи, поэтому присваивая им значения можно выделять нужные элементы.

//выбрать (выделить) второй элемент списка
objSel.selectedIndex = 1;
//или так
objSel.options[1].selected=true;

Для выбора нескольких элементов (при установленном свойстве multiple) нужно установить свойство selected=true для всех нужных элементов:

//выбрать (выделить) 1 и 3 элементы списка
objSel.options[0].selected=true;
objSel.options[2].selected=true;

При динамическом заполнении списка через скрипт и последующей установке выделенного пункта через свойство selectedIndex или selected некоторые браузеры могут вести себя по разному. Так в браузере Opera проявляется такое поведение (баг) в добавлении пустых элементов в список, доступ к которым из скрипта невозможен (скрипт их не видит, зато пользователь видит и может их выбрать). Эти пустые лже-элементы списка появляются после установки свойства selectedIndex или selected. Для обхода этой ошибки в Opera используйте установку этих свойств через setTimeout с задержкой в 1мс:

var objSel = document.getElementById("mySelect");
//Динамически создаем элементы списка
objSel.options[0] = new Option("1-ая строка списка", "str0");
objSel.options[1] = new Option("2-ая строка списка", "str1");
//Выделяем второй элемент списка
setTimeout( function(){objSel.options[1].selected=true;}, 1 );

Удаление n-го элемента списка

//удалить элемент списка с индексом 1 (второй элемент списка
objSel.options[1] = null;)

Или используя DOM метод remove:

oListbox.remove(0); //удалить первый элемент списка

Очистка списка SELECT (удаление всех элементов из списка)?

Для этого можно установить свойство length в ноль:

objSel.options.length = 0;

Либо вызвать DOM метод remove для каждого элемента списка:

function clearSelect(oListbox)
{
  for (var i=oListbox.options.length-1; i >= 0; i--)
  {
      oListbox.remove(i);
  }
};

Перемещение элемента списка вверх или вниз

function shiftUpOption (oListbox, iIndex)
{
  if (iIndex > 0)
  {
    var oOption = oListbox.options[iIndex];
    var oPrevOption = oListbox.options[iIndex-1];
    oListbox.insertBefore(oOption, oPrevOption);
  }
};

function shiftDownOption (oListbox, iIndex)
{
  if (iIndex < oListbox.options.length - 1)
  {
    var oOption = oListbox.options[iIndex];
    var oNextOption = oListbox.options[iIndex+1];
    oListbox.insertBefore(oNextOption, oOption);
  }
};

Пример:

var objSel = document.getElementById("mySelect");
 //переместить второй элемент списка (с индектом 1) на первую позицию (с индексом 0)
shiftDownOption (objSel, 1);

Немає коментарів:

Дописати коментар

HyperComments for Blogger

comments powered by HyperComments