0

I've added 4 dynamic row while back ref:https://devdocs.magento.com/guides/v2.4/ext-best-practices/tutorials/dynamic-row-system-config.html

Now I've added a 5th column but all the row data that was previously there disappeared!

I can see the data in the database but when the new field is added instead of magento just ignoring if is empty or not set it just won't render.

in _prepareToRender method I have.

protected function _prepareToRender()
    {
        $this->addColumn('from_qty', ['label' => __('From'), 'class' => 'required-entry']);
        $this->addColumn('to_qty', ['label' => __('To'), 'class' => 'required-entry']);
        $this->addColumn('price', ['label' => __('Price'), 'class' => 'required-entry']);
        //$this->addColumn('title', ['label' => __('Title'));
        $this->_addAfter = false;
        $this->_addButtonLabel = __('Add');
    }

above commented out I'm adding a new field called title but the precious rows that was saved when the new field is added it doesn't render in the backend.

any ideas how to go about that? Thanks

2
  • please put full code that you did Apr 23, 2021 at 6:05
  • @Juliano How you have resolved this?
    – amitshree
    Jun 18, 2021 at 4:57

1 Answer 1

0

It's maybe too late, but I answer for next people who stuck on that.

For dynamic row, Magento will fill data with an array of value for each row. If the column key doesn't exist (because you have added a new column), that will break and your config become empty.

To prevent that, you need to override the method protected function _prepareArrayRow(DataObject $row) to fill the row array with empty values for each new column.

For example, I have a dynamic row config with one column by website, if we create a new website we want to have a new column.

So to prevent breaking my config I set empty value to cells which aren't set like that:

protected function _prepareArrayRow(DataObject $row)
{
    $rowData = $row->getData();
    /** @var \Magento\Store\Model\ResourceModel\Website\Collection $websiteCollection */
    $websiteCollection = $this->websiteCollectionFactory->create();

    /** @var \Magento\Store\Model\Website $website */
    foreach ($websiteCollection as $website) {
        $websiteCode = $website->getCode();

        if (!isset($rowData[$websiteCode])) {
            $rowData[$websiteCode] = '';
            $rowData['column_values'][$rowData['_id'] . $websiteCode] = '';
        }
    }

    $row->addData($rowData);
}

To help to understand, that is the array structure for a row :

   [
        '<your_first_column_id>' => '<value>',
        '<your_second_column_id>' => '<value>',
        ...
        '_id' => '<id_of_the_row_generated_by_magento>',
        'columns_values' => [
            '<_id>_<your_first_column_id>' => '<value>',
            '<_id>_<your_second_column_id>' => '<value>'
            ...
        ]
    ]

So you need to add new row with empty value for each new column you add.

(the column_id is the first param you give when you do a addColumn in _preprareToRender)

Have a nice day !

EDIT : There is a better way to make it generic and not depending on what you do in _preprareToRender. You can retrieve all existing columns and set empty value for each of them that doesn't exist in the current row :

protected function _prepareArrayRow(DataObject $row)
{
    $columns = $this->getColumns();
    $rowData = $row->getData();

    foreach ($columns as $key => $column) {
        if (!isset($rowData[$key])) {
            $rowData[$key] = '';
            $rowData['column_values'][$rowData['_id'] . $key] = '';
        }
    }

    $row->addData($rowData);
}

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.