Часто бывают задачи, где 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, приоритет и скорость ответа там выше.