2

I created Grid using UI Components and provide Edit action using < actionsColumn > in vendormodulename_entity_list.xml

<actionsColumn name="actions" class="Vendor\Modulename\Ui\Component\Listing\Column\EntityAction">
       <argument name="data" xsi:type="array">
           <item name="config" xsi:type="array">
               <item name="resizeEnabled" xsi:type="boolean">false</item>
               <item name="resizeDefaultWidth" xsi:type="string">107</item>
               <item name="indexField" xsi:type="string">id</item>
           </item>
       </argument>
</actionsColumn>

Created EntityAction.php file under Vendor\Modulename\Ui\Component\Listing\Column directory and define edit page url with authorization rule

namespace Vendor\Modulename\Ui\Component\Listing\Column;


use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;
use Magento\Framework\UrlInterface;

class EntityAction extends Column
  {
   /**
   * Authorization level of a basic admin session
   *
   * @see _isAllowed()
   */
   const ADMIN_RESOURCE = 'Vendor_Modulename::entity';

  /** Url path */
  const ROW_EDIT_URL = 'routeadminlabel/controllername/edit';

  /** @var UrlInterface */
  protected $_urlBuilder;

  /**
   * @var string
   */
  private $_editUrl;

  /**
   * @param ContextInterface   $context
   * @param UiComponentFactory $uiComponentFactory
   * @param UrlInterface       $urlBuilder
   * @param array              $components
   * @param array              $data
   * @param string             $editUrl
   */
  public function __construct(
    ContextInterface $context,
    UiComponentFactory $uiComponentFactory,
    UrlInterface $urlBuilder,
    array $components = [],
    array $data = [],
    $editUrl = self::ROW_EDIT_URL
  ) 
  {
    $this->_urlBuilder = $urlBuilder;
    $this->_editUrl = $editUrl;
    parent::__construct($context, $uiComponentFactory, $components, $data);
  }

  /**
   * Prepare Data Source.
   *
   * @param array $dataSource
   *
   * @return array
   */
  public function prepareDataSource(array $dataSource)
  {
    if (isset($dataSource['data']['items'])) {
        foreach ($dataSource['data']['items'] as &$item) {
            $name = $this->getData('name');
            if (isset($item['st_id'])) {
                $item[$name]['edit'] = [
                    'href' => $this->_urlBuilder->getUrl(
                        $this->_editUrl, 
                        ['id' => $item['st_id']]
                    ),
                    'label' => __('Edit'),
                ];
            }
        }
    }

    return $dataSource;
  }
}

and finally I created action file in controller dir

namespace Vendor\Modulename\Controller\Adminhtml\Controllername;

use Magento\Backend\App\Action;
use Magento\Framework\Controller\ResultFactory;

class Edit extends \Magento\Backend\App\Action
{
    /**

     * Authorization level of a basic admin session
     *
     * @see _isAllowed()
     */
    const ADMIN_RESOURCE = 'Vendor_Modulename::save';

    /**
     * @var \Magento\Framework\Registry
     */
    private $coreRegistry;

    /**
     * @var \Vendor\Modulename\Model\EntityFactory
     */
    private $entityFactory;

    /**
     * @param \Magento\Backend\App\Action\Context $context
     * @param \Magento\Framework\Registry $coreRegistry,
     * @param \Vendor\Modulename\Model\EntityFactory $entityFactory
     */
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\Registry $coreRegistry,
        \Vendor\Modulename\Model\EntityFactory $entityFactory
    ) {
        parent::__construct($context);
        $this->coreRegistry = $coreRegistry;
        $this->entityFactory = $entityFactory; 
       //die("test reached controller constructor"); # This get printed on browser          
    }

    /**
     * Mapped Entity List page.
     * @return \Magento\Backend\Model\View\Result\Page
     */
    public function execute()
    {
        //die("test reached controller function"); # Unable to print on browser , just redirects it to Dashboard
        $rowId = (int) $this->getRequest()->getParam('id');
        $rowData = $this->entityFactory->create();
        /** @var \Magento\Backend\Model\View\Result\Page $resultPage */
        if ($rowId) {
            $rowData = $rowData->load($rowId);
            //$rowTitle = $rowData->getTitle();
            if (!$rowData->getEntityId()) {
                $this->messageManager->addError(__('row data no longer exist.'));
                $this->_redirect('*/*/index');
                return;
            }
        }

        $this->coreRegistry->register('row_data', $rowData);
        $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
        $title = "Entity Information";
        $resultPage->getConfig()->getTitle()->prepend($title);
        return $resultPage;
    }


}

Note

  • Read die() inside the constructot and execute methods.

  • It works fine when I disabled Secret Key to URLs.

I aslo define rules for Vendor_Modulename::entity and Vendor_Modulename::save into access control list using acl.xml

All answers are welcomed.

0

Although I left this issue and continued my work after disabled secret key from admin. But later when I review my code I found that I provided different values for routeid and frontName in routes.xml under the /etc/adminhtml dir.

I wonder, No where is written that it is mandatory to provide same values for both route attributes. If both are need to be same then why should use different attributes it could be a single attribute.

and now this module(CRUD operation in Custom Module) working fine

0

I found that I provided different values for routeid and frontName in routes.xml under the /etc/adminhtml dir.

Yes, this is the answer. I can't vote because I don't have enough reputation, but I wanted to confirm that this is the problem so other people don't waste 5 hours debugging the core code.

The route's id and frontName MUST be identical. This implements some "rules" that I did not find anywhere in the documentation (please tell me if I am wrong and there is so I can rectify this affirmation): The layout action's xml must follow the naming rule:

<route_id||frontName>_<sub_controller_directory_of_your_route>_<action_name>

The same goes for the component xml.

The component name is the component's xml name.

Example:

Your route id = frontName = "foo"
Vendor/Module|
             |/Controller/Adminhtml/Bar|
             |                         |
             |                         |/Grid.php
             |                         |/Edit.php
             |
             |/view/adminhtml|
                             |/layout|
                                     |
                                     |/foo_bar_grid.xml
                                     |/foo_bar_edit.xml
                             |
                             |/ui_component|
                                           |
                                           |/foo_bar_grid.xml
                                           |/foo_bar_form.xml

And your url's are:

  • foo/bar/grid
  • foo/bar/edit

And the uiComponent name's are:

  • foo_bar_grid
  • foo_bar_form

Now when you're trying to go to your form's edit url you won't be redirected to dashboard because of the wrong secret key.

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.