I've successfully created several customer extension attributes that display on the customer form and save and load data.
enter image description here

When I try to move these fields to a new custom tab on the customer admin page, they break. The source models still load, but the data isn't populated or saved. I can see when I inspect that the form name changes from customer['my_attribute'] to my_tab[my_attribute].
enter image description here

I suspect I need to change my UpgradeData.php script to use a custom form, but I'm having trouble finding resources on how to go about this.

Relevant snippet from UpgradeData.php:

        $exemptionTypeCode = 'my_exemption_type';
        $eavSetup->addAttribute(
            CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER,
            $exemptionTypeCode,
            [
                'group' => 'General',
                'type' => 'varchar',
                'label' => 'Exemption Type',
                'input' => 'select',

                'required' => false,
                'visible' => true,
                'user_defined' => true,
                'position' => 501,
                'system' => 0,
                'sort_order' => 50,
                'default' => 'non_exempt',

                'source' => 'Custom\Module\Model\Attribute\Source\CustomerExemptionType',
                'backend' => 'Custom\Module\Model\Attribute\Backend\CustomerExemptionType',
                'frontend' => 'Custom\Module\Model\Attribute\Frontend\CustomerExemptionType',
                'global' => 'Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL',

                'is_used_in_grid' => false,
                'is_visible_in_grid' => false,
                'is_filterable_in_grid' => false,
                'is_html_allowed_on_front' => true,
                'visible_on_front' => true
            ]
        );
        $eavSetup->addAttributeToSet(
            CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER,
            CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER,
            null,
            $exemptionTypeCode);
        $exemptionType = $this->eavConfig->getAttribute(
            CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER,
            $exemptionTypeCode);
        $exemptionType->setData('used_in_forms', ['adminhtml_customer']);
        $exemptionType->getResource()->save($exemptionType);

Snippet from customer_form.xml, changing fieldset name from 'customer' to 'my_tab' breaks the extension attributes.

<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<fieldset name="customer">
    <field name="my_exemption_type" formElement="select">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="label" xsi:type="string" translate="true">Exemption Type</item>
                <item name="source" xsi:type="string">customer</item>
            </item>
        </argument>
        <settings>
            <visible>true</visible>
        </settings>
    </field>
</fieldset>

Any help with either moving attributes to different tabs, creating a new admin form, or a different approach I haven't considered are appreciated!

有帮助吗?

解决方案

I know this post is old, but decided to add my findings of a working solution, after spending hours looking at this.

First off, I had to try and understand the concepts of Magento's UI components and find a simple way to achieve this, without writing additional classes and data models. Here is some good reading material if anyone is interested:

https://devdocs.magento.com/guides/v2.4/ui_comp_guide/concepts/ui_comp_data_source.html

The solution:

  1. Programatically install the customer attributes. I wont go into detail for this since everyone has their on way of installing customer attributes and the install / update script in the original question should be sufficient. The only thing you would need to change is 'visible' => false, so that the attribute does not show under the default "Account Information" tab.

  2. Add "view/adminhtml/ui_component/customer_form.xml" to your module with the following (obviously update the fieldset names and field name to whatever you require):

    <form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="rfm">
        <settings>
            <collapsible>false</collapsible>
            <label translate="true">RFM Information</label>
            <componentType>fieldset</componentType>
            <dataScope>customer</dataScope>
        </settings>
        <fieldset name="rfm_group">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string" translate="true">General Information</item>
                    <item name="dataScope" xsi:type="string">customer</item>
                    <item name="sortOrder" xsi:type="number">1</item>
                    <item name="collapsible" xsi:type="boolean">true</item>
                    <item name="opened" xsi:type="boolean">true</item>
                </item>
            </argument>
            <field name="rfm_recency" formElement="input">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="source" xsi:type="string">customer</item>
                    </item>
                </argument>
                <settings>
                    <label translate="true">Recency</label>
                    <dataType>text</dataType>
                    <visible>true</visible>
                    <imports>
                        <link name="value">${ $.provider }:data.customer.rfm_recency</link>
                    </imports>
                    <exports>
                        <link name="value">${ $.provider }:data.customer.rfm_recency</link>
                    </exports>
                </settings>
            </field>
        </fieldset>
    </fieldset>
    

You will notice i have a nested fieldset with a single input field, where the input field name would be composed like rfm[rfm_group][rfm_recency]. In order to compose the field name like customer[rfm_recency], we need to set a <dataScope> in each fieldset nodes and field nodes. You will see how I do this in my example above.

Next you will notice I have included imports and exports nodes under the field node.

  • The imports node (read) is telling the Magento UI which data value I want to link to my attribute value.
  • The exports node (write) is telling the Magento UI where I want to save my attribute value to.

Once you have implemented the customer_form.xml, clear the caches and reload your customer edit page. You should see something similar to this:

enter image description here

You will just need to make sure that the attribute is not visible in the "Account information" tab and the value actually saves as expected.

许可以下: CC-BY-SA归因
scroll top