Часто бывают задачи, где Ajax просто необходим. К счастью, добавить динамичность в наш элемент не составит большого труда.
Нам необходимо будет выполнить несколько действий:
Зарегистрировать экшен в конструкторе элемента, иначе он не выполнится.
Создать метод с именем аналогичным названию экшена и добавить принимаемые аргументы.
public function __construct() { parent::__construct(); $this->registerCallback('myFirstAjax'); }
Добавляем метод в наш элемент.
// Нам нужно знать количество передаваемых параметров, чтобы их принять. public function myFirstAjax($param1, $param2, $param3) { // Получаем текст по умолчанию из настроек элемента. $default = $this->config->get('ajax', 'default text'); return $this->app->jbajax->send(array( 'default' => $default, 'param1' => $param1, 'param2' => $param2, 'param3' => $param3, ) ); }
Сформировать правильную ссылку для POST запроса на элемент нам поможет хелпер JBAjax и его метод element.
$url = $this->app->jbrouter->element($this->identifier, $this->getItem()->id, 'myFirstAjax');
Если мы хотим добавить дополнительные параметры, нам нужно подготовить массив args перед отправкой запроса. К примеру, это можно сделать в js.
<script type="text/javascript"> jQuery(document).ready(function () { jQuery('.css селектор').on('click', function(){ // Наш массив дополнительных параметров var data = new Array('1', '2', '3'); jQuery.ajax({ type: 'POST', data: 'args=' + data, url: '<?php echo $url; ?>', success: function(html){ console.log(html.param1); console.log(html.param2); console.log(html.param3); console.log(html.default); } }); }); }); </script>
Или с помощью php в метод send передать четвертым аргументом массив.
$data = array('1', '2', '3'); $url = $this->app->jbrouter->element($this->identifier, $this->getItem()->id, 'myFirstAjax', $data);
Отдать ответ в виде JSON можно с помощью метода send в хелпере JBAjax. Все, что нам нужно — указать ключ и его значение, как мы это сделали в примере выше. Дальше нам остается в js скрипте принять результат и обработать его.
Элемент создан. Можем его использовать при подаче материалов, а также делать его повторяемым. Но как же быть с импортом, если нам надо наполнить свой сайт товарами?
К счастью, это так же предусмотрено разработчиками JBZoo. Файл элемента необходимо разместить в папке:
/media/zoo/applications/jbuniversal/framework/elements/user/
.
Название файла соответствует имени элемента.
Создаем файл jbint.php
Название класса должно содержать префикс JBCSVItemUser и постфикс (имя нашего элемента) JBInt. Наследуется от класса JBCSVItem.
В нашем классе должны быть переопределены 2 метода:
У родительского класса определены две константы:
class JBCSVItemUserJBlist extends JBCSVItem { public function toCSV() { $result = array(); $params = $this->app->jbuser->getParam('export-items', array()); if (!empty($this->_value)) { foreach($this->_value as $jbint) { $result[] = $jbint['number']; } } // Объединять повторяемые поля? if ((int)$params->merge_repeatable) { return implode(JBCSVItem::SEP_ROWS, $result); } else { return $result; } } public function fromCSV() { $data = ($position == 1) ? array() : $this->_element->data(); if (strpos($value, JBCSVItem::SEP_ROWS)) { foreach (explode(JBCSVItem::SEP_ROWS, $value) as $val) { $values[] = array( 'number' => $val, ); } $data = $values; } else { $data[] = array('number' => $value); } $this->_element->bindData($data); return $this->_item; } }
Чтобы у нашего элемента появились настройки для фильтра, нам необходимо создать xml файл и наполнить его.
По примеру создания настроек в фильтре для нового элемента, мы создадим и новый шаблон с названием number. Он будет иметь уникальный тип инпута — number. Также будет возможность поиска по диапазону.
Добавление шаблона для нового элемента в фильтр состоит из двух этапов:
Создание xml файла с названием нашего элемента.
Написание класса шаблона.
XML файл с именем нашего элемента надо создать по пути:
/media/zoo/applications/jbuniversal/config/mod_jbzoo_search/jbint.xml
.
Имя нашего файла-шаблона соответствует имени опции в параметре — jbzoo_filter_render.
Добавим в параметр новый шаблон
<param name="jbzoo_filter_render" type="list" label="JBZOO_ELEMENT_TEMPLATE" description="JBZOO_ELEMENT_TEMPLATE_DESC" default="_auto_" > <option value="_auto_">JBZOO_ELEMENT_TEMPLATE_AUTO</option> <option value="text">JBZOO_ELEMENT_TEMPLATE_TEXT</option> <option value="text-range">JBZOO_ELEMENT_TEMPLATE_TEXT_RANGE</option> <option value="checkbox">JBZOO_ELEMENT_TEMPLATE_CHECKBOX</option> <option value="jqueryui">JBZOO_ELEMENT_TEMPLATE_JQUERYUI</option> <option value="radio">JBZOO_ELEMENT_TEMPLATE_RADIO</option> <option value="select">JBZOO_ELEMENT_TEMPLATE_SELECT</option> <option value="select-chosen">JBZOO_ELEMENT_TEMPLATE_SELECT_CHOSEN</option> <option value="slider">JBZOO_ELEMENT_TEMPLATE_SLIDER</option> <!-- Имя нового шаблона --> <option value="number">JBZOO_ELEMENT_TEMPLATE_NUMBER_RANGE</option> <!-- Имя нового шаблона --> <option value="hidden">JBZOO_ELEMENT_TEMPLATE_HIDDEN</option> </param>
Теперь от нас будет требоваться создать файл шаблона
/media/zoo/applications/jbuniversal/framework/render/filter/element.<АЛИАС_ОПЦИИ>.php
.
Название класса должно начинаться с JBFilterElement и заканчиваться алиасом выбранной опции, наследоваться от класса JBFilterElement.
class JBFilterElementNumber extends JBFilterElement { /** * Render HTML * @return string|null */ public function html() { $html = array(); $values = array('', ''); if (isset($this->_value['range'])) { if (!is_array($this->_value['range'])) { $values = explode('/', $this->_value['range']); } else if (is_array($this->_value['range'])) { $values = $this->_value['range']; } } $html[] = '<label for="' . $this->_getId('1') . '">' . JText::_('JBZOO_FROM') . '</label>'; $html[] = $this->_number( $this->_getName('0'), $values[0], $this->_attrs, $this->_getId('1') ); $html[] = '<br />'; $html[] = '<label for="' . $this->_getId('2') . '">' . JText::_('JBZOO_TO') . '</label>'; $html[] = $this->_number( $this->_getName('1'), $values[1], $this->_attrs, $this->_getId('2') ); return implode("\n\r", $html); } /** * Get name * @param $postFix * @return string */ protected function _getName($postFix = null) { return parent::_getName('range') . '[' . $postFix . ']'; } /** * Generates an HTML input type[number]. * @param $name * @param null $value * @param null $attribs * @param null $idtag * @return string */ protected function _number($name, $value = null, $attribs = null, $idtag = null) { if ($idtag && is_array($attribs)) { $attribs['id'] = $idtag; } $attribs = $this->app->jbhtml->buildAttrs($attribs); if (strpos($attribs, 'jsAutocomplete') !== false) { $this->app->jbassets->jqueryui(); $this->app->jbassets->initAutocomplete(); } return '<input type="number" name="'.$name.'" value="'.$value.'" '. $attribs.' />' ; } /** * Get main attrs * @param array $attrs * @return array */ protected function _getAttrs(array $attrs) { $attrs = parent::_getAttrs($attrs); $attrs['maxlength'] = '255'; $attrs['size'] = '60'; if ((int)$this->_params->get('jbzoo_filter_autocomplete', 0)) { $attrs['class'][] = 'jsAutocomplete'; $attrs['placeholder'] = $this->_getPlaceholder(); } return $attrs; } }
Если вы столкнулись с каким-нибудь препятствием или что-то у вас не выходит, загляните в соседние файлы, возможно там вы найдете ответ.
Для чего нужны события? С помощью событий мы можем глобально влиять на составные Zoo/JBZoo — элементы, категории, материалы.
Разберем несколько событий, которые могут быть вызваны для элемента.
afterDisplay — вызывается после вывода.
beforeDisplay — вызывается перед выводом.
download — событие, которое вызывается перед загрузкой, пока что только для DownloadElement.
afterSubmissionDisplay — аналог afterDisplay только при подаче материала.
beforeSubmissionDisplay — аналог beforeDisplay только при подаче материала.
beforeEdit — событие происходит до редактирования.
Рассмотрим пример. Обернем все элементы в div с классом event. Тут нам поможет событие afterDisplay — в нем можно получить содержимое элемента.
/** * On after element display * @param $event */ public static function afterDisplay($event) { $params = $event->getParameters(); $params['html'] = '<div class="event">'.$params['html'].'</div>'; $event->setReturnValue($params); }
Все события по элементу можно посмотреть в классе JBEventElement
/media/zoo/applications/jbuniversal/framework/events/jbevent.element.php
.
Вы можете обратиться на наш специальный форум техподдержки JBZoo. Если у вас нет активного аккаунта со знаком «плюс» в тарифном плане, то вы можете задать свой вопрос в одном из этих разделов или на любой из наших контактов. Форум специально предназначен для JBZoo, приоритет и скорость ответа там выше.