4

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.

Here's the image of what i'm trying to achieve: dynamic fields

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.