3

I have created admin grid for Image Slider in backend and need to add backend form for that grid.

If I click Add New slide or edit button, it needs to show a form. So Suggest me, how to create a backend form and how to link it with the grid?

1 Answer 1

8

If you just need to create an admin form, have a look at here.

https://www.pierrefay.com/magento2-training/form-component-backend-crud-admin.html

To create our Form, we will first create the newAction action in our controller like this:

Pfay/Contacts/Controller/Adminhtml/Contact/NewAction.php

<?php
namespace Pfay\Contacts\Controller\Adminhtml\Test;
use Magento\Backend\App\Action;
use Pfay\Contacts\Model\Contact as Contact;

class NewAction extends \Magento\Backend\App\Action
{
    /**
     * Edit A Contact Page
     *
     * @return \Magento\Backend\Model\View\Result\Page|\Magento\Backend\Model\View\Result\Redirect
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    public function execute()
    {
        $this->_view->loadLayout();
        $this->_view->renderLayout();

        $contactDatas = $this->getRequest()->getParam('contact');
        if(is_array($contactDatas)) {
            $contact = $this->_objectManager->create(Contact::class);
            $contact->setData($contactDatas)->save();
            $resultRedirect = $this->resultRedirectFactory->create();
            return $resultRedirect->setPath('*/*/index');
        }
    }
}

We load and then display the layout that will contain the form. We check if we receive the parameter "contact" (if the form is sent), if yes then we save the contact in the database . Logically, we will now create the layout

Pfay/Contacts/view/adminhtml/layout/contacts_test_newaction.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="contacts_test_edit"/>
    <body/>
</page>

In this layout, we just tell him to look for our layout contacts_text_edit. We create the layout file for editing

Pfay/Contacts/view/adminhtml/layout/contacts_test_edit.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="styles"/>
    <update handle="editor"/>
    <body>
        <referenceContainer name="content">
            <uiComponent name="pfay_contacts_form"/>
        </referenceContainer>
    </body>
</page>

Creating the file uiComponent for creation our form in magento2 Here it is said to load a uiComponent named "pfay_contacts_form", ( remember we did the same for the grid in the previous tutorial). We will, therefore, create the form in this uiComponent form. So let's create our uiComponent file for our form

app/code/Pfay/Contacts/view/adminhtml/ui_component/pfay_contacts_form.xml

<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">pfay_contacts_form.contacts_form_data_source</item>
            <item name="deps" xsi:type="string">pfay_contacts_form.contacts_form_data_source</item>
        </item>
        <item name="label" xsi:type="string" translate="true">Sample Form</item>
        <item name="layout" xsi:type="array">
            <item name="type" xsi:type="string">tabs</item>
        </item>

        <item name="buttons" xsi:type="array">
            <item name="back" xsi:type="string">Pfay\Contacts\Block\Adminhtml\Contact\Edit\BackButton</item>
            <item name="delete" xsi:type="string">Pfay\Contacts\Block\Adminhtml\Contact\Edit\DeleteButton</item>
            <item name="reset" xsi:type="string">Pfay\Contacts\Block\Adminhtml\Contact\Edit\ResetButton</item>
            <item name="save" xsi:type="string">Pfay\Contacts\Block\Adminhtml\Contact\Edit\SaveButton</item>
        </item>
    </argument>

    <dataSource name="contacts_form_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Pfay\Contacts\Model\Contact\DataProvider</argument>
            <argument name="name" xsi:type="string">contacts_form_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">pfay_contacts_id</argument>
            <argument name="requestFieldName" xsi:type="string">id</argument>
        </argument>
        <argument name="data" xsi:type="array">
            <item name="js_config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>
            </item>
        </argument>
    </dataSource>

    <fieldset name="contact">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="label" xsi:type="string" translate="true">Sample Fieldset</item>
            </item>
        </argument>

        <!-- This field represents form id and is hidden -->
        <field name="pfay_contact_id">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="visible" xsi:type="boolean">false</item>
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="source" xsi:type="string">contact</item>
                </item>
            </argument>
        </field>

        <!-- This field has data type 'text' and standard 'input' form element and looks like input -->
        <field name="name">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string">Name</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="source" xsi:type="string">contact</item>
                </item>
            </argument>
        </field>


        <!-- This field has data type 'text' and standard 'input' form element and looks like input -->
        <field name="email">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string">Email</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="source" xsi:type="string">contact</item>
                </item>
            </argument>
        </field>

    </fieldset>
</form>

The datasource of our magento2 form takes here our class "Pfay\Contacts\Model\Contact\DataProvider" so we will create it. So create

app/code/Pfay/Contacts/Model/Contact/DataProvider.php

<?php
namespace Pfay\Contacts\Model\Contact;

use Pfay\Contacts\Model\ResourceModel\Contact\CollectionFactory;
use Pfay\Contacts\Model\Contact;

class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
{
    /**
     * @param string $name
     * @param string $primaryFieldName
     * @param string $requestFieldName
     * @param CollectionFactory $contactCollectionFactory
     * @param array $meta
     * @param array $data
     */
    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        CollectionFactory $contactCollectionFactory,
        array $meta = [],
        array $data = []
    ) {
        $this->collection = $contactCollectionFactory->create();
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
    }

    public function getData()
    {
        if (isset($this->loadedData)) {
            return $this->loadedData;
        }

        $items = $this->collection->getItems();
        $this->loadedData = array();
        /** @var Contact $contact */
        foreach ($items as $contact) {
            // our fieldset is called "contact" or this table so that magento can find its datas:
            $this->loadedData[$contact->getId()]['contact'] = $contact->getData();
        }

        return $this->loadedData;

    }
}

It is this file that allows our fields to be automatically mapped to the database. The so-called "dataBinding". Here we called our fieldset "contact", so we pass our Contact object in the loadedData array that we return. Configuring our form buttons Under magento2, in the forms, we define classes for buttons like what we did in our uiComponent:

 <item name="buttons" xsi:type="array">
        <item name="back" xsi:type="string">Pfay\Contacts\Block\Adminhtml\Contact\Edit\BackButton</item>
        <item name="delete" xsi:type="string">Pfay\Contacts\Block\Adminhtml\Contact\Edit\DeleteButton</item>
        <item name="reset" xsi:type="string">Pfay\Contacts\Block\Adminhtml\Contact\Edit\ResetButton</item>
        <item name="save" xsi:type="string">Pfay\Contacts\Block\Adminhtml\Contact\Edit\SaveButton</item>
    </item>

We will create our files: Create a GenericButton: The GenericButton is the element that allows other buttons to exist. This is the base that extends the other buttons.

app/code/Pfay/Contacts/Block/Adminhtml/Contact/Edit/GenericButton.php

<?php
namespace Pfay\Contacts\Block\Adminhtml\Contact\Edit;

use Magento\Search\Controller\RegistryConstants;

/**
 * Class GenericButton
 */
class GenericButton
{
    /**
     * Url Builder
     *
     * @var \Magento\Framework\UrlInterface
     */
    protected $urlBuilder;

    /**
     * Registry
     *
     * @var \Magento\Framework\Registry
     */
    protected $registry;

    /**
     * Constructor
     *
     * @param \Magento\Backend\Block\Widget\Context $context
     * @param \Magento\Framework\Registry $registry
     */
    public function __construct(
        \Magento\Backend\Block\Widget\Context $context,
        \Magento\Framework\Registry $registry
    ) {
        $this->urlBuilder = $context->getUrlBuilder();
        $this->registry = $registry;
    }

    /**
     * Return the synonyms group Id.
     *
     * @return int|null
     */
    public function getId()
    {
        $contact = $this->registry->registry('contact');
        return $contact ? $contact->getId() : null;
    }

    /**
     * Generate url by route and parameters
     *
     * @param   string $route
     * @param   array $params
     * @return  string
     */
    public function getUrl($route = '', $params = [])
    {
        return $this->urlBuilder->getUrl($route, $params);
    }
}

Create a button to save our magento2 form Create the file

app/code/Pfay/Contacts/Block/Adminhtml/Contact/Edit/BackButton.php

In which you just configure the label of the button, the associated event and the form-role that automatically triggers events js for magento2.

<?php
namespace Pfay\Contacts\Block\Adminhtml\Contact\Edit;

use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;

/**
 * Class BackButton
 */
class BackButton extends GenericButton implements ButtonProviderInterface
{
    /**
     * @return array
     */
    public function getButtonData()
    {
        return [
            'label' => __('Back'),
            'on_click' => sprintf("location.href = '%s';", $this->getBackUrl()),
            'class' => 'back',
            'sort_order' => 10
        ];
    }

    /**
     * Get URL for back (reset) button
     *
     * @return string
     */
    public function getBackUrl()
    {
        return $this->getUrl('*/*/');
    }
}

Create a button to delete an object using our form Then create the file to delete an item from our formular

app/code/Pfay/Contacts/Block/Adminhtml/Contact/Edit/DeleteButton.php

Here it is more or less pariel but for the suppression:

<?php
namespace Pfay\Contacts\Block\Adminhtml\Contact\Edit;

use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;

/**
 * Class DeleteButton
 */
class DeleteButton extends GenericButton implements ButtonProviderInterface
{
    /**
     * @return array
     */
    public function getButtonData()
    {
        $data = [];
        if ($this->getId()) {
            $data = [
                'label' => __('Delete Contact'),
                'class' => 'delete',
                'on_click' => 'deleteConfirm(\''
                    . __('Are you sure you want to delete this contact ?')
                    . '\', \'' . $this->getDeleteUrl() . '\')',
                'sort_order' => 20,
            ];
        }
        return $data;
    }

    /**
     * @return string
     */
    public function getDeleteUrl()
    {
        return $this->getUrl('*/*/delete', ['pfay_contacts_id' => $this->getId()]);
    }
}

Create a reset button to reset our magento2 form

app/code/Pfay/Contacts/Block/Adminhtml/Contact/Edit/ResetButton.php

<?php
namespace Pfay\Contacts\Block\Adminhtml\Contact\Edit;

use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;

/**
 * Class ResetButton
 */
class ResetButton implements ButtonProviderInterface
{
    /**
     * @return array
     */
    public function getButtonData()
    {
        return [
            'label' => __('Reset'),
            'class' => 'reset',
            'on_click' => 'location.reload();',
            'sort_order' => 30
        ];
    }
}

Create a reset button to save our form

app/code/Pfay/Contacts/Block/Adminhtml/Contact/Edit/SaveButton.php

<?php
namespace Pfay\Contacts\Block\Adminhtml\Contact\Edit;

use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;

/**
 * Class SaveButton
 */
class SaveButton extends GenericButton implements ButtonProviderInterface
{
    /**
     * @return array
     */
    public function getButtonData()
    {
        return [
            'label' => __('Save Contact'),
            'class' => 'save primary',
            'data_attribute' => [
                'mage-init' => ['button' => ['event' => 'save']],
                'form-role' => 'save',
            ],
            'sort_order' => 90,
        ];
    }
}

And here are !! Our buttons are created and theoretically, everything should work :) Create our delete action We create our delete action to remove an object from the Magento grid like this:

<?php
namespace Pfay\Contacts\Controller\Adminhtml\Test;
use Pfay\Contacts\Model\Contact as Contact;
use Magento\Backend\App\Action;

class Delete extends \Magento\Backend\App\Action
{
    public function execute()
    {
        $id = $this->getRequest()->getParam('id');

        if (!($contact = $this->_objectManager->create(Contact::class)->load($id))) {
            $this->messageManager->addError(__('Unable to proceed. Please, try again.'));
            $resultRedirect = $this->resultRedirectFactory->create();
            return $resultRedirect->setPath('*/*/index', array('_current' => true));
        }
        try{
            $contact->delete();
            $this->messageManager->addSuccess(__('Your contact has been deleted !'));
        } catch (Exception $e) {
            $this->messageManager->addError(__('Error while trying to delete contact: '));
            $resultRedirect = $this->resultRedirectFactory->create();
            return $resultRedirect->setPath('*/*/index', array('_current' => true));
        }

        $resultRedirect = $this->resultRedirectFactory->create();
        return $resultRedirect->setPath('*/*/index', array('_current' => true));
    }
}

Here is another tutorial for your reference. https://webkul.com/blog/create-ui-form-magento2-part-1/

5
  • @Jayashree what problem are you encountered in given tutorials? Commented Nov 8, 2017 at 5:38
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
    – Piyush
    Commented Nov 8, 2017 at 5:44
  • @Piyush I forgot it :) Thank you for your suggestion. Commented Nov 8, 2017 at 6:04
  • Thank you, I have created Backend form. But one more doubt , How to save backend form data in database
    – Jaisa
    Commented Nov 9, 2017 at 12:23
  • 2
    OK, so where is "Pfay\Contacts\Model\ResourceModel\Contact\CollectionFactory" and "Pfay\Contacts\Model\Contact.php"? (example code will not deploy without them)
    – Scott
    Commented Jun 20, 2018 at 19:01

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.