Very often, to save some module settings we have to create and use custom fields for the module settings page. To demonstrate the case, let’s take multiselect sorting as an example, which is used in our module BelVG_Priсelist for sorting attributes. We are going to use jQuery UI as a supplementary library, specifically, the part which is responsible for sorting.
In the first place we create a custom field for the module settings in the admin panel.
File app\code\BelVG\Pricelist\etc\adminhtml\system.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
---------------------------------------------------------------------- <?xml version="1.0" encoding="UTF-8"?> ... <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../Config/etc/system_file.xsd"> <system> … <section id="pricelist" translate="label" sortOrder="140" showInDefault="1" showInWebsite="1" showInStore="1"> … <group id="content" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1"> … <field id="attributes" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Additional Attributes</label> <source_model>BelVG\Pricelist\Model\Config\Source\Attributes</source_model> <frontend_model>BelVG\Pricelist\Block\System\Config\Form\Field\Attributes</frontend_model> </field> </group> </section> </system> </config> |
Key nodes here are sоurсe_mоdel and frоntend_mоdel and the parameter type in the field node:
- Sоurсe_mоdel – determines values for multiselect;
- Frоntend_mоdel – defines the layout of the field;
- Type – determines the type of the source element which we are going to extend;
- Source_model – this one is quite simple: here we fetch the required attributes and pass as an array with the method toOptionArray().
File app\code\BelVG\Pricelist\Model\Config\Source\Attributes.php (DOWNLOAD):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
------------------------------------------------------------------------------------------------------- <?php namespace BelVG\Pricelist\Model\Config\Source; class Attributes implements \Magento\Framework\Option\ArrayInterface { protected $_entityType; protected $_store; public function __construct( \Magento\Store\Model\Store $store, \Magento\Eav\Model\Entity\Type $entityType ) { $this->_store = $store; $this->_entityType = $entityType; } public function toOptionArray() { $types = array('text', 'select', 'decimal'); $attributes = $this->_entityType->loadByCode('catalog_product')->getAttributeCollection(); $attributes->addFieldToFilter('frontend_input', $types); $result = array(); foreach ($attributes as $attr) { if ($attr->getFrontendLabel()) { $result[] = array('value' => $attr->getAttributeId(), 'label' => $attr->getFrontendLabel(), 'title' => $attr->getAttributeCode()); } } return $result; } } |
Lets have a closer look at the class frоntend_mоdel. The basic idea is to extend the original element (type = text) and to add additional elements into js code. We will use the same bасkend_mоdel for saving values – in our case this is ( ).
File app\code\BelVG\Pricelist\Block\System\Config\Form\Field\Attributes.php (DOWNLOAD):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
--------------------------------------------------------------------------------------------------------------------- <?php namespace BelVG\Pricelist\Block\System\Config\Form\Field; use Magento\Framework\Data\Form\Element\AbstractElement; class Attributes extends \Magento\Config\Block\System\Config\Form\Field { protected function _getElementHtml(AbstractElement $element) { $values = $element->getValues(); $html = '<table id="' . $element->getId() . '_table" class="ui_select_table" cellspacing="0">'; $html .= '<tbody><tr>'; $html .= '<td><ul id="' . $element->getId() . '_selected" class="ui_select selected sortable">'; $selected = explode(',', $element->getValue()); foreach ($selected as $value) { if ($key = array_search($value, array_column($values, 'value'))) { $html .= '<li value="' . $value . '" title="' . $values[$key]['title'] . '">'; $html .= isset($values[$key]['label'])?$values[$key]['label']:'n/a'; $html .= '</li>'; $values[$key]['selected'] = TRUE; } } $html .= '</ul></td><td>'; $html .= '<ul id="' . $element->getId() . '_source" class="ui_select source sortable">'; if ($values) { foreach ($values as $option) { if (!isset($option['selected'])) { $html .= '<li value="' . $option['value'] . '" title="' . $option['title'] . '">'; $html .= isset($option['label'])?$option['label']:'n/a'; $html .= '</li>'; } } } $html .= '</ul></td></tr></tbody></table>'; $html .= '<div style="display:none;">' . $element->getElementHtml() . '</div>'; $html .= '<script type="text/javascript"> require(["jquery"], function(jQuery){ require(["BelVG_Pricelist/js/verpage", "ui/1.11.4"], function(){ jQuery(document).ready( function() { jQuery("#' . $element->getId() . '_selected, #' . $element->getId() . '_source").sortable({ connectWith: ".sortable", stop: function(event, ui) { var vals = []; jQuery("#' . $element->getId() . '_selected").find("li").each(function(index, element){ vals.push(jQuery(element).val()); }); jQuery("#' . $element->getId() . '").val(vals); } }).disableSelection(); }); }) }) </script>'; return $html; } } |
Magento 2 Migration
Take your online store to the next level with BelVG Magento 2 Migration
Visit the pageBasically, it is enough to override only the method _getElementHtml() in our case. But for more complex custom fields you may need to override some other methods too. To connect an additional js library it should be added to requirejs-config.js under app/code/BelVG/Pricelist/view/аdminhtml:
File app/code/BelVG/Pricelist/view/adminhtml/requirejs-config.js:
1 2 3 4 5 6 7 8 9 |
--------------------------------------------------------------------------------------------------------------------- var config = { map: { '*': { 'ui/1.11.4': 'BelVG_Pricelist/jqueryext/ui/1.11.4/jquery-ui' } } }; |
Also place the library file into the folder: app/code/BelVG/Pricelist/view/adminhtml/web/jqueryext/ui/1.11.4/ jquery-ui.js
So now we have a custom element where you can select and sort elements (in the demonstrated case these are attributes):
It is possible to use this element in any project or module practically unchanged.
Magento Extensions
Take your online store to the next level with BelVG Magento extensions
Visit the store