Adding input prefix in an admin form
-
29-09-2020 - |
Question
I'm trying to build a CRUD module for Magento 2 by using the ui components.
but I need to add a prefix for all my inputs in the form.
So if I add a field called name
I need the field name to actually be prefix[name]
.
Using the Magento\Framework\Data\Form
class to generate my fields worked great with
$form = $this->_formFactory->create();
$form->setHtmlIdPrefix('prefix_');
$form->setFieldNameSuffix('prefix');
But I want to do it via ui component xml.
Here is how my xml looks right now:
<?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">[namespace]_[module]_[entity]_form.[entity]_form_data_source</item>
<item name="deps" xsi:type="string">[namespace]_[module]_[entity]_form.[entity]_form_data_source</item>
</item>
<item name="label" xsi:type="string" translate="true">[Entity] Information</item>
<item name="config" xsi:type="array">
<item name="dataScope" xsi:type="string">data</item>
<item name="namespace" xsi:type="string">[namespace]_[module]_[entity]_form</item>
</item>
<item name="template" xsi:type="string">templates/form/collapsible</item>
<item name="buttons" xsi:type="array">
<item name="back" xsi:type="string">[Namespace]\[Module]\Block\Adminhtml\[Entity]\Edit\Buttons\Back</item>
<item name="delete" xsi:type="string">[Namespace]\[Module]\Block\Adminhtml\[Entity]\Edit\Buttons\Delete</item>
<item name="reset" xsi:type="string">[Namespace]\[Module]\Block\Adminhtml\[Entity]\Edit\Buttons\Reset</item>
<item name="save" xsi:type="string">[Namespace]\[Module]\Block\Adminhtml\[Entity]\Edit\Buttons\Save</item>
<item name="save_and_continue" xsi:type="string">[Namespace]\[Module]\Block\Adminhtml\[Entity]\Edit\Buttons\SaveAndContinue</item>
</item>
</argument>
<dataSource name="[entity]_form_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">[Namespace]\[Module]\Model\[Entity]\DataProvider</argument>
<argument name="name" xsi:type="string">[entity]_form_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">[entity]_id</argument>
<argument name="requestFieldName" xsi:type="string">[entity]_id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="submit_url" xsi:type="url" path="[namespace_module]/[entity]/save"/>
</item>
</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="[entity]">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string">[Entity] Information</item>
</item>
<item name="collapsible" xsi:type="boolean">true</item>
</argument>
<field name="[enitity]_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">[entity]</item>
<item name="dataScope" xsi:type="string">[entity]_id</item>
</item>
</argument>
</field>
<field name="name">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="dataType" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Name</item>
<item name="formElement" xsi:type="string">input</item>
<item name="source" xsi:type="string">[entity]</item>
<item name="sortOrder" xsi:type="number">10</item>
<item name="dataScope" xsi:type="string">name</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
</item>
</argument>
</field>
</fieldset>
</form>
This works nicely, and generates the add/edit form with a single field called name
but I don't know how to add the prefix.
Solution
How can I control dataScope?
If you want to control whole name of POST key (like prefix[name]
) on Field level then you'll interested in discard autocomposing it.
First of all how it composed? When a Field placed in chain Form1 > Fieldset1 > Fieldset2 > Field
, then Field gets POST key Form1[Fieldset1][Fieldset2][Field]
.
If you want to omit Fieldset1 from chain then you configure its dataScope
as empty sting. Examples:
Fieldset1.dataScope = ""
-> POST key is Form1[Fieldset2][Field]
.
Fieldset1.dataScope = ""
Fieldset2.dataScope = ""
-> POST key is Form1[Field]
.
Form1.dataScope = "data"
Fieldset1.dataScope = ""
Fieldset2.dataScope = ""
-> POST key is Field
.
Form1.dataScope = "data.prefix"
Fieldset1.dataScope = ""
Fieldset2.dataScope = ""
-> POST key is prefix[Field]
.
Form1.dataScope = "data"
Fieldset1.dataScope = ""
Fieldset2.dataScope = ""
Field.dataScope = "prefix.field2"
-> POST key is prefix[field2]
.
What does dataScope affect?
You should remember that dataScope
is not a POST key. It's a keychain from DataProvider object. In xml configuration there is <dataSource/>
tag. This tag configures who is provider data for form. Client side app produces DataProvider object and link every Field's value with some DataProvider's key. So string dataScope
just point to some DataProvider's key.
If you want to control Form's POST object it means that you want to control DataProvider's data structure also.