I have looked around and this is my last resort. I'm new to magento 2. I created a plugin in magento 1 (using this link as a good guide) and i would like to replicate same in magento 2 however things aren't working as expected.
I would like to create a dynamic number of fields in admin system.xml. I basically loop through an array and use the values to create fields.
here's the section for the field in my system.xml
<field id="servicestwo" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Providers</label>
<frontend_model>Company\Module\Block\Adminhtml\Config\Form\Fieldset\Carriers</frontend_model>
</field>
Here's my Carriers.php file
namespace Netplus\Saddle\Block\Adminhtml\Config\Form\Fieldset;
use Magento\Config\Block\System\Config\Form\Fieldset;
use Magento\Framework\Data\Form\Element\AbstractElement;
class Carriers extends Fieldset{
protected $_dummyElement;
protected $_fieldRenderer;
protected $_statevalues;
/**
* @param \Magento\Backend\Block\Context $context
* @param \Magento\Backend\Model\Auth\Session $authSession
* @param \Magento\Framework\View\Helper\Js $jsHelper
* @param array $data
*/
public function __construct(
\Magento\Backend\Block\Context $context,
\Magento\Backend\Model\Auth\Session $authSession,
\Magento\Framework\View\Helper\Js $jsHelper,
array $data = []
) {
parent::__construct($context,$authSession,$jsHelper, $data);
}
public function render(AbstractElement $element)
{
$html = $this->_getHeaderHtml($element);
//here you can loop through all the fields you want to add
//for each element you need to call $this->_getFieldHtml($element, $group);
$groups = array(
array('name'=>'0211','label'=>'First Service Provider'),
array('name'=>'0212','label'=>'Second Service Provider'),
array('name'=>'0213','label'=>'Third Service Provider'),
);
foreach ($groups as $group) {
$html.= $this->_getFieldHtml($element, $group) . ' '. $this->_getFieldHtml2($element, $group) ;
}
return $html;
}
//this creates a dummy element so you can say if your config fields are available on default and website level
// - you can skip this and add the scope for each element in _getFieldHtml method
protected function _getDummyElement()
{
if (empty($this->_dummyElement)) {
$this->_dummyElement = new \Magento\Framework\DataObject(array('show_in_default'=>1, 'show_in_website'=>1));
}
return $this->_dummyElement;
}
//this sets the fields renderer. If you have a custom renderer tou can change this.
protected function _getFieldRenderer()
{
if (empty($this->_fieldRenderer)) {
//$this->_fieldRenderer = Mage::getBlockSingleton('adminhtml/system_config_form_field');
$this->_fieldRenderer = $this->_layout->getBlockSingleton('Magento\Config\Block\System\Config\Form\Field');
}
return $this->_fieldRenderer;
}
//this is usefull in case you need to create a config field with type dropdown or multiselect. For text and texareaa you can skip it.
protected function _getStateValues()
{
$options_list=[];
$options_list[] = array('value'=>'State one', 'label'=>'State one');
$options_list[] = array('value'=>'State two', 'label'=>'State two');
$options_list[] = array('value'=>'State three', 'label'=>'State three');
$this->_statevalues = $options_list;
return $this->_statevalues;
}
//this actually gets the html for a field
protected function _getFieldHtml($fieldset, $group)
{
$group_id = $group['value'];
$group_code = $group['label'];
$e = $this->_getDummyElement();//get the dummy element
$field = $fieldset->addField($group_id.'_s_id', 'select',//this is the type of the element (can be text, textarea, select, multiselect, ...)
array(
'name' => 'groups[my_module][fields][group_'.$group_id.'_s_id][value]',//this is groups[group name][fields][field name][value]
'label' => $group_code,//this is the label of the element
'value' => 'Esorom',//$data,//this is the current value
'values' => $this->_getStateValues(),//this is necessary if the type is select or multiselect
'inherit' => 1,
'onchange' => "myFunction( '".$group_id."')",
'can_use_default_value' => $this->getForm()->canUseDefaultValue($e),//sets if it can be changed on the default level
'can_use_website_value' => $this->getForm()->canUseWebsiteValue($e),//sets if can be changed on website level
))->setRenderer($this->_getFieldRenderer());
return $field->toHtml();
}
//this actually gets the html for a field
protected function _getFieldHtml2($fieldset, $group)
{
$group_id = $group['value'];
$group_code = $group['label'];
$e = $this->_getDummyElement();//get the dummy element
$field = $fieldset->addField($group_id.'_l_id', 'text',//this is the type of the element (can be text, textarea, select, multiselect, ...)
array(
'name' => 'groups[my_module][fields][group_'.$group_id.'_l_id][value]',//this is groups[group name][fields][field name][value]
//'label' => $group_code,//this is the label of the element
'value' => 'Osolo',//this is the current value
'inherit' => 1,
'can_use_default_value' => $this->getForm()->canUseDefaultValue($e),//sets if it can be changed on the default level
'can_use_website_value' => $this->getForm()->canUseWebsiteValue($e),//sets if can be changed on website level
))->setRenderer($this->_getFieldRenderer());
return $field->toHtml();
}
}
However on accessing my module settings place in the admin i get the error message:
Fatal error: Uncaught Error: Call to a member function getFieldsetCss() on null in C:\xampp\htdocs\magento_sec\vendor\magento\module-config\Block\System\Config\Form\Fieldset.php:191
and upon investigating, it comes from this line $html = $this->_getHeaderHtml($element);
Please any help would be greatly appreciated.