1

I've created a grid under a tab in an admin UI form. But I'm having trouble saving the checkbox change values.

enter image description here

I can't catch the tab checkbox values on form submit in the controller. Only the values from the top tab come through (this is a ui form).

Any ideas?

UI XML code

https://github.com/DominicWatts/Announce/blob/develop/view/adminhtml/ui_component/xigen_announce_group_form.xml#L42-L50

    <htmlContent name="announce_group_edit_tab_view_message_content">
        <block class="Xigen\Announce\Block\Adminhtml\Group\Edit\Tab\Tab" name="announce_group_edit_tab_message" template="Xigen_Announce::tab/message.phtml">
            <block class="Xigen\Announce\Block\Adminhtml\Group\Edit\Tab\Message" name="announce_group_edit_tab_message_grid" />
            <arguments>
                <argument name="sort_order" xsi:type="number">100</argument>
                <argument name="tab_label" xsi:type="string" translate="true">Messages</argument>
            </arguments>
        </block>
    </htmlContent>

Grid code

https://github.com/DominicWatts/Announce/blob/develop/Block/Adminhtml/Group/Edit/Tab/Message.php

<?php

declare(strict_types=1);

namespace Xigen\Announce\Block\Adminhtml\Group\Edit\Tab;

use Magento\Backend\Block\Template\Context;
use Magento\Backend\Block\Widget\Grid\Extended as ExtendedGrid;
use Magento\Backend\Block\Widget\Tab\TabInterface;
use Magento\Backend\Helper\Data;
use Magento\Framework\Registry;
use Xigen\Announce\Api\Data\GroupInterface;
use Xigen\Announce\Model\ResourceModel\Message\CollectionFactory;

class Message extends ExtendedGrid implements TabInterface
{
    /**
     * @var Registry
     */
    protected $coreRegistry = null;

    /**
     * @var bool
     */
    protected $isAjaxLoaded = true;

    /**
     * @var \Xigen\Announce\Model\ResourceModel\Message\CollectionFactory
     */
    protected $messageCollectionFactory;

    public function __construct(
        Context $context,
        Data $backendHelper,
        CollectionFactory $messageCollectionFactory,
        Registry $coreRegistry,
        array $data = []
    ) {
        $this->messageCollectionFactory = $messageCollectionFactory;
        $this->coreRegistry = $coreRegistry;
        parent::__construct($context, $backendHelper, $data);
    }

    /**
     * @return void
     */
    protected function _construct()
    {
        parent::_construct();
        $this->setId('announce_group_edit_tab_message_grid');
        $this->setDefaultSort('message_id');
        $this->setDefaultDir('DESC');
        $this->setTitle(__('Messages'));
        $this->setSaveParametersInSession(true);
        $this->setUseAjax(true);
        if ($groupId = $this->getRequest()->getParam('group_id')) {
            $this->setDefaultFilter(['group_id' => $groupId]);
        }
        if ($this->canShowTab()) {
            $this->setDefaultFilter(['in_messages' => 1]);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getTabLabel()
    {
        return __('Messages');
    }

    /**
     * {@inheritdoc}
     */
    public function getTabTitle()
    {
        return __('Messages');
    }

    /**
     * {@inheritdoc}
     */
    public function isHidden()
    {
        return false;
    }

    /**
     * @return Grid
     */
    protected function _prepareCollection()
    {
        $collection = $this->messageCollectionFactory->create()
            ->addFieldToSelect("*");
        $this->setCollection($collection);
        return parent::_prepareCollection();
    }

    /**
     * @return Extended
     */
    protected function _prepareColumns()
    {
        $this->addColumn(
            'in_messages',
            [
                'type' => 'checkbox',
                'name' => 'in_messages',
                'values' => $this->_getSelectedMessages(),
                'align' => 'center',
                'index' => 'message_id',
                'header_css_class' => 'col-select',
                'column_css_class' => 'col-select'
            ]
        );

        $this->addColumn(
            'message_id',
            [
                'header' => __('Message Id'),
                'sortable' => true,
                'index' => 'message_id',
                'header_css_class' => 'col-id',
                'column_css_class' => 'col-id'
            ]
        );

        $this->addColumn(
            'name',
            [
                'header' => __('name'),
                'sortable' => true,
                'index' => 'name',
                'header_css_class' => 'col-name',
                'column_css_class' => 'col-name'
            ]
        );

        $this->addColumn(
            'status',
            [
                'header' => __('Status'),
                'align' => 'center',
                'filter' => \Xigen\Announce\Block\Adminhtml\Group\Edit\Tab\Grid\Filter\Status::class,
                'index' => 'status',
                'renderer' => \Xigen\Announce\Block\Adminhtml\Group\Edit\Tab\Grid\Renderer\Status::class
            ]
        );

        $this->addColumn(
            'sort',
            [
                'header' => __('Sort'),
                'type' => 'number',
                'validate_class' => 'validate-number',
                'index' => 'sort',
                'editable' => true,
                'edit_only' => true,
                'header_css_class' => 'col-sort',
                'column_css_class' => 'col-sort'
            ]
        );

        // $this->addExportType('*/*/exportCsv', __('CSV'));
        // $this->addExportType('*/*/exportExcel', __('Excel XML'));

        return parent::_prepareColumns();
    }

    /**
     * Add filter
     *
     * @param Column $column
     * @return $this
     */
    protected function _addColumnFilterToCollection($column)
    {
        // Set custom filter for in message flag
        if ($column->getId() == 'in_messages') {
            $messageIds = $this->_getSelectedMessages();
            if (empty($messageIds)) {
                $messageIds = 0;
            }
            if ($column->getFilter()->getValue()) {
                $this->getCollection()->addFieldToFilter('message_id', ['in' => $messageIds]);
            } else {
                if ($messageIds) {
                    $this->getCollection()->addFieldToFilter('message_id', ['nin' => $messageIds]);
                }
            }
        } else {
            parent::_addColumnFilterToCollection($column);
        }
        return $this;
    }

    /**
     * @inheritdoc
     */
    public function canShowTab()
    {
        return $this->coreRegistry->registry('xigen_announce_group');
    }

    /**
     * Tab should be loaded through Ajax call
     * @return bool
     */
    public function isAjaxLoaded()
    {
        return false;
    }

    /**
     * Checks when this block is readonly
     * @return bool
     */
    public function isReadonly()
    {
        return false;
    }

    /**
     * Retrieve selected related messages
     * @return array
     */
    protected function _getSelectedMessages()
    {
        return array_keys($this->getSelectedMessages());
    }

    /**
     * Retrieve related message
     * @return array
     */
    public function getSelectedMessages()
    {
        $messages = [];

        if ($selected = $this->coreRegistry->registry('xigen_announce_group')) {
            $collection = $selected->getMessages();
        } elseif ($groupId = $this->getRequest()->getParam('group_id')) {
            $collection = $this->messageCollectionFactory->create()
                ->addFieldToSelect("*")
                ->addFieldToFilter(GroupInterface::GROUP_ID, ['eq' => $groupId]);
        }

        foreach ($collection as $item) {
            $messages[$item->getMessageId()] = ['sort' => $item->getSort()];
        }

        return $messages;
    }

    /**
     * @return string
     */
    public function getGridUrl()
    {
        return $this->getUrl('*/*/grid', ['_current' => true]);
    }

    /**
     * get row url
     * @param  object $row
     * @return string
     */
    public function getRowUrl($row)
    {
        return $this->getUrl(
            '*/message/edit',
            ['message_id' => $row->getId()]
        );
    }
}

In the controller I'm var dumping

var_dump($this->getRequest()->getPostValue());
var_dump($this->getRequest()->getParams());

But nothing for this tab. Until I catch the checkbox values I can't save changes.

1
+100

You need to do some changes and corrections.

Edit view/adminhtml/ui_component/xigen_announce_group_form.xml file and put some extra code under announce_group_edit_tab_message as per below.

    <block class="Xigen\Announce\Block\Adminhtml\Group\Edit\Tab\Tab" name="announce_group_edit_tab_message" template="Xigen_Announce::tab/message.phtml">
        <block class="Xigen\Announce\Block\Adminhtml\Group\Edit\Tab\Message" name="announce_group_edit_tab_message_grid" />
        <arguments>
            <argument name="sort_order" xsi:type="number">100</argument>
            <argument name="tab_label" xsi:type="string" translate="true">Messages</argument>
        </arguments>
        <block class="Magento\Backend\Block\Widget\Grid\Serializer" name="customerproduct_grid_serializer">
            <arguments>
                <argument name="grid_block" xsi:type="string">announce_group_edit_tab_message_grid</argument>
                <argument name="callback" xsi:type="string">_getSelectedMessages</argument>
                <argument name="input_element_name" xsi:type="string">messages_list</argument>
                <argument name="reload_param_name" xsi:type="string">in_messages</argument>
            </arguments>
        </block>
        <block name="grid_script_js" template="Xigen_Announce::script-js.phtml"/>
    </block>

Now you need to change the method public from protected.

    public function _getSelectedMessages() {
          return array_keys($this->getSelectedMessages());
    }

We need to add a custom template file script-js.phtml to add an input field under POST data.

<script>
    require(["jquery"], function($){ $("input[name='messages_list']").attr('data-form-part','xigen_announce_group_form'); });
</script>

You may need to work on post data because it will send data like "1&2&3".

| improve this answer | |
  • Couple of minor adjustments i.e. name field was message[list] but otherwise that got me there! Thanks – Dominic Xigen May 22 at 23:27
1
  1. in your block template, you may create a hidden field (see /vendor/magento/module-catalog/view/adminhtml/templates/catalog/category/edit/assign_products.phtml for an example of what I mean)

  2. then, very much like this template above shows, add a javascript snippet that may behave similarly to /vendor/magento/module-catalog/view/adminhtml/web/catalog/category/assign-products.js. particularly, the line gridJsObject.rowClickCallback = categoryProductRowClick; and $('in_category_products').value = Object.toJSON(categoryProducts); may be most useful

| improve this answer | |
  • I appreciate the example. I took a look and I think with a bit more time I might have been able to untangle this example and get something working, But in this case the other solution was simpler and easier to implement with what I had already done. – Dominic Xigen May 22 at 23:30
  • No problem, glad you’re sorted. – Herve Tribouilloy May 23 at 7:47

Your Answer

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

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