Виджет Tabs
171Веб-программирование --- jQuery UI --- Виджет Tabs
Создание виджета Tabs
Для создания виджета Tabs используется метод tabs(). Как и в случае виджета Accordion, для применения этого метода потребуется отдельная структура HTML-элементов. Пример такой структуры приведен ниже:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery UI</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.ui/1.10.3/jquery-ui.min.js"></script>
<link rel="stylesheet" href="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.10.3/themes/sunny/jquery-ui.css">
<script type="text/javascript">
$(function() {
$('#tabs').tabs();
$('button').button();
});
</script>
</head>
<body>
<h1>Цветочный магазин</h1>
<form method="post" action="phphandler.php">
<div id="tabs">
<ul>
<li><a href="#tab1">Ряд 1</a>
<li><a href="#tab2">Ряд 2</a>
<li><a href="#tab3">Ряд 3</a>
</ul>
<div id="tab1">
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/astor.png"/>
<label for="astor">Астра:</label>
<input name="astor" value="0" required>
</div>
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/daffodil.png"/>
<label for="daffodil">Нарцисс:</label>
<input name="daffodil" value="0" required >
</div>
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/rose.png"/>
<label for="rose">Роза:</label>
<input name="rose" value="0" required>
</div>
</div>
<div id="tab2">
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/peony.png"/>
<label for="peony">Пион:</label>
<input name="peony" value="0" required>
</div>
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/primula.png"/>
<label for="primula">Примула:</label>
<input name="primula" value="0" required>
</div>
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/snowdrop.png"/>
<label for="snowdrop">Подснежник:</label>
<input name="snowdrop" value="0" required>
</div>
</div>
<div id="tab3">
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/carnation.png"/>
<label for="carnation">Гвоздика:</label>
<input name="carnation" value="0" required>
</div>
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/lily.png"/>
<label for="lily">Лилия:</label>
<input name="lily" value="0" required>
</div>
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/orchid.png"/>
<label for="orchid">Орхидея:</label>
<input name="orchid" value="0" required>
</div>
</div>
</div>
<div id="buttonDiv"><button type="submit">Заказать</button></div>
</form>
</body>
<style>
h1 {
min-width: 70px; border: thick double black; margin-left: auto;
margin-right: auto; text-align: center; font-size: x-large; padding: .5em;
color: darkgreen; background-image: url("http://professorweb.ru/downloads/jquery/border.png");
background-size: contain; margin-top: 0;
}
.dcell {display: table-cell; padding: 10px;}
.dcell > * {vertical-align: middle}
input {width: 2em; text-align: right; border: thin solid black; padding: 2px;}
label {width: 6em; padding-left: .5em; display: inline-block;}
#buttonDiv {text-align: center; margin-top:12px;}
button {padding: 12px;}
#oblock {display: block; margin-left: auto; margin-right: auto; min-width: 700px; }
</style>
</html>
Элемент, к которому вы собираетесь применить метод tabs(), должен содержать элементы двух типов. Элементы первого типа — это элементы содержимого, т.е. элементы, содержимое которых должно отображаться в отдельных вкладках. Ко второму типу относятся структурные элементы, содержащие информацию, которая используется для создания структуры вкладок.
В качестве контейнеров содержимого используются элементы div. В данном примере используются три элемента div, каждый из которых будет содержать один ряд элементов с информацией о цветочной продукции, аналогично тому, как это делалось во всех предыдущих примерах:
<div id="tab1">...</div>
<div id="tab2">...</div>
<div id="tab3">...</div>
Очень важно, чтобы каждый элемент содержимого был снабжен идентификатором (атрибутом id) и виджет мог находить элемент, который требуется отобразить. Для создания необходимой структуры используются элементы <li>, каждый из которых должен содержать элемент <a>:
<ul>
<li><a href="#tab1">Ряд 1</a>
<li><a href="#tab2">Ряд 2</a>
<li><a href="#tab3">Ряд 3</a>
</ul>
Количество элементов <li> определяет количество вкладок. Содержимое элемента <a> используется в качестве ярлыка вкладки, а атрибут href указывает, к какому именно элементу содержимого (вкладке) относится данный ярлык.
Каким образом использованная в примере структура HTML-элементов отображается в окне браузера, показано на рисунке:
Вкладки являются хорошо известной метафорой интерфейса пользователя. Щелчок на вкладке приводит к отображению соответствующего элемента содержимого. Как и виджет Accordion с его структурой панелей, напоминающей клавиатуру аккордеона и раздвигающейся подобно мехам гармошки, виджет Tabs обеспечивает возможность относительно компактного представления больших объемов содержимого, что позволяет сконцентрировать внимание на наиболее важной информации.
Это означает, что необходимо тщательно продумывать, каким образом вкладки и их содержимое должны соотноситься между собой. Ваша задача состоит в том, чтобы путем группирования информации избавить пользователя от необходимости часто переходить с одной вкладки на другую для получения доступа к нужным данным. Как и в случае любого пользовательского интерфейса, это требует глубокого понимания задач, решаемых пользователем, и того, как организован весь его рабочий процесс (а не только ваша система).
Получение содержимого вкладок с помощью Ajax
Одной из замечательных особенностей вкладок jQuery UI является возможность получения содержимого с помощью Ajax. Для этого достаточно указать URL-адрес источника в атрибуте href соответствующего элемента. Чтобы продемонстрировать, как это работает, я создал документ под названием tabflowers.html, содержимое которого представлено в примере ниже:
<!-- Содержимое файла tabflowers.html -->
<div>
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/astor.png"/>
<label for="astor">Астра:</label>
<input name="astor" value="0" required>
</div>
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/daffodil.png"/>
<label for="daffodil">Нарцисс:</label>
<input name="daffodil" value="0" required >
</div>
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/rose.png"/>
<label for="rose">Роза:</label>
<input name="rose" value="0" required>
</div>
</div>
<div>
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/peony.png"/>
<label for="peony">Пион:</label>
<input name="peony" value="0" required>
</div>
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/primula.png"/>
<label for="primula">Примула:</label>
<input name="primula" value="0" required>
</div>
<div class="dcell">
<img src="http://professorweb.ru/downloads/jquery/snowdrop.png"/>
<label for="snowdrop">Подснежник:</label>
<input name="snowdrop" value="0" required>
</div>
</div>
Чтобы не усложнять пример, я использую те же структуру и содержимое, что и в генерируемых элементах содержимого. Использование файла tabflowers.html в качестве содержимого вкладок показано в примере ниже:
<form method="post" action="phphandler.php">
<div id="tabs">
<ul>
<li><a href="tabflowers.html">Содержимое Ajax</a>
<li><a href="#tab1">Ряд 1</a>
<li><a href="#tab2">Ряд 2</a>
<li><a href="#tab3">Ряд 3</a>
</ul>
...
</form>
Вместо того чтобы использовать настройки метода tabs(), вы изменяете структуру элемента. В данном примере я добавил новую вкладку, назвав ее "Содержимое Ajax", и указал URL-адрес источника содержимого, которое должно быть загружено. Результат представлен на рисунке:
По умолчанию загружаться во вкладки с помощью Ajax могут только HTML-документы, однако, как будет показано в одном из следующих разделов, для этого пригодны также данные в формате JSON.
Настройка виджета Tabs
На первый взгляд, вкладки виджета Tabs могут показаться простой разновидностью панелей виджета Accordion, характеризующихся вертикальным расположением. Действительно, у этих виджетов есть общие характеристики, но для вкладок Tabs (далее просто вкладки) предусмотрено намного больше настраиваемых свойств и конфигурационных параметров.
Свойства, поддерживаемые виджетом Tabs, приведены в таблице ниже. Примеры их использования для настройки виджета описываются в следующих разделах:
Свойство | Описание |
---|---|
active | Позволяет получить или задать индекс активной вкладки |
collapsible | Если эта опция равна true, то пользователь не будет иметь возможности оставить невыбранными все вкладки. Значение по умолчанию — false, которое означает, что одна из вкладок всегда должна быть активна (открыта) |
disabled | Установка значения true или false означает соответственно отключение или включение функциональности вкладок. Если в качестве значения задан массив чисел, то они указывают индексы отключаемых вкладок |
event | Позволяет получить или задать событие, которое делает вкладку активной. По умолчанию таким событием является click, т.е. вкладка активизируется после выполнения на ней щелчка |
heightStyle | Определяет высоту вкладок. Возможные значения: auto (высота всех вкладок будет одинаковой и равной высоте самой высокой вкладки), content (высота вкладки определяется ее содержимым), fill (вкладки занимают все пространство своего родительского элемента по высоте) |
show и hide | Определяет эффекты, которые должны использоваться при анимации процессов открытия и закрытия вкладок. Значение по умолчанию — null, означающее, что эффекты не используются |
Методы, поддерживаемые виджетом jQuery UI Tabs, перечислены в таблице ниже. Использование наиболее полезных из них будет продемонстрировано в следующих разделах:
Метод | Описание |
---|---|
tabs("destroy") | Полностью удаляет функциональность виджета Tabs из базового HTML-элемента |
tabs("disable") | Приостанавливает работу всего виджета или отдельных вкладок |
tabs("enable") | Возобновляет работу ранее приостановленного виджета или отдельных вкладок |
tabs("option") | Позволяет изменить одну или несколько опций. Более подробное описание настройки конфигурационных параметров виджетов jQuery UI на примере виджета Button описывались ранее |
tabs("load") | Осуществляет принудительную загрузку содержимого вкладки |
tabs("refresh") | Заставляет явно обновить внешний вид вкладок (удобно при программном изменении вкладок, например при их добавлении или удалении). Этот метод не принимает аргументов |
tabs("widget") | Возвращает объект jQuery, представляющий виджет Tabs. Этот метод не принимает аргументов |
Отключение отдельных вкладок
Если опции disable присвоено логическое значение, то оно воздействует на виджет Tabs в целом. Однако имеется возможность включать и отключать отдельные вкладки, указывая их номера в виде целочисленного массива, как показано в примере ниже:
<!DOCTYPE html>
...
<script type="text/javascript">
$(function() {
$('#tabs').tabs({
beforeActivate: function(event, ui) {
$('input:checkbox').button("enable")
.filter('#cb' + (Number(ui.newTab.text().substring(3))-1))
.button("disable");
}
});
$('input:checkbox').button().click(function() {
var disabledPositions = [];
$('input:checked')
.each(function(index, elem) {
disabledPositions.push($(this).data("index"));
})
console.log(disabledPositions)
$('#tabs').tabs("option", "disabled", disabledPositions)
});
});
</script>
...
<div id="buttonDiv">
<label for="cb0">Вкладка 1</label>
<input type="checkbox" id="cb0" data-index=0 disabled>
<label for="cb1">Вкладка 2</label>
<input type="checkbox" id="cb1" data-index=1>
<label for="cb2">Вкладка 3</label>
<input type="checkbox" id="cb2" data-index=2>
</div>
...
Запустить пример
В этом документе мы создаем виджет Tabs со статическим содержимым и добавляем набор флажков, преобразуя их в кнопки-переключатели jQuery UI. Щелчок на кнопке приводит к включению или отключению соответствующей вкладки. Кроме того, мы используем событие select для отключения кнопки, когда соответствующая ей вкладка становится активной. Результат представлен на рисунке:
Изменение типа события, активизирующего вкладку
По умолчанию виджет Tabs реагирует на событие click. Это означает, что для активизации вкладки пользователь должен выполнить щелчок на ней. Опция event позволяет указать другое событие, наступление которого будет приводить к активизации вкладки. Чаще всего в этой роли выступают другие события мыши, как показано в примере ниже:
$(function() {
$('#tabs').tabs({
event: "mouseover"
});
});
Запустить пример
В этом примере указано событие mouseover, т.е. переключение вкладок в этом виджете будет осуществляться при наведении указателя мыши на ярлык соответствующей вкладки.
Я уже давал совет относительно умеренного использования описанного подхода в случае виджета Accordion, и сейчас также рекомендую поступать аналогичным образом. Внешне этот эффект кажется привлекательным, но он может раздражать пользователей, поскольку заставляет их постоянно следить за тем, чтобы указатель мыши случайно не оказался над ярлыком другой вкладки, что приведет к смене отображаемого содержимого.
Использование свертываемых вкладок
Используя опцию collapsible, можно создать своего рода гибрид вкладок виджета Tabs и панелей виджета Accordion, как показано в примере ниже:
$(function() {
$('#tabs').tabs({
collapsible: true
});
});
Если опция collapsible равна true, то щелчок на активной вкладке приводит к ее свертыванию, точно так же, как в случае панели виджета Accordion. Я привел пример использования этой опции лишь для полноты обсуждения, но сам никогда не использую ее в своих проектах, поскольку считаю, что этот эффект не относится к числу интуитивно понятных для пользователей и лишь создает помехи в работе.
Добавление и удаление вкладок
Для добавления и удаления вкладок программным путем нужно использовать возможности jQuery и вызвать метод refresh для обновления виджета Tabs. Это может быть полезным при обработке динамического содержимого или при генерации вкладок в ответ на пользовательский ввод. Ниже показан соответствующий пример:
<!DOCTYPE html>
...
<script type="text/javascript">
$(function() {
$('#tabs').tabs();
$('button').button().click(function(e) {
var tabsElem = $('#tabs');
if (this.id == "add") {
// Добавляем вкладку
$( "<li><a href='#tab1'>" + $('#tabLabel').val() +"</a></li>" )
.appendTo( "#tabs .ui-tabs-nav" );
tabsElem.tabs("refresh");
} else {
// Ищем активную вкладку и удаляем содержимое и вкладку
var tabIndex = tabsElem.tabs("option", "active");
tabsElem.find('li:eq(' + tabIndex + ')').css('display','none');
tabsElem.tabs("refresh");
}
})
});
</script>
</head>
<body>
<h1>Цветочный магазин</h1>
<div id="dc1" class="ui-widget">
<label for="tabLabel" style="width:130px">Имя вкладки: </label><input id="tabLabel" style="width:150px"/>
<button id="add">Добавить вкладку</button>
<button id="remove">Удалить активную вкладку</button>
</div>
<form method="post" action="phphandler.php">
<div id="tabs">
<ul>
<li><a href="#tab1">Ряд 1</a>
<li><a href="#tab2">Ряд 2</a>
<li><a href="#tab3">Ряд 3</a>
</ul>
...
</form>
Запустить пример
В этом примере добавлены элемент input и два элемента button, позволяющие добавлять новые вкладки и удалять существующие. Эти дополнения документа отображены на рисунке:
Когда на кнопке "Удалить активную вкладку" выполняется щелчок, мы получаем индекс активной вкладки с помощью опции active и удаляем соответствующий элемент <li> с помощью jQuery.