Preface

The UI component is designed for rendering a User Interface in a simple and flexible way.  It enables a connection between the UI  visual elements and the related data process submitted by users.

In this Magento Developer Guide, I will guide you on how to use the UI component to create UI Form in Magento 2.

Prerequisites

  • Set up module
  • Set up table
  • Set up 3 files: model, resourcemodel, and collection
  • Set up the controller and layout filet. In the layout file, a reference to a file ui component is ui_component/my_form.xml

Create UI Form

Create layout file:

  • File name: <routes>_<controller>_<action>.xml
  • Sample Code:
Magenest/MyForm/view/adminhtml/ layout/magenest_myform_index.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"> 
<body>
<referenceContainer name="content"> 
<uiComponent name="my_form" /> 
</referenceContainer> 
</body> 
</page>

Create the corresponding ui_component file named my_form.xml

  • Sample Code: 
Magenest/MyForm/view/adminhtml/ui_component/my_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">my_form.my_form_data_source</item>
</item>
<item name="label" xsi:type="string" translate="true">Information</item>
<item name="config" xsi:type="array">
<item name="dataScope" xsi:type="string">data</item>
<item name="namespace" xsi:type="string">my_form</item>
</item>
<item name="template" xsi:type="string">templates/form/collapsible</item>
</argument>
<settings>
       <buttons>
           <button name="save" class="Magenest\MyForm\Block\Adminhtml\Form\Edit\SaveButton"/>
           <button name="reset" class="Magenest\MyForm\Block\Adminhtml\Form\Edit\ResetButton"/>
           <button name="delete" class="Magenest\MyForm\Block\Adminhtml\Form\Edit\DeleteButton"/>
           <button name="back" class="Magenest\MyForm\Block\Adminhtml\Form\Edit\BackButton"/>
       </buttons>
       <namespace>magenest_form</namespace>
       <dataScope>data</dataScope>
       <deps>
           <dep>my_form.my_form_data_source</dep>
       </deps>
   </settings>
<dataSource name="my_form_data_source">
       <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>
       <settings>
           <submitUrl path="magenest/myform/save"/>
       </settings>
     <dataProvider class="Magenest\MyForm\UiComponent\DataProvider" name="my_form_data_source">
           <settings>
               <requestFieldName>id</requestFieldName>
               <primaryFieldName>id</primaryFieldName>
           </settings>
       </dataProvider>
   </dataSource>

<fieldset name="my_form_fieldset">
<settings>
   <collapsible>true</collapsible>
   <label>Fieldset Label</label>
</settings>
<field name="id" formElement="input">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="source" xsi:type="string">my_form</item>
</item>
</argument>
<settings>
   <dataType>text</dataType>
   <visible>false</visible>
   <dataScope>id</dataScope>
   <label>Id</label>
</settings>
</field>
<field name="name" formElement="input">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="source" xsi:type="string">my_form</item>
</item>
</argument>
<settings>
   <dataType>text</dataType>
   <visible>true</visible>
   <dataScope>name</dataScope>
   <label>Name</label>
</settings>
</field>
<field name="description" formElement="input">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="source" xsi:type="string">my_form</item>
</item>
</argument>
<settings>
   <dataType>text</dataType>
   <visible>true</visible>
   <dataScope>description</dataScope>
   <label>Description</label>
</settings>
</field>
</fieldset>
</form>
  • Result:
  • It includes 3 nodes: argument, dataSource, and fieldset.
    • Argument nodes need to declare the name as data, be able to set file templates (such as HTML or XHTML), file component (js), label, data provider, dependencies, data scope, namespace, etc.
    • DataSource node defines a data source, data source needn’t template, but it is still a component and needs to set a link to file component (js).
  • Besides, dataSource needs an argument whose name is dataProvider, this argument is a configurableObject (php object), dataProvider is used to retrieve data from the database.
  • Class dataProvider need to implement this interface: \Magento\Framework\

View\Element\UiComponent\DataProvider\DataProviderInterface.

  • The best is to extend this class: \Magento\Framework\

View\Element\UiComponent\DataProvider\DataProvider

  • In this class, we need add-on primaryFieldName parameters into __construct, requestFieldName corresponds to file my_form.xml. In addition, it is necessary to set the corresponding collection.
    • Fieldset node defines fields. Besides basic fields, a custom field can be written, set components, and template.

Other Files in my_form.xml:

4 button files: 4 button files can be declared with the following content:

Back Button: 

Magenest/MyForm/Block/Adminhtml/Form/Edit/BackButton.php
<?php 
namespace Magenest\MyForm\Block\Adminhtml\Form\Edit; 
use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; 
class BackButton extends GenericButton implements ButtonProviderInterface { 
public function getButtonData() { 
return [ 
'label' => __('Back'), 
'on_click' => sprintf("location.href= '%s';", $this->getBackUrl()), 
'class' => 'back', 
'sort_order' => 10 ]; 
} 
public function getBackUrl() { return $this->getUrl('*/*/'); } 
}

Delete Button:

Magenest/MyForm/Block/Adminhtml/Form/Edit/DeleteButton.php
<?php 
namespace Magenest\MyForm\Block\Adminhtml\Form\Edit; 
use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; 
class DeleteButton extends GenericButton implements ButtonProviderInterface { 
public function getButtonData(){ 
return [ 
'label' => __('Delete Contact'), 
'on_click' => 'deleteConfirm(\'' . __('Are you sure you want to delete this contact ?') . '\', \'' . $this->getDeleteUrl() . '\')', 
'class' => 'delete', 
'sort_order' => 20 
]; 
} 
public function getDeleteUrl() { 
$id = $this->request->getParam('id');
return $this->getUrl('*/*/delete', ['id' => $id]); 
} 
}

Reset Button:

Magenest/MyForm/Block/Adminhtml/Form/Edit/ResetButton.php
<?php 
namespace Magenest\MyForm\Block\Adminhtml\Form\Edit; 
use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; 
class ResetButton extends GenericButton implements ButtonProviderInterface { 
public function getButtonData() { 
return [ 
'label' => __('Reset'), 
'on_click' => 'javascript: location.reload();', 'class' => 'reset', 'sort_order' => 30 ]; 
} 
}

Save Button: 

Magenest/MyForm/Block/Adminhtml/Form/Edit/SaveButton.php
<?php 
namespace Magenest\MyForm\Block\Adminhtml\Contact\Edit; 
use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
class SaveButton extends GenericButton implements ButtonProviderInterface { 
public function getButtonData() { 
return [ 
'label' => __('Save Contact'), 
'class' => 'save primary', 
'data_attribute' => [ 
'mage-init' => [
'button' => ['event' => 'save']], 
'form-role' => 'save', 
], 
'sort_order' => 90 ];
}
public function getSaveUrl() { 
return $this->getUrl('*/*/save', []) ; 
} 
}

Conclusions

I hope that creating a form using the UI component in Magento 2 will become easier after you read the instructions in this blog.

If you have any questions, feel free to contact us via support@magenest.com.