1

I have created a UI form with field catalog rule conditions. The form loads display the conditions section and it is saved in the table. But in edit case the conditions are not displayed.

Reference: https://www.mageworx.com/blog/2016/09/magento-2-module-with-conditions-model-fieldset/

Please help me to resolve this. Here is my code

Installschema.php

 public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $installer = $setup;
        $contextInterface = $context;
        $installer->startSetup();

        $table = $installer->getConnection()->newTable(
            $installer->getTable('example_label')
        )->addColumn(
            'label_id',
            \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
            null,
            ['identity' => true, 'nullable' => false, 'primary' => true],
            'ID'
        )->addColumn(
            'name',
            \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
            255,
            ['nullable' => false],
            'Name'
        )->addColumn(
            'conditions_serialized',
            Table::TYPE_TEXT,
            '4G',
            [],
            'Conditions Serialized'
        )->addIndex(
            $installer->getIdxName('example_label', ['name']),
            ['name']
        )->setComment('example_label Table');
        $installer->getConnection()->createTable($table);

     }

UI Form

<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">productlabel_form.productlabel_form_data_source</item>
            <item name="deps" xsi:type="string">productlabel_form.productlabel_form_data_source</item>
        </item>
        <item name="label" xsi:type="string" translate="true">Information</item>
        <item name="config" xsi:type="array">
            <item name="dataScope" xsi:type="string">data</item>
            <item name="namespace" xsi:type="string">productlabel_form</item>
        </item>
        <item name="buttons" xsi:type="array">
            <item name="save" xsi:type="string">Vendor\ProductLabel\Block\Adminhtml\Productlabel\Edit\Button\Save</item>           
        </item>
    </argument>
    <settings>
        <layout>
            <navContainerName>left</navContainerName>
            <type>tabs</type>
        </layout>
        <deps>
            <dep>productlabel_form.productlabel_form_data_source</dep>
        </deps>
    </settings>
    <dataSource name="productlabel_form_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Vendor\ProductLabel\Model\ResourceModel\Productlabel\DataProvider</argument>
            <argument name="name" xsi:type="string">productlabel_form_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">label_id</argument>
            <argument name="requestFieldName" xsi:type="string">label_id</argument>
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="submit_url" xsi:type="url" path="productlabel/productlabel/save"/>
                </item>
            </argument>
        </argument>
        <argument name="data" xsi:type="array">
            <item name="js_config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>
            </item>
        </argument>
    </dataSource>
    <fieldset name="productlabel_details">
        <settings>
            <label translate="true">Details</label>
        </settings>

        <field name="label_id">
         <argument name="data" xsi:type="array">
             <item name="config" xsi:type="array">
                 <item name="visible" xsi:type="boolean">false</item>
                 <item name="dataType" xsi:type="string">text</item>
                 <item name="formElement" xsi:type="string">input</item>
                 <item name="source" xsi:type="string">label_id</item>
             </item>
         </argument>
        </field>  
        <field name="name">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Name</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="source" xsi:type="string">name</item>
                    <item name="dataScope" xsi:type="string">name</item>
                    <item name="required" xsi:type="boolean">true</item>
                    <item name="validation" xsi:type="array">
                            <item name="required-entry" xsi:type="boolean">true</item>
                    </item>
                </item>
            </argument>
        </field>       


    </fieldset>
    <fieldset name="conditions_fieldset">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="label" xsi:type="string" translate="true">Conditions</item>
                <item name="collapsible" xsi:type="boolean">false</item>
            </item>
        </argument>
        <container name="conditions_serialized_container" >
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="sortOrder" xsi:type="number">10</item>
                </item>
            </argument>
            <htmlContent name="html_content">
                <argument name="block" xsi:type="object">Vendor\ProductLabel\Block\Adminhtml\Productlabel\Edit\Tab\Conditions</argument>
            </htmlContent>
        </container>
    </fieldset>
</form>

Conditions.php

use Magento\Framework\App\ObjectManager;

class Conditions extends \Magento\Backend\Block\Widget\Form\Generic 
{

    protected $_rendererFieldset;


    protected $_conditions;

    protected $_nameInLayout = 'conditions';

    private $ruleFactory;

    private $labelFactory;


    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Data\FormFactory $formFactory,
        \Magento\Rule\Block\Conditions $conditions,
        \Magento\Backend\Block\Widget\Form\Renderer\Fieldset $rendererFieldset,
        \Vendor\ProductLabel\Model\ProductlabelFactory $labelFactory,
        array $data = []
    ) {
        $this->_rendererFieldset = $rendererFieldset;
        $this->_conditions = $conditions;
        $this->labelFactory = $labelFactory;
        parent::__construct($context, $registry, $formFactory, $data);
    }


    private function getRuleFactory()
    {
        if ($this->ruleFactory === null) {
            $this->ruleFactory = ObjectManager::getInstance()->get('Magento\CatalogRule\Model\RuleFactory');
        }
        return $this->ruleFactory;
    }

    public function getTabClass()
    {
        return null;
    }


    public function getTabUrl()
    {
        return null;
    }

    public function isAjaxLoaded()
    {
        return false;
    }


    public function getTabLabel()
    {
        return __('Conditions');
    }


    public function getTabTitle()
    {
        return __('Conditions');
    }

    public function canShowTab()
    {
        return true;
    }


    public function isHidden()
    {
        return false;
    }


    protected function _prepareForm()
    {
        $model = $this->_coreRegistry->registry('current_label');
        $form = $this->addTabToForm($model);
        $this->setForm($form);

        return parent::_prepareForm();
    }


    protected function addTabToForm($model, $fieldsetId = 'conditions_serialized_field', $formName = 'productlabel_form')
    {
        if (!$model) {
            $id = $this->getRequest()->getParam('id');
            $model = $this->getRuleFactory()->create();
            $model->load($id);
        }
        $conditionsFieldSetId = $model->getConditionsFieldSetId($formName);
        $newChildUrl = $this->getUrl(
            'catalog_rule/promo_catalog/newConditionHtml/form/' . $conditionsFieldSetId,
            ['form_namespace' => $formName]
        );


        /** @var \Magento\Framework\Data\Form $form */
        $form = $this->_formFactory->create();
        $form->setHtmlIdPrefix('rule_');
        $renderer = $this->_rendererFieldset->setTemplate(
            'Magento_CatalogRule::promo/fieldset.phtml'
        )->setNewChildUrl(
            $newChildUrl
        );


        $fieldset = $form->addFieldset(
            $fieldsetId,
            [
                'legend' => __(
                    'Apply the rule only if the following conditions are met (leave blank for all products).'
                )
            ]
        )->setRenderer(
            $renderer
        );
        $fieldset->addField(
            'conditions',
            'text',
            [
                'name'           => 'conditions',
                'label'          => __('Conditions'),
                'title'          => __('Conditions'),
                'required'       => true,
                'data-form-part' => $formName
            ]
        )->setRule(
            $model
        )->setRenderer(
            $this->_conditions
        );

        $form->setValues($model->getData());

        $this->setConditionFormName($model->getConditions(), $formName);
        return $form;
    }

     private function setConditionFormName(\Magento\Rule\Model\Condition\AbstractCondition $conditions, $formName)
    {
        $conditions->setFormName($formName);
        if ($conditions->getConditions() && is_array($conditions->getConditions())) {
            foreach ($conditions->getConditions() as $condition) {
                $this->setConditionFormName($condition, $formName);
            }
        }

Save Controller

public function execute()
    {
        $resultRedirect = $this->resultRedirectFactory->create();
        $data = $this->getRequest()->getPostValue();
        if ($data) {


            if(isset($data['rule'])){
                $dataArray['conditions_serialized'] = $this->serializer->serialize($data['rule']['conditions']);
            }
            $dataArray['name'] = $data['productlabel_details']['name'];


            $label = $this->labelDataFactory->create();
            $this->dataObjectHelper->populateWithArray(
                $label,
                $dataArray,
                '\Vendor\ProductLabel\Api\Data\ProductlabelInterface'
            );
            try {                
                $labelInterface = $this->labelRepository->save($label);
                $this->_getSession()->setFormData(false);
                $this->messageManager->addSuccess(__('You saved the item.'));                
                return $resultRedirect->setPath('*/*/');
            } catch (\Exception $e) {

            }
        }
        return $resultRedirect->setPath('*/*/');
    }

Edit Controller

 public function execute()
    {
        $id = $this->getRequest()->getParam('label_id');
        $model = $this->labelFactory->create();   

        if ($id) {
            $model->load($id);                        
            if (!$model->getId()) {                
                $resultRedirect = $this->resultRedirectFactory->create();
                return $resultRedirect->setPath('*/*/');
            }

        }

        $data = $this->_session->getPageData(true);
        if (!empty($data)) {
            $model->addData($data);
        }

        $model->getConditions()->setJsFormObject('conditions_serialized_field');

        $this->coreRegistry->register('current_label', $model);

        $resultPage = $this->resultPageFactory->create();

        $this->initPage($resultPage)->addBreadcrumb(
            $id ? __('Edit Product Label') : __('New  Label'),
            $id ? __('Edit Product Label') : __('New  Label')
        );
        $resultPage->getConfig()->getTitle()->prepend(__(' labels'));
        $resultPage->getConfig()->getTitle()->prepend($id? ('Edit  Label') : __('New  Label'));
        return $resultPage;
    }

2 Answers 2

1

I have fixed the issue by changing the save function.

Conditions Block

    use Magento\Backend\Block\Widget\Tab\TabInterface;
    use Magento\Backend\Block\Widget\Form\Generic;

    class Conditions extends Generic implements TabInterface
    {



  protected $rendererFieldset;

    protected $conditions;

    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Data\FormFactory $formFactory,
        \Magento\Rule\Block\Conditions $conditions,
        \Magento\Backend\Block\Widget\Form\Renderer\Fieldset $rendererFieldset,
        \Vendor\ProductLabel\Model\ProductlabelFactory $labelFactory,
        array $data = []
    ) {
        $this->rendererFieldset = $rendererFieldset;
        $this->conditions = $conditions;
        $this->labelFactory = $labelFactory;
        parent::__construct($context, $registry, $formFactory, $data);
    }

     public function getTabLabel()
    {
        return __('Conditions');
    }

    public function getTabTitle()
    {
        return __('Conditions');
    }

    public function canShowTab()
    {
        return true;
    }

    public function isHidden()
    {
        return false;
    }

    protected function _prepareForm()
    {
        $model = $this->_coreRegistry->registry('current_label');
        $form = $this->addTabToForm($model);
        $this->setForm($form);
        return parent::_prepareForm();
    }


    protected function addTabToForm($model, $fieldsetId = 'conditions_fieldset', $formName = 'productlabel_form')
    {
        if (!$model) {
            $id = $this->getRequest()->getParam('id');
            $model = $this->labelFactory->create();
            $model->load($id);
        }

        $newChildUrl = $this->getUrl('productlabel/productlabel/newConditionHtml/form/rule_conditions_fieldset');

        /** @var \Magento\Framework\Data\Form $form */
        $form = $this->_formFactory->create();
        $form->setHtmlIdPrefix('rule_');
        $renderer = $this->rendererFieldset->setTemplate(
            'Magento_CatalogRule::promo/fieldset.phtml'
        )->setNewChildUrl(
            $newChildUrl
        );

        $fieldset = $form->addFieldset(
            $fieldsetId,
            [
                'legend' => __(
                    'Apply the rule only if the following conditions are met (leave blank for all products).'
                )
            ]
        )->setRenderer(
            $renderer
        );
        $fieldset->addField(
            'conditions',
            'text',
            [
                'name'           => 'conditions',
                'label'          => __('Conditions'),
                'title'          => __('Conditions'),
                'required'       => true,
                'data-form-part' => $formName
            ]
        )->setRule(
            $model
        )->setRenderer(
            $this->conditions
        );

        $form->setValues($model->getData());

        $this->setConditionFormName($model->getConditions(), $formName);
        return $form;
    }


    private function setConditionFormName(\Magento\Rule\Model\Condition\AbstractCondition $conditions, $formName)
    {
        $conditions->setFormName($formName);
        if ($conditions->getConditions() && is_array($conditions->getConditions())) {
            foreach ($conditions->getConditions() as $condition) {
                $this->setConditionFormName($condition, $formName);
            }
        }
    }
}

NewConditionHtml Controller

namespace Vendor\ProductLabel\Controller\Adminhtml\Productlabel;

class NewConditionHtml extends \Vendor\ProductLabel\Controller\Adminhtml\Productlabel
{


     public function execute()
    {
        $id = $this->getRequest()->getParam('id');
        $labelFactory = $this->_objectManager->create('Vendor\ProductLabel\Model\ProductlabelFactory');
        $typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type')));
        $type = $typeArr[0];
        $model = $this->_objectManager->create(
            $type
        )->setId(
            $id
        )->setType(
            $type
        )->setRule(
            $labelFactory->create()
        )->setPrefix(
            'conditions'
        );

        if (!empty($typeArr[1])) {
            $model->setAttribute($typeArr[1]);
        }

        if ($model instanceof \Magento\Rule\Model\Condition\AbstractCondition) {
            $model->setFormName('productlabel_form')->setJsFormObject('conditions_fieldset');
            $html = $model->asHtmlRecursive();
        } else {
            $html = '';
        }
        $this->getResponse()->setBody($html);
    }
}

Save Controller

class Save extends \Vendor\ProductLabel\Controller\Adminhtml\Productlabel
{

    private $productModel;
    private $labelFactory;
    protected $imageUploader;

    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\Registry $registry,
        \Vendor\ProductLabel\Model\ProductlabelFactory $labelFactory,
        \Magento\Catalog\Model\Product $product
    ) {
        $this->labelFactory = $labelFactory;
        $this->productModel = $product;
        parent::__construct($context, $registry);
    }


    public function execute()
    {
        $resultRedirect = $this->resultRedirectFactory->create();
        $data = $this->getRequest()->getPostValue();

        if ($data) {
            $model = $this->labelFactory->create();
            if(isset($data['productlabel_details']['label_id'])){
                $id = $data['productlabel_details']['label_id'];
                if ($id) {
                    $model->load($id);
                    $dataArray['id'] = $id;                    
                }
            }

            if(isset($data['rule'])){
                unset($data['rule']['conditions']['type']);
                unset($data['rule']['conditions']['value']);
                unset($data['rule']['conditions']['aggregator']);
                $dataArray['conditions'] = $data['rule']['conditions'];//$this->serializer->serialize
            }

            $dataArray['form_key'] = $data['form_key'];
            $dataArray['name'] = $data['productlabel_details']['name'];

            $model->loadPost($dataArray);
            try {                
                $model->save();
                $this->_getSession()->setFormData(false);
                $this->messageManager->addSuccess(__('You saved the item.'));
                if ($this->getRequest()->getParam('back')) {
                    return $resultRedirect->setPath('*/*/edit', ['label_id' => $model->getId()]);
                }
                return $resultRedirect->setPath('*/*/');
            } catch (\Exception $e) {
                $this->messageManager->addError($e->getMessage());
                $this->_getSession()->setFormData($data);
                return $resultRedirect->setPath(
                    '*/*/edit',
                    ['label_id' => $model->getId()]
                );
            }
        }
        return $resultRedirect->setPath('*/*/');
    }
}
0

Try with below way :

In your data provider file set condition field value like below.

Vendor\ProductLabel\Model\ResourceModel\Productlabel\DataProvider

 "conditions_serialized_field" => $collectionData->getData('conditions_serialized_field')

I hope it works!

6
  • I have tried it,but it is not working May 16, 2019 at 10:48
  • Have you got any error? other fields data are coming up with filled? May 16, 2019 at 11:04
  • There is no errors. All other fields are working fine. May 16, 2019 at 11:09
  • Got the issue. It is due to the serialize function in the save controller May 16, 2019 at 11:29
  • In the database serialized value is not saved? May 16, 2019 at 11:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.