There are often tasks where Ajax is just necessary. Fortunately, it’s not hard to add responsiveness to your element.
We will have to do several things:
public function __construct() { parent::__construct(); $this->registerCallback('myFirstAjax'); }
Adding the method to our element.
// We need to know the number of passed parameters in order to receive them. public function myFirstAjax($param1, $param2, $param3) { // We get the default text from the settings of the element. $default = $this->config->get('ajax', 'default text'); return $this->app->jbajax->send(array( 'default' => $default, 'param1' => $param1, 'param2' => $param2, 'param3' => $param3, ) ); }
JBAjax helper and its element method will help us to create a correct link for a POST request.
$url = $this->app->jbrouter->element($this->identifier, $this->getItem()->id, 'myFirstAjax');
If we want to pass additional parameters, we need to prepare args array before sending the request. You can do it using js, for example.
<script type="text/javascript"> jQuery(document).ready(function () { jQuery('.css selector’).on(‘click’, function(){ // Our array with additional parameters 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>
Or you can use php to pass an array as a fourth argument to the send method.
$data = array(‘1’, ‘2’, ‘3’); $url = $this->app->jbrouter->element($this->identifier, $this->getItem()->id, 'myFirstAjax', $data);
You can return the reply as JSON using send method of JBAjax helper. All that you need to do is to specify a key and its value like we did in the above example. Then we just need to receive the result in a js script and process it.
Element is created. We can use it for item submission or make it repeatable. But what to do with an import if we need to fill our website with products?
Fortunately, this is also covered by JBZoo developers. File of the element should be placed in this folder:
/media/zoo/applications/jbuniversal/framework/elements/user/
. File name corresponds to the element name.
Class name should have a prefix - JBCSVItemUser and a postfix (the name of our element) - JBInt. It is inherited from JBCSVItem class.
2 methods should be redefined in our class:
Parent class has two defined constants:
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']; } } // Should we merge repeatable fields? 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; } }
In order for our element to have setting for a filter, we need to create an xml file and fill it.
Using creation of settings for a new element in a filter as an example, we’ll create a new template named number. It will have a unique input type - number. There is also will be a range search.
There are two steps needed to create a filter template for a new element:
XML file with the name of our element should be created here:
/media/zoo/applications/jbuniversal/config/mod_jbzoo_search/jbint.xml
. The name of our template file corresponds to the option name in a parameter - jbzoo_filter_render.
Adding our new template to the parameter:
<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> <!-- Name of the new template --> <option value="number">JBZOO_ELEMENT_TEMPLATE_NUMBER_RANGE</option> <!-- Name of the new template --> <option value="hidden">JBZOO_ELEMENT_TEMPLATE_HIDDEN</option> </param>
Now we need to create a file for the template
/media/zoo/applications/jbuniversal/framework/render/filter/element.<OPTION_ALIAS>.php
Name of the class should start with JBFilterElement and end with an alias of the chosen option, inherited from the JBFilterElement class.
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; } }
If you encounter any obstacles or can’t make something, look at the neighboring files, maybe you’ll find an answer there.
What are events for? By using events we can globally affect the components of ZOO/JBZoo - elements, categories, items.
Let’s examine several events which can be called for an element.
Let’s examine an example. Let’s wrap all elements in a div with the event class. afterDisplay event will help us here - we can get element contents from it.
/** * 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); }
You can find all events for an element in the JBEventElement class:
/media/zoo/applications/jbuniversal/framework/events/jbevent.element.php
Visit our special JBZoo tech support forum which is specifically meant for JBZoo so the priority of the response and its promptness are much better there than in any other place. With inactive account with a “Plus” sign in a tariff plan you can ask for support in one of these sections or use any of our contacts.