Creating a backend form to add/edit data

If you want to add a new record or edit an existing record, it is possible to create a form to have a user friendly way to process the data. In this example, we will see how to create a form to edit an existing record. The path used to add a record will be as follows:

http://example.com/admin/sample/demolist/new/

This will require the controller name to be new, but as this is a reserved word in PHP, the class name used will be newAction. The execute function is not only used to add a new record, but it can also be used to edit an existing record. In the following code, only the execute action is shown; see the sample code for the complete source.

Getting ready

In this recipe, we will add the option to add or edit records; for this, the route used in the previous chapter is used, only new controllers and blocks are shown.

How to do it…

Follow these steps to add a form to your module:

  1. Add the controller:

    Controller/Adminhtml/Demolist/NewAction.php

    <?php
    namespace GenmatoSampleControllerAdminhtmlDemolist;
    use MagentoBackendAppAction;
    class NewAction extends Action
    {
      public function execute()
      {
        $demoId = $this->getRequest()->getParam('demo_id');
        $this->_coreRegistry->register('current_demo_id', $demoId);
    
        /** @var MagentoBackendModelViewResultPage $resultPage */
        $resultPage = $this->resultPageFactory->create();
        if ($demoId === null) {
          $resultPage->addBreadcrumb(__('New DemoList'), __('New DemoList'));
          $resultPage->getConfig()->getTitle()->prepend(__('New DemoList'));
        } else {
          $resultPage->addBreadcrumb(__('Edit DemoList'), __('Edit DemoList'));
          $resultPage->getConfig()->getTitle()->prepend(__('Edit DemoList'));
        }
        // Build the edit form
        $resultPage->getLayout()->addBlock('GenmatoSampleBlockAdminhtmlDemoEdit', 'demolist', 'content')
        ->setEditMode((bool)$demoId);
    
        return $resultPage;
      }
    }
  2. Create the Form container:

    Block/Adminhtml/Demo/Edit.php

    <?php
    namespace GenmatoSampleBlockAdminhtmlDemo;
    use MagentoBackendBlockWidgetFormContainer;
    class Edit extends Container
    {
      /**
      * Remove Delete button if record can't be deleted.
      *
      * @return void
      */
      protected function _construct()
      {
        $this->_objectId = 'demo_id';
        $this->_controller = 'adminhtml_demo';
        $this->_blockGroup = 'Genmato_Sample';
        parent::_construct();
        $demoId = $this->getDemoId();
        if (!$demoId) {
          $this->buttonList->remove('delete');
        }
      }
    
      /**
      * Retrieve the header text, either editing an existing record or creating a new one.
      *
      * @return MagentoFrameworkPhrase
      */
      public function getHeaderText()
      {
        $demoId = $this->getDemoId();
        if (!$demoId) {
          return __('New DemoList Item');
        } else {
          return __('Edit DemoList Item');
        }
      }
    
      public function getDemoId()
      {
        if (!$this->demoId) {
          $this->demoId=$this->coreRegistry->registry('current_demo_id');
        }
        return $this->demoId;
      }
    }
  3. Build the form by defining the fields and types that are used:

    Block/Adminhtml/Demo/Edit/Form.php

    <?php
    namespace GenmatoSampleBlockAdminhtmlDemoEdit;
    use MagentoCustomerControllerRegistryConstants;
    use MagentoBackendBlockWidgetFormGeneric;
    class Form extends Generic
    {
      /**
      * Prepare form for render
      *
      * @return void
      */
      protected function _prepareLayout()
      {
        parent::_prepareLayout();
    
        /** @var MagentoFrameworkDataForm $form */
        $form = $this->_formFactory->create();
    
        $demoId = $this->_coreRegistry->registry('current_demo_id');
        /** @var GenmatoSampleModelDemoFactory $demoData */
        if ($demoId === null) {
          $demoData = $this->demoDataFactory->create();
        } else {
          $demoData = $this->demoDataFactory->create()->load($demoId);
        }
    
        $yesNo = [];
        $yesNo[0] = 'No';
        $yesNo[1] = 'Yes';
    
        $fieldset = $form->addFieldset('base_fieldset', ['legend' => __('Basic Information')]);
    
        $fieldset->addField(
          'title',
          'text',
          [
            'name' => 'title',
            'label' => __('Title'),
            'title' => __('Title'),
            'required' => true
          ]
        );
    
        $fieldset->addField(
          'is_active',
          'select',
          [
            'name' => 'is_active',
            'label' => __('Active'),
            'title' => __('Active'),
            'class' => 'required-entry',
            'required' => true,
            'values' => $yesNo,
          ]
        );
    
        $fieldset->addField(
          'is_visible',
          'select',
          [
            'name' => 'is_visible',
            'label' => __('Visible'),
            'title' => __('Visible'),
            'class' => 'required-entry',
            'required' => true,
            'values' => $yesNo,
          ]
        );
    
        if ($demoData->getId() !== null) {
          // If edit add id
          $form->addField('demo_id', 'hidden', ['name' => 'demo_id', 'value' => $demoData->getId()]);
        }
    
        if ($this->_backendSession->getDemoData()) {
          $form->addValues($this->_backendSession->getDemoData());
          $this->_backendSession->setDemoData(null);
        } else {
          $form->addValues(
            [
              'id' => $demoData->getId(),
              'title' => $demoData->getTitle(),
              'is_active' => $demoData->getIsActive(),
              'is_visible' => $demoData->getIsVisible(),
            ]
          );
        }
    
        $form->setUseContainer(true);
        $form->setId('edit_form');
        $form->setAction($this->getUrl('*/*/save'));
        $form->setMethod('post');
        $this->setForm($form);
      }
    }
  4. Add the Save action controller, which is called when pressing the Submit button:

    Controller/Adminhtml/Demolist/Save.php

    <?php
    namespace GenmatoSampleControllerAdminhtmlDemolist;
    use MagentoBackendAppAction;
    class Save extends Action
    {
      /**
      * Save DemoList item.
      *
      * @return MagentoBackendModelViewResultPage|MagentoBackendModelViewResultRedirect
      */
      public function execute()
      {
        $id = $this->getRequest()->getParam('demo_id');
        $resultRedirect = $this->resultRedirectFactory->create();
        try {
          if ($id !== null) {
            $demoData = $this->demoFactory->create()->load((int)$id);
          } else {
            $demoData = $this->demoFactory->create();
          }
          $data = $this->getRequest()->getParams();
          $demoData->setData($data)->save();
    
          $this->messageManager->addSuccess(__('Saved DemoList item.'));
          $resultRedirect->setPath('sample/demolist');
        } catch (Exception $e) {
          $this->messageManager->addError($e->getMessage());
          $this->_getSession()->setDemoData($data);
    
          $resultRedirect->setPath('sample/demolist/edit', ['demo_id' => $id]);
        }
        return $resultRedirect;
      }
    }

How it works…

In the controller, the demo_id parameter is stored in the Magento registry; this makes the data available to retrieve in the same request in other blocks/models to do further processing with it. Additionally, the GenmatoSampleBlockAdminhtmlDemoEdit class is loaded. This class will generate the container for the form and load the GenmatoSampleBlockAdminhtmlDemoEditForm class that will generate the form to be shown.

Building the form

Every form is built from the following:

$form = $this->_formFactory->create();

As it is not possible to add fields to a form directly, you need to create a fieldset first. It is possible to add multiple fieldsets to a single form and assign multiple form fields to a fieldset. To create a fieldset, use the following command:

$fieldset = $form->addFieldset('[name]', ['legend' => __([heading])]);

Adding a form field

Adding a form field to the fieldset is done as follows:

$fieldset->addField([elementId], [type], [config], [after]);

This method has the following parameters:

  • elementId: This is the unique name of the form field element.
  • type: This defines the type of element that is used as the input field. This can be your own class that implements the MagentoFrameworkDataFormElementAbstractElement class or one of the following:
    • button
    • checkbox
    • checkboxes
    • column
    • date
    • editablemultiselect
    • editor
    • fieldset
    • file
    • gallery
    • hidden
    • image
    • imagefile
    • label
    • link
    • multiline
    • multiselect
    • note
    • obscure
    • password
    • radio
    • radios
    • reset
    • select
    • submit
    • text
    • textarea
    • time

    These input types are rendered from the classes found under the MagentoFrameworkDataFormElement directory.

  • config: This is an array of extra configuration data; some of the options are as follows:
    • name: This is the name of the element from the data model that holds the data
    • label: This is the text that is used as a label
    • title: This is the text that is used as the field title parameter
    • class: This is the optional class for the input field, which can be used for form validation
    • required: This is optional. This is set if a field is required to have data.
    • value: This is the value used for select/multiselect
  • after: This is the optional parameter to specify where the form field needs to be placed; use elementId of the form field that you want to place this field after.

Loading the data

In order to display the data currently stored for the record that we want to edit, the stored demo_id is retrieved from the registry:

$demoId = $this->_coreRegistry->registry('current_demo_id');

Next, we check whether there is a valid value stored as demoId and load the data from the database (or just set an empty object):

/** @var GenmatoSampleModelDemoFactory $demoData */
if ($demoId === null) {
  $demoData = $this->demoDataFactory->create();
} else {
  $demoData = $this->demoDataFactory->create()->load($demoId);
}

Now that the data is loaded, it is possible to set this data to the form fields:

$form->addValues(
  [
    'id' => $demoData->getId(),
    'title' => $demoData->getTitle(),
    'is_active' => $demoData->getIsActive(),
    'is_visible' => $demoData->getIsVisible(),
  ]
);

Saving the data

When submitting the form to save the data, the action and method should be set to the URL that handles the save action:

$form->setAction($this->getUrl('*/*/save'));
$form->setMethod('post');

The URL */*/save maps to the Controller/Adminhtml/Demolist/Save controller and will handle the save action.

In the controller, we first load the current record to load all the current values:

if ($id !== null) {
  $demoData = $this->demoFactory->create()->load((int)$id);
} else {
  $demoData = $this->demoFactory->create();
}

Next, we retrieve the submitted data, store it in the loaded object, and save the object:

$data = $this->getRequest()->getParams();
$demoData->setData($data)->save();
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.134.17