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.
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.
Follow these steps to add a form to your module:
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; } }
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; } }
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); } }
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; } }
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.
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 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: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 datalabel
: This is the text that is used as a labeltitle
: This is the text that is used as the field title parameterclass
: This is the optional class for the input field, which can be used for form validationrequired
: This is optional. This is set if a field is required to have data.value
: This is the value used for select/multiselectafter
: 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.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(), ] );
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();
3.133.134.17