1

This is my ui component file content:

<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">vendor_modulename_shippingmethods_form.shippingmethods_form_data_source</item>
        </item>
        <item name="label" translate="true" xsi:type="string">General Information</item>
        <item name="template" xsi:type="string">templates/form/collapsible</item>
    </argument>
    <dataSource name="shippingmethods_form_data_source">
        <dataProvider class="Vendor\Modulename\Model\ShippingMethods\DataProvider" name="shippingmethods_form_data_source">
            <settings>
                <requestFieldName>entity_id</requestFieldName>
                <primaryFieldName>entity_id</primaryFieldName>
            </settings>
        </dataProvider>
    </dataSource>
    <fieldset name="general">
        <settings>
            <label translate="true">Shipping Method Infomation</label>
        </settings>
        <field formElement="input" name="name" sortOrder="20">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="source" xsi:type="string">name</item>
                    <item name="label" xsi:type="string" translate="true">Name</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="dataScope" xsi:type="string">name</item>
                </item>
            </argument>
            <settings>
                <validation>
                    <rule name="required-entry" xsi:type="boolean">false</rule>
                </validation>
            </settings>
        </field>
    </fieldset>
</form>

and this is my DataProvider:

    namespace Vendor\ModuleName\Model\ShippingMethods;

    use Vendor\ModuleName\Model\ResourceModel\ShippingMethods\CollectionFactory;

    class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
    {

        protected $_loadedData;

        public function __construct(
            $name,
            $primaryFieldName,
            $requestFieldName,
            CollectionFactory $employeeCollectionFactory,
            array $meta = [],
            array $data = []
        ) {
            $this->collection = $employeeCollectionFactory->create();
            parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
        }

        public function getData()
        {
            if (isset($this->_loadedData)) {
                return $this->_loadedData;
            }
            $items = $this->collection->getItems();
            .......
        }
    }

If I display my query string in the getData() with echo $this->collection->getSelect();, the result is:

SELECT `main_table`.* FROM `mytable` AS `main_table` WHERE (`entity_id` = '') . My id is missing. Not sure how, any idea where to look ?  Thnx in advance

2 Answers 2

4

They were empty because the primaryFieldName and requestFieldName had wrong values. Instead of entity_id in my case i need to change it to simply id.

3

A few things are playing together here.

✅ Overall

  • <requestFieldName>id</requestFieldName> is going to be what you have configured (in your XML) your URL Parameter to be when the user clicks Edit from the Listing UI Component (aka. The Grid); it's what you see written in the web-browser's address bar.
  • <primaryFieldName>policy_id</primaryFieldName> is generally not going to change and it will be the same as the column name in the MySQL database.

Note: The example code herein came from a module that manages Content-Security-Policies so that's why you will see policy_id used. Your code will have something else there.


🥇 How to read the URL parameter into the Edit form UI Component

Hint: For this functionality, we only care about <requestFieldName/>

Make sure the following element matches whatever is showing-up as the URL parameter name in the web-browser's address bar:

./view/adminhtml/ui_component/[your_component]_edit_form.xml
<dataProvider class="..." name="...">
    <settings>
        ...
        <requestFieldName>policy_id</requestFieldName>
        ...
    </settings>
</dataProvider>

For example, look at the following two example URL parameters:

#1 https://local.domain.com/admin/csp/policy/edit/id/1/key/.../
#2 https://local.domain.com/admin/csp/policy/edit/policy_id/1/key/.../

☝️ the difference between those would correspond to these XML values, respectively:

#1 <requestFieldName>id</requestFieldName>
#2 <requestFieldName>policy_id</requestFieldName>

🥈 How to write the URL parameter from the Listing UI Component

The Edit button on the Listing UI Component navigates the user to an Edit URL. To control what URL parameter name is placed in that URL, modify the following to have your desired URL parameter name within <item name="urlEntityParamName" /> around here:

./view/adminhtml/ui_component/[your_component]_listing.xml
<listing xmlns:xsi="..." xsi:noNamespaceSchemaLocation="...">
    <columns>
        <actionsColumn name="actions" class="...">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="urlEntityParamName" xsi:type="string">policy_id</item>
                    ...
                </item>
            </argument>
            <settings>
                <indexField>policy_id</indexField>
            </settings>
        </actionsColumn>
    </columns>
</listing>


📚 A note about your Module's DataProvider.php

I don't believe people are making this mistake anymore but make sure your this file has at least this:

.\Model\YOUR_OBJECT\DataProvider.php
<?php
namespace YOUR_PACKAGE\YOUR_MODULE\Model\YOUR_OBJECT;

use YOUR_PACKAGE\YOUR_MODULE\Model\ResourceModel\YOUR_OBJECT\CollectionFactory;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Ui\DataProvider\Modifier\PoolInterface;

class DataProvider extends \Magento\Ui\DataProvider\ModifierPoolDataProvider
{

    protected $collection;
    protected $dataPersistor;
    protected $loadedData;

    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        CollectionFactory $yourCollectionFactory,
        DataPersistorInterface $dataPersistor,
        array $meta = [],
        array $data = [],
        PoolInterface $pool = null
    ) {
        $this->collection = $yourCollectionFactory->create();
        $this->dataPersistor = $dataPersistor;
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data, $pool);
    }

    public function getData()
    {
        if (isset($this->loadedData)) {
            return $this->loadedData;
        }
        $items = $this->collection->getItems();
        foreach ($items as $_yourObject) {
            $this->loadedData[$_yourObject->getId()] = $_yourObject->getData();
        }

        $data = $this->dataPersistor->get('your_object');
        if (!empty($data)) {
            $yourObject = $this->collection->getNewEmptyItem();
            $yourObject->setData($data);
            $this->loadedData[$yourObject->getId()] = $yourObject->getData();
            $this->dataPersistor->clear('your_object');
        }

        return $this->loadedData;
    }
}

Hint: ☝️Keep in mind that for Factory classes, you don't actually need to have a file named YOUR_PACKAGE\YOUR_MODULE\Model\ResourceModel\YOUR_OBJECT\CollectionFactory.php you only need to have YOUR_PACKAGE\YOUR_MODULE\Model\ResourceModel\YOUR_OBJECT\Collection.php and Magento magic will take care of making the Factory reference work based on what you already have in Collection.php.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.