3

I have added a custom button on the Sales Order View page in Admin using Plugin.

When that button clicks it should open a popup with form and when I submit that form then this information should pass to the controller to process that data and again redirect the same order page.

I have added a button using the below plugin. Please help me out to achieve the above requirement.

Plugin File /var/www/magento/app/code/MyCompany/Customadmin/Plugin/CreateWarrantyOrder.php

<?php

namespace MyCompany\Customadmin\Plugin;

/**
 * Class View
 *
 * @package MyCompany\Customadmin\Plugin\CreateWarrantyOrder
 */
class CreateWarrantyOrder
{

    public function beforeSetLayout(
        \Magento\Sales\Block\Adminhtml\Order\View $subject,
        $layout
    ) {
        $subject->addButton(
            'sendordersms',
            [
                'label' => __('Create Warranty Order'),
                'onclick' => "",
                'class' => 'action-default action-warranty-order',
            ]
        );
        return [$layout];
    }

    public function afterToHtml(
        \Magento\Sales\Block\Adminhtml\Order\View $subject,
        $result
    ) {
        if($subject->getNameInLayout() == 'sales_order_edit'){
            $customBlockHtml = $subject->getLayout()->createBlock(
                \MyCompany\Customadmin\Block\Adminhtml\Order\ModalBox::class,
                $subject->getNameInLayout().'_modal_box'
            )->setTemplate('MyCompany_Customadmin::order/modalbox.phtml')
                ->toHtml();

            return $result.$customBlockHtml;
        }
        return $result;
    }
}

Modalbox - /var/www/magento/app/code/MyCompany/Customadmin/view/adminhtml/templates/order/modalbox.phtml

<?php
/**
 * @var $block \MyCompany\Customadmin\Block\Adminhtml\Order\ModalBox
 */
echo $block->getInfo();
$controllerUrl = $block->getUrl("customadmin/adminhtml/order");
?>
<div id="popup-modal" style="display: none">

    <form action="<?php echo $controllerUrl; ?>" method="POST">
        <input name="firstname" type="text">
        <input name="lastname" type="text">
        <input name="phone" type="text">
        <input type="submit" value="Submit">
        <input type="reset" value="Clear">
    </form>
</div>

<script>
    require(
        [
            'jquery',
            'Magento_Ui/js/modal/modal'
        ],
        function (
            $,
            modal
        ) {
            var options = {
                type: 'popup',
                responsive: true,
                innerScroll: true,
                title: 'Create Order Warranty',
                modalClass: 'custom-modal',
                buttons: [{
                    text: $.mage.__('Close'),
                    class: '',
                    click: function () {
                        this.closeModal();
                     }
                }]
            };

            var popup = modal(options, $('#popup-modal'));
            $("#sendordersms").click(function() {
                $("#popup-modal").modal('openModal');
            });
        }

    );
</script>

Block File /var/www/magento/app/code/MyCompany/Customadmin/Block/Adminhtml/Order/ModalBox.php

<?php

namespace MyCompany\Customadmin\Block\Adminhtml\Order;

/**
 * Class ModalBox
 *
 * @package MyCompany\Customadmin\Block\Adminhtml\Order
 */
class ModalBox extends \Magento\Backend\Block\Template
{

    /**
     * Constructor
     *
     * @param \Magento\Backend\Block\Template\Context  $context
     * @param array $data
     */
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        array $data = []
    ) {
        parent::__construct($context, $data);
    }

    /**
     * @return string
     */
    public function getInfo()
    {
        $firstname = $this->getRequest()->getParam('firstname');

        \Magento\Framework\App\ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class)->debug('ModalBox data >>> ' . $firstname);

        return __('Hello Developer! This how to get the ');
    }
}

Controller File - /var/www/magento/app/code/MyCompany/Customadmin/Controller/Adminhtml/Order/OrderController.php

<?php
namespace MyCompany\Customadmin\Controller\Adminhtml\Order;

class OrderController extends \Magento\Backend\App\Action
{
    /**
     * Hello test controller page.
     *
     * @return \Magento\Backend\Model\View\Result\Page
     */
    /**
     * Check Permission.
     *
     * @return bool
     */
    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('MyCompany_Customadmin::ordercontroller');
    }


    public function execute()
    {
        if ($order = $this->_initOrder()) {
            try {

                 $firstname = $this->getRequest()->getParam('firstname');

                \Magento\Framework\App\ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class)->debug('OrderController data >>> ' . $firstname);


                /*$connection = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Framework\App\ResourceConnection')->getConnection();
                $sql = "UPDATE sales_order SET order_file_sent = '0' WHERE entity_id = '".$order->getEntityId()."'" ; 
                $connection->query($sql) ;*/



            } catch (\Exception $e) {

                $this->messageManager->addError(__('Failed '));
                $this->logger->critical($e);

            }

            $this->messageManager->addSuccess(__('Success'));
            return $this->resultRedirectFactory->create()->setPath(
                'sales/order/view',
                [
                    'order_id' => $order->getEntityId()
                ]
            );
        }

        return $this->resultRedirectFactory->create()->setPath('sales/*/');
    }

}

Routes.xml /var/www/magento/app/code/MyCompany/Customadmin/etc/adminhtml/routes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
    <router id="admin">
        <route id="customadmin" frontName="customadmin">
            <module name="MyCompany_Customadmin"/>
        </route>
    </router>
</config>

di.xml /var/www/magento/app/code/MyCompany/Customadmin/etc/adminhtml/di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Sales\Block\Adminhtml\Order\View">
        <plugin name="CreateWarrantyOrder" type="MyCompany\Customadmin\Plugin\CreateWarrantyOrder"/>
    </type>
</config>
4

If you want to call a pop on your custom button click then you have to create a modal box .

  • For create a modal box, you need to create a child block of Magento\Sales\Block\Adminhtml\Order\View .
  • On that child build a modal box with form
  • After that add this child Block HTML out with Magento\Sales\Block\Adminhtml\Order\View out using toHtml()plugin. after Plugi afterToHtml().

Create a Block class and a phtml to render the popup and form

Block Class: app\code\MyCompany\Customadmin\Block\Adminhtml\Order\ModalBox and code Will be like:

   <?php


namespace StackExchange\MagentoTest\Block\Adminhtml\Order;

/**
 * Class ModalBox
 *
 * @package StackExchange\MagentoTest\Block\Adminhtml\Order
 */
class ModalBox extends \Magento\Backend\Block\Template
{

    /**
     * Constructor
     *
     * @param \Magento\Backend\Block\Template\Context  $context
     * @param array $data
     */
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        array $data = []
    ) {
        parent::__construct($context, $data);
    }

    /**
     * @return string
     */
    public function getInfo()
    {
        //Your block cod
        return __('Hello Developer! This how to get the ');
    }
    public function getFormUrl()
    {
        $orderId = false;
        if($this->hasData('order')){
            $orderId = $this->getOrder()->getId();
        }
        return $this->getUrl('magentotest/order/order',[
            'order_id' => $orderId
        ]);
    }
}
Phtml code is below and the location is:

Location: app/code/MyCompany/Customadmin/view/adminhtml/templates/order/modalbox.phtml

Code

   <?php
/**
 * @var $block \StackExchange\MagentoTest\Block\Adminhtml\Order\ModalBox
 */

?>
<div id="popup-modal" style="display: none">

    <form action="<?= $block->escapeUrl($block->getFormUrl())?>" method="post"
          id="order-view-add-warranty-form">
        <input name="firstname" type="text">
        <input name="lastname" type="text">
        <input name="phone" type="text">
        <input name="bookingTime" type="date">

        <input type="button" value="Submit" id="order-view-add-warranty">
    </form>
</div>

<script>
    require(
        [
            'jquery',
            'Magento_Ui/js/modal/modal'
        ],
        function (
            $,
            modal
        ) {
            var options = {
                type: 'popup',
                responsive: true,
                innerScroll: true,
                title: 'Modal Title',
                modalClass: 'custom-modal',
                buttons: [{
                    text: $.mage.__('Close'),
                    class: '',
                    click: function () {
                        this.closeModal();
                     }
                }]
            };

            var popup = modal(options, $('#popup-modal'));
            $("#sendordersms").click(function() {
                $("#popup-modal").modal('openModal');
            });

            $('#order-view-add-warranty').click(function () {
                $('#order-view-add-warranty-form').append($('<input>', {
                    'name': 'form_key',
                    'value': window.FORM_KEY,
                    'type': 'hidden'
                }));
                $('#order-view-add-warranty-form').submit();

            });

        }

    );
</script>

Update a plugin class MyCompany\Customadmin\Plugin\CreateWarrantyOrder

Add new after plugin on toHtml() on this class and append MyCompany\Customadmin\Block\Adminhtml\Order\ModalBox block output using this after plugin afterToHtml. And code:

<?php


namespace StackExchange\MagentoTest\Plugin\Magento\Sales\Block\Adminhtml\Order;

/**
 * Class View
 *
 * @package StackExchange\MagentoTest\Plugin\Magento\Sales\Block\Adminhtml\Order
 */
class View
{

    public function beforeSetLayout(
        \Magento\Sales\Block\Adminhtml\Order\View $subject,
        $layout
    ) {
        $subject->addButton(
            'sendordersms',
            [
                'label' => __('Create Warranty Order'),
                'onclick' => "",
                'class' => 'action-default action-warranty-order',
            ]
        );
        return [$layout];
    }

    public function afterToHtml(
        \Magento\Sales\Block\Adminhtml\Order\View $subject,
        $result
    ) {
        if($subject->getNameInLayout() == 'sales_order_edit'){
            $customBlockHtml = $subject->getLayout()->createBlock(
                \StackExchange\MagentoTest\Block\Adminhtml\Order\ModalBox::class,
                $subject->getNameInLayout().'_modal_box'
            )->setOrder($subject->getOrder())
                ->setTemplate('StackExchange_MagentoTest::order/modalbox.phtml')
                ->toHtml();
            return $result.$customBlockHtml;
        }
        return $result;
    }
}

Changs at Controller code

   <?php

namespace StackExchange\MagentoTest\Controller\Adminhtml\Order;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\View\Result\Page;
use Magento\Framework\View\Result\PageFactory;
use Magento\Sales\Controller\Adminhtml\Order as AdminOrder;

class Order extends AdminOrder implements HttpPostActionInterface
{
    /**
     * Changes ACL Resource Id
     */
    const ADMIN_RESOURCE = 'Magento_Sales::hold';
    /**
     * @inheritDoc
     */
    public function execute()
    {
        $resultRedirect = $this->resultRedirectFactory->create();

        $order = $this->_initOrder();
        if ($order) {
            $post = $this->getRequest()->getPostValue();

            echo "<pre>";
            print_r($post);
            exit;
            $resultRedirect->setPath('sales/order/view', ['order_id' => $order->getId()]);
            return $resultRedirect;
        }
        $resultRedirect->setPath('sales/*/');
        return $resultRedirect;
    }
}

Above code are working on local. You have to changes class name and URL as per your requirement.

MOdule share at https://github.com/devamitbera/magento-stackexchange/blob/master/StackExchange-306851.zip

| improve this answer | |
  • I have created a child block as per this tutorial magento.stackexchange.com/questions/163562/…. But still not sure how can I link that phtml to button click – Rahul Mar 12 at 9:27
  • can you please provide some detail answer. – Rahul Mar 13 at 7:48
  • 1
    will do. it might be after few hrs – Amit Bera Mar 13 at 8:25
  • 1
    please check the answer carefully. I have mentioned this Block and template are responsible pop content render – Amit Bera Mar 16 at 11:21
  • 1
    i will help you... – Amit Bera Mar 17 at 11:50

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.