Предположим, есть задача сделать форму фильтрации товаров на сайте примерно такого вида:
Сайт работает под управлением Umi.CMS, нужный каталог товаров создан, все свойства товаров заполнены. Нужно кроссбраузерно сверстать форму и заставить её работать. С последним трудностей не возникает, нужные для фильтрации инструменты в Umi присутствуют. Однако
верстка и программирование ползунков для выбора диапазона периодически доставляет немало хлопот.
Хорошая форма выбора диапазона должна удовлетворять следующим условиям:
1) Границы диапазона должны быть управляемыми со стороны администратора проекта. Цены растут, все меняется.
2) При пересечении ползунков в момент перетаскивания диапазон должен оставаться управляемым.
3) Ползунки должны взаимодействовать с текстовыми полями ввода значений.
В качестве подходящего инструмента для реализации анимации ползунков диапазона выбран Adobe Flash, который предоставляет отличную возможность нарисовать недостающие элементы интерфейса. А возможности ActionScript и особенно пакета
классов external позволяют сделать то, что нужно: заставить ползунки предсказуемо двигаться и организовать передачу данных для JavaScript и обратно в целях организации нормальной работы формы.
Итак, чтобы сделать работающую форму фильтрации на основе ценового диапазона, следует пройти следующие три шага:
1) Подготовка swf-файла с анимацией ползунков.
Интерфейс формы выбора ползунков будет состоять из следующих компонентов:
— Клипы ползунков: левый и правый. При подготовке клипов желательно учесть, чтобы при пересечении их на общем участке диапазона левый ползунок принимал форму правого и наоборот, что позволит сохранить целостность восприятия формы. Можно сделать два клипа для левого и правого ползунка с противоположными формами на разных кадрах, либо поэкспериментировать с отображением одного клипа.
— Клипы линии, на которой расположены ползунки: нижняя основная и верхняя, которая будет отображать выбранный диапазон.
— Текстовые поля, отображающие заданные в административной панели границы диапазона.
— Клип фона. Любой.
После создания и размещения всех необходимых компонентов, подготовим файл с классом ActionScript для организации его работы. Чтобы ползунки управляемо передвигались в пределах нужного диапазона, следует получить некоторые данные:
минимальная и максимальная границы диапазона, выбранные пользователем значения минимума и максимума (если пользователь ещё ничего не выбрал, они равны границам диапазона), статус выбора — как раз указывает на то, выбирал ли пользователь диапазон или ещё нет.
Эти данные позволяет получить пакет классов ActionScript external. Класс ExternalInterface позволяет зарегистрировать методы, необходимые для обмена данными между swf-файлом и JavaScript-кодом на странице формы. Например,
if (ExternalInterface.available) {
ExternalInterface.addCallback("getDiapasonData", getDiapasonData);
ExternalInterface.addCallback("setDiapasonValue", setDiapasonValue);
}
Здесь в случае доступности ExternalInterface регистрируются два метода:
getDiapasonData — отвечает за получение и первичную обработку данных, необходимых для правильной работы ползунков. Выполняется один раз после того, как Javascript сформирует нужные параметры для передачи в swf-файл.
private function getDiapasonData(begin_diapason:Number, next_diapason:Number, price_status:Number = 0, min_price:Number = 0, max_price:Number = 0):void {
// .. код пропущен, так как отклоняется от решения текущей задачи ..
// параметр price_status служит для указания, выбирал ли пользователь значения диапазона, или используются значения по умолчанию
// это не логическая переменная, так как возможно более двух вариантов статуса, что используется в других случаях
if (price_status > 0) {
// вычисление положения ползунков в зависимости от значений диапазона
var all_summ:Number = next_diapason - begin_diapason;
var start_relation:Number = min_price / all_summ;
var end_relation:Number = max_price / all_summ;
// 276 - значение длины линии для ползунков в пикселях в данном конкретном примере
var line_x:Number = (276 * (min_price - begin_diapason)) / (next_diapason - begin_diapason);
var line_x_width:Number = (276 * (max_price - begin_diapason)) / (next_diapason - begin_diapason) - line_x;
var next_x:Number = line_x + line_x_width;
// .. далее происходит назначение вычисленных значений ползункам и верхней линии диапазона
}
}
setDiapasonValue — отвечает за передачу конкретных значений диапазона из JavaScript-функции для дальнейшего использования. Выполняется при каждом заполнении текстовых значений диапазона в HTML-форме.
private function setDiapasonValue(temp_min_price:int, temp_max_price:int):void {
// минимальная граница диапазона должна быть действительно меньше максимальной
if(temp_min_price < temp_max_price) {
// вычисление позиции ползункцов по переданным значениям диапазона
var temp_relation:Number = (end_diapason - start_diapason) / 276;
var temp_x_start:int = 0;
if(temp_min_price < start_diapason) {
temp_min_price = start_diapason;
}
temp_x_start = (temp_min_price - start_diapason) / temp_relation;
var temp_x_end:int = 0;
if(temp_max_price > end_diapason) {
temp_max_price = end_diapason;
}
if(temp_max_price < start_diapason) {
temp_max_price = start_diapason;
}
temp_x_end = (temp_max_price - start_diapason) / temp_relation;
// .. далее происходит назначение вычисленных значений ползункам и верхней линии диапазона
}
}
Переданные из функции JavaScript параметры становятся полноценными параметрами методов ActionScript и пригодны для программирования анимации ползунков.
Для выполнения обратной передачи значений из ActionScript в функции JavaScript используется метод call класса ExternalInterface, которому передается название нужной функции JavaScript с параметрами.
Например, следующие методы служат для передачи значений каждого ползунка из ActionScript соответствующим функциям JavaScript. Происходит вычисление цены в зависимости от положения ползунка с округлением до 100 рублей:
private function setStartDiapason():void {
var relation:Number = line_mc.x / 276;
var current_diapason:Number = Math.round((start_diapason + Math.round((end_diapason - start_diapason) * relation)) / 100) * 100;
ExternalInterface.call("setStartDiapason", current_diapason);
}
private function setEndDiapason():void {
var relation:Number = (line_mc.x + line_mc.width) / 276;
var current_diapason:Number = Math.round((start_diapason + Math.round((end_diapason - start_diapason) * relation)) / 100) * 100;
ExternalInterface.call("setEndDiapason", current_diapason);
}
2) Подготовка параметров для формы диапазона в административной панели Umi.CMS и настройка XSLT-шаблонов для них.
Для обеспечения всего функционала формы ценового диапазона нужно обеспечить администратора сайта возможностью самостоятельно задавать его границы: минимальную и максимальную цену.
Цены со временем меняются, а указание широких границ диапазона ухудшает точность вычислений при осуществлении анимации. Тем более, что для определённых групп товаров диапазон цен вполне вычисляем.
Для хранения пользовательских свойств в Umi.CMS предлагается создание страниц особого типа данных, например, «Общие параметры сайта». На этой странице можно создать группу свойств «Диапазон цен», а в ней разместить два свойства числового типа:
Минимальный уровень цен (minimalnyj_uroven_cen) и Максимальный уровень цен (maksimalnyj_uroven_cen). Запоминаем сгенерированные системой идентификаторы этих свойств либо меняем их на более удобные для чтения и тоже запоминаем.
После этого в структурном дереве страниц создаем или находим страницу «Общие параметры сайта» и указываем значения этих свойств.
В XSLT-шаблоне выбираем значения ценового диапазона и сохраняем в переменных:
<xsl:variable name="minPriceValue" select="$commonParams//property[@name = 'minimalnyj_uroven_cen']/value" />
<xsl:variable name="maxPriceValue" select="$commonParams//property[@name = 'maksimalnyj_uroven_cen']/value" />
Здесь commonParams — это переменная, хранящая информацию о свойствах страницы «Общие параметры сайта».
Прямо в XSLT-шаблоне размещаем следующий код JavaScript
<script type="text/javascript">
// эта конструкция позволяет получить числовое значение, даже если администратор забыл его указать
min_price_product = parseFloat('<xsl:value-of select="$minPriceValue" />');
max_price_product = parseFloat('<xsl:value-of select="$maxPriceValue" />') + 100;
start_diapason_price = min_price_product;
end_diapason_price = max_price_product - 100;
if(start_diapason_price > 0) {
current_start_diapason_price = start_diapason_price;
}
else {
current_start_diapason_price = min_price_product;
start_diapason_price = min_price_product;
}
if(end_diapason_price > 0) {
current_end_diapason_price = end_diapason_price;
}
else {
current_end_diapason_price = max_price_product;
end_diapason_price = max_price_product;
}
// переопредение переменных, если пользователь уже указывал диапазон цен
<xsl:if test="$min_price !='' or $max_price !=''">
price_status = 1;
min_price = parseFloat('<xsl:value-of select="$min_price" />');
max_price = parseFloat('<xsl:value-of select="$max_price" />');
</xsl:if>
</script>
Здесь выполняется выборка значений ценового диапазона из административной панели и подготовка нужных переменных для передачи в swf-файл с анимацией ползунков.
Генерация JavaScript-кода прямо в XSLT-шаблоне не очень приятное занятие, так как некоторые конструкции JavaScript нельзя записать, не подвергнув дополнительной обработке в соответствии с правилами XSLT.
Шаблонизатор Umi.CMS ревностно следит за соблюдением чистоты синтаксиса шаблона, однако это простейший путь получения значений переменых из административной панели.
К тому же данные переменные используются и далее в шаблоне для решения уже других задач, не связанных с текущей.
3) Подготовка кода JavaScript для организации взаимодействия между формой и ползунками.
Необходимо подготовить функции обмена данными с кодом ActionScript. Их можно разместить в отдельном файле JavaScript. Там же присутствует инициализация нужных переменных и запуск функции первоначальной установки позиций ползунков после загрузки страницы.
Для последней цели применяется библиотека jQuery, которая должна быть предварительно подключена, а поскольку её кроссбраузерность признаётся не всеми браузерами, можно дополнить вызов функции инициализации назначением обработчика события onLoad для тега body.
Каких-либо особых библиотек для организации взаимодействия JavaScript и ActionScript не требуется. Всё уже есть и готово к использованию непосредственно в самих языках.
Список необходимых функций JavaScript может выглядеть следующим образом:
// эта фукнция вызывается из кода ActionScript для назначения минимального уровня цен со стороны пользователя
function setStartDiapason(start_diapason) {
current_start_diapason_price = start_diapason;
document.filter_form.min_price.value = current_start_diapason_price;
}
// эта фукнция вызывается из кода ActionScript для назначения максимального уровня цен со стороны пользователя
function setEndDiapason(end_diapason) {
current_end_diapason_price = end_diapason;
document.filter_form.max_price.value = current_end_diapason_price;
}
Значения, устанавливаемые этими функциями, в дальнейшем используются для выбора товаров в указанном ценовом диапазоне.
// обращение к swf-файлу с анимацией ползунков для передачи начальных значений
jQuery(document).ready(function(){
if(document.diapason) {
document.diapason.getDiapasonData(start_diapason_price, end_diapason_price, price_status, min_price, max_price);
}
});
// вызов этой функции можно сделать так: <body onLoad="setDiapasonPrice();">
// точно такая же передача начальных данных в swf-файл
function setDiapasonPrice() {
if(document.diapason) {
document.diapason.getDiapasonData(start_diapason_price, end_diapason_price, price_status, min_price, max_price);
}
};
// Передача новых значений в swf-файл после заполнения пользователем текстовых полей формы
function setDiapasonValue() {
var temp_min_price = parseInt(document.filter_form.min_price.value);
var temp_max_price = parseInt(document.filter_form.max_price.value);
if(temp_min_price <= temp_max_price) {
document.diapason.setDiapasonValue(temp_min_price, temp_max_price);
}
}
После выполнения указанных шагов посетитель сайта получает форму фильтрации товаров, в которой может задавать диапазон цен посредством ползунков swf-файла либо привычных полей ввода текста.
Примерно по такой схеме можно организовать взаимодействие Umi.CMS с Flash-роликами, используя в качестве посредника код JavaScript.
Автор: angekus