Pergunta

How can I load the data from customer DataProvider plugin into my ui_component dynamicRows?

I have created a new tab in the admin customer edit form, and added my ui_component, which seems to work well. But I can't populate the data already stored in my database.

I have tried to add xml for DataSource, but I think that has conflict with original customer_form.xml DataSource "customer_form.customer_form_data_source" because when I add DataSource, the page no longer loads.

dataSource XML:

<dataSource name="mycustomrows">
    <argument name="dataProvider" xsi:type="configurableObject">
        <argument name="class" xsi:type="string">MyVendor\MyModule\Model\Customer\DataProvider</argument>
        <argument name="primaryFieldName" xsi:type="string">id</argument>
        <argument name="requestFieldName" xsi:type="string">id</argument>
        <argument name="meta" xsi:type="array">
            <item name="mycustomrows" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string" translate="true">My Custom Rows</item>
                </item>
            </item>
        </argument>
        <argument name="data" xsi:type="array">
            <item name="js_config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
            </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>

dataProvider for dataSource:

<?php

namespace MyVendor\MyModule\Model\Customer;

class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
{
   protected $loadedData;
   protected $collectionFactory;

   public function __construct(
       $name,
       $primaryFieldName,
       $requestFieldName,
       \MyVendor\MyModule\Model\ResourceModel\Row\Collection $collection,
       \MyVendor\MyModule\Model\ResourceModel\Row\CollectionFactory $collectionFactory,
       array $meta = [],
       array $data = []
   ) {
       $this->collection = $collection;
       $this->collectionFactory = $collectionFactory;

       parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
   }

   public function getData()
   {
       if (isset($this->loadedData)) {
           return $this->loadedData;
       }

       $collection = $this->collectionFactory->create(); 
       // add Filter for Customer ID
       //->setOrder('position', 'ASC');
       $items = $collection->getItems();

       foreach ($items as $item) {
           $this->loadedData[$item->getId()] = $item->getData();
       }

       return $this->loadedData;
   }
}

I believe the data has to be loaded with Plugin for "Magento\Customer\Model\Customer\DataProvider" as I am doing below, but I can't seem to get populate rows on load.

view/adminhtml/ui_component/customer_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">
    <fieldset name="mycustomrows">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="label" xsi:type="string" translate="true">My Custom Rows</item>
                <item name="sortOrder" xsi:type="number">10</item>
            </item>
        </argument>
        <dynamicRows name="mycustomrows">
            <settings>
                <addButtonLabel translate="true">Add Row</addButtonLabel>
                <additionalClasses>
                    <class name="admin__field-wide">true</class>
                </additionalClasses>
                <componentType>dynamicRows</componentType>
            </settings>

            <container name="record" component="Magento_Ui/js/dynamic-rows/record">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="isTemplate" xsi:type="boolean">true</item>
                        <item name="is_collection" xsi:type="boolean">true</item>
                        <item name="componentType" xsi:type="string">container</item>
                        <item name="positionProvider" xsi:type="string">position</item>
                    </item>
                </argument>


                <field name="mycustomrows_select1" formElement="select" sortOrder="10">
                    <settings>
                        <dataType>text</dataType>
                        <label translate="true">Select Field 1</label>
                        <disabled>false</disabled>
                        <dataScope>mycustomrows_select1</dataScope>
                    </settings>
                    <formElements>
                        <select>
                            <settings>
                                <options class="MyVendor\MyModule\Model\Source\SelectFieldOne"/>
                            </settings>
                        </select>
                    </formElements>
                </field>
                <field name="mycustomrows_input1" sortOrder="20" 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">Text Field 1</label>
                        <dataType>text</dataType>
                        <dataScope>mycustomrows_text1</dataScope>
                    </settings>
                </field>
                <actionDelete sortOrder="30">
                    <argument name="data" xsi:type="array">
                        <item name="config" xsi:type="array">
                            <item name="componentType" xsi:type="string">actionDelete</item>
                            <item name="dataType" xsi:type="string">text</item>
                            <item name="fit" xsi:type="boolean">false</item>
                            <item name="label" xsi:type="string">Actions</item>
                            <item name="sortOrder" xsi:type="string">500</item>
                            <item name="additionalClasses" xsi:type="string">data-grid-actions-cell</item>
                            <item name="template" xsi:type="string">Magento_Backend/dynamic-rows/cells/action-delete</item>
                        </item>
                    </argument>
                </actionDelete>
            </container>
        </dynamicRows>
    </fieldset>
</form>

etc/adminhtml/di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Customer\Model\Customer\DataProvider">
        <plugin name="customer_get_mycustomrows" type="MyVendor\MyModule\Model\Customer\DataProvider" sortOrder="5" />
    </type>
</config>

Model/Customer/DataProvider.php

<?php
namespace MyVendor\MyModule\Model\Customer;

class DataProvider 
{
    protected $collection;
    protected $collectionFactory;
    protected $loadedData;

    public function __construct(
        \MyVendor\MyModule\Model\ResourceModel\Row\Collection $collection,
        \MyVendor\MyModule\Model\ResourceModel\Row\CollectionFactory $collectionFactory,
        array $data = []
    ) {
        $this->collection = $collection;
        $this->collectionFactory = $collectionFactory;
    }

    public function afterGetData(\Magento\Customer\Model\Customer\DataProvider $subject, $result)
    {
        if($result){
            $customer_id = key($result);
            $customerData =  $result[$customer_id]['customer'];

            if(is_null($this->loadedData)) {
                $this->loadedData = array();
                $collection = $this->collectionFactory->create(); //->setOrder('position', 'ASC');
                $items = $collection->getItems();

                foreach ($items as $item) {
                    $this->loadedData[] = $item->getData();
                }
            }

            $result[$customer_id]['customer']["mycustomrows"] = $this->loadedData;
        }
        return $result;
    }

}

I can't seem to get any records populated when I load a customer edit page.

Foi útil?

Solução

You need to change in the last two steps,

Step-1, you need to add a plugin for DataProviderWithDefaultAddresses in place of DataProvider,

etc/adminhtml/di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Customer\Model\Customer\DataProviderWithDefaultAddresses">
        <plugin name="customer_get_mycustomrows" type="MyVendor\MyModule\Model\Customer\DataProvider" sortOrder="5" />
    </type>
</config>

And in below class use DataProviderWithDefaultAddresses as a subject in the argument, Model/Customer/DataProvider.php

<?php
namespace MyVendor\MyModule\Model\Customer;

class DataProvider 
{
    protected $collection;
    protected $collectionFactory;
    protected $loadedData;

    public function __construct(
        \MyVendor\MyModule\Model\ResourceModel\Row\Collection $collection,
        \MyVendor\MyModule\Model\ResourceModel\Row\CollectionFactory $collectionFactory,
        array $data = []
    ) {
        $this->collection = $collection;
        $this->collectionFactory = $collectionFactory;
    }

    public function afterGetData(\Magento\Customer\Model\Customer\DataProviderWithDefaultAddresses $subject, $result)
    {
        if($result){
            $customer_id = key($result);
            $customerData =  $result[$customer_id]['customer'];

            if(is_null($this->loadedData)) {
                $this->loadedData = array();
                $collection = $this->collectionFactory->create(); //->setOrder('position', 'ASC');
                $items = $collection->getItems();

                foreach ($items as $item) {
                    $this->loadedData[] = $item->getData();
                }
            }

            $result[$customer_id]['customer']["mycustomrows"] = $this->loadedData;
        }
        return $result;
    }

}

After run compile command and clear cache data will be loaded into edit form.

Outras dicas

This will load custom collection in dynamic rows:

customer_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">
    <fieldset name="customdata">
       <argument name="data" xsi:type="array">
           <item name="config" xsi:type="array">
               <item name="label" xsi:type="string" translate="true">Custom data</item>
               <item name="sortOrder" xsi:type="number">1</item>
           </item>
       </argument>
       <container name="customdata">
           <argument name="data" xsi:type="array">
               <item name="config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/dynamic-rows/dynamic-rows</item>
                    <item name="template" xsi:type="string">ui/dynamic-rows/templates/default</item>
                    <item name="componentType" xsi:type="string">dynamicRows</item>
                    <item name="recordTemplate" xsi:type="string">record</item>
                    <item name="addButtonLabel" xsi:type="string">Add new</item>
                    <item name="deleteProperty" xsi:type="boolean">false</item>
                    <item name="additionalClasses" xsi:type="array">
                        <item name="admin__field-wide" xsi:type="boolean">true</item>
                    </item>
               </item>
           </argument>
           <container name="record">
               <argument name="data" xsi:type="array">
                   <item name="config" xsi:type="array">
                       <item name="label" xsi:type="string" translate="true">Custom data</item>
                       <item name="component" xsi:type="string" translate="true">Magento_Ui/js/dynamic-rows/record</item>
                       <item name="isTemplate" xsi:type="boolean">true</item>
                       <item name="is_collection" xsi:type="boolean">true</item>
                       <item name="showFallbackReset" xsi:type="boolean">false</item>
                   </item>
               </argument>
                <field formElement="input" name="field" sortOrder="90">
                    <argument name="data" xsi:type="array">
                        <item name="config" xsi:type="array">
                            <item name="source" xsi:type="string">Data</item>
                        </item>
                    </argument>
                    <settings>
                        <dataType>text</dataType>
                        <label translate="true">Field</label>
                        <dataScope>field</dataScope>
                        <validation>
                            <rule name="required-entry" xsi:type="boolean">true</rule>
                        </validation>
                    </settings>
                </field>
           </container>
       </container>
   </fieldset>
</form>

DataProvider.php

protected $collection;
protected $collectionFactory;

protected $loadedData;

public function __construct(
    \Vendor\Vendor\Model\ResourceModel\Vendor\Collection $collection,
    \Vendor\Vendor\Model\ResourceModel\Vendor\CollectionFactory $collectionFactory,
    array $data = []
) {
    $this->collection = $collection;
    $this->collectionFactory = $collectionFactory;  
}

public function afterGetData(\Magento\Customer\Model\Customer\DataProviderWithDefaultAddresses $subject, $result)
{
    if ($result)
    {
        $customer_id = key($result);
        $customerData =  $result[$customer_id]['customer'];

        if (is_null($this->loadedData)) 
        {
            $this->loadedData = [];

            $collection = $this->collectionFactory->create();

            $items = $collection->getItems();

            foreach ($items as $item) 
            {
                $result[$customer_id]["customdata"]["customdata"][] = $item->getData();
            }
        }
    }

    return $result;
}

di.xml

<type name="Magento\Customer\Model\Customer\DataProviderWithDefaultAddresses">
    <plugin name="customdata" type="Vendor\Vendor\Model\Customer\DataProvider" sortOrder="5" />
</type>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a magento.stackexchange
scroll top