Magento2 – How to Create Custom ‘Duplicate’ Buttons for Adminhtml Form

adminhtmlgridmagento2

How to create custom "Duplicate" buttons for Adminhtml Form in Magento2?

I need to create a duplicate button in adminhtml form just like product edit page in admin side.

Best Answer

Inside your form container add button (in the _construct method):

class Edit extends \Magento\Backend\Block\Widget\Form\Container
{
//....
    /**
     * Initialize form
     * Add standard buttons
     * Add "Save and Continue" button
     *
     * @return void
     */
    protected function _construct()
    {
    //.....


        // Here we check is that model already exists
        if ($this->getRequest()->getParam('id')) {
            // creating duplication url
            $duplicateUrl = $this->_urlBuilder->getUrl(
                static::URL_PATH_DUPLICATE, // path to the duplicate action, string like 'module_route/controller/action'
                [
                    // our model's id, id - is parameter from the request
                    'id' => $this->getRequest()->getParam('id'),
                ]
            );
            $this->buttonList->add(
                'duplicate',
                [
                    'class' => 'save',
                    'label' => __('Duplicate'),
                    'onclick' => 'setLocation("' . $duplicateUrl . '")'
                ],
                12 // sort order
            );
        }

Add controller's action:

namespace Vendor\Module\Controller\Adminhtml\Some\Thing;

class Duplicate extends \Magento\Backend\App\Action
{
    /**
     * Create model duplicate
     *
     * @return \Magento\Backend\Model\View\Result\Redirect
     */
    public function execute()
    {
        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
        $resultRedirect = $this->resultRedirectFactory->create();
        /** @var \Vendor\Module\Model\Name $model */
        $model = $this->coreRegistry->registry('your_model_unique_identifier');
        try {
            $newModel = clone $model; // clone
            $newModel->setId(null); // remove id
            $newModel->isObjectNew(true); // set object as new
            $newModel->setData('is_active', 0); // set another data if needed
            $newModel->getResource()->save($newModel); // save new model (clone)
            // add success message and redirect to the edit form with the newly created model
            $this->messageManager->addSuccessMessage(__('You duplicated the model.'));
            $resultRedirect->setPath('*/*/edit', ['_current' => true, 'id' => $newModel->getId()]);
        } catch (\Exception $e) {
            // if something is going wrong: catch exception & redirect back
            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
            $this->messageManager->addErrorMessage($e->getMessage());
            $resultRedirect->setPath('*/*/edit', ['_current' => true]);
        }

        return $resultRedirect;
    }
}

Result should look like this:

result