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.

Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top