In Magento 2, you might want to show a downloadable link in the admin panel form. This link can point to a file stored in the pub/media/
directory of your Magento installation. You can dynamically fetch the file name from your database and display the link in the admin UI. This is particularly useful when you are working with informative fields that require users to download a file, such as a CSV report, PDF, or other documents.
In this blog post, we will guide you step-by-step on how to add a dynamic downloadable link to your Magento 2 Admin UI form. We will break the process into clear, easy-to-follow steps.
Step 1: Create the UI Form
The first step is to define a UI form that will hold the downloadable link. In Magento 2, you create a UI component XML file that defines the form and its fields. Below is the XML configuration for a basic form.
File: app/code/VendorName/ModuleName/view/adminhtml/ui_component/importui_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">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">importui_form.importui_form_data_source</item>
<item name="deps" xsi:type="string">importui_form.importui_form_data_source</item>
</item>
<item name="label" xsi:type="string" translate="true">General Information</item>
<item name="config" xsi:type="array">
<item name="dataScope" xsi:type="string">data</item>
<item name="namespace" xsi:type="string">importui_form</item>
</item>
<item name="spinner" xsi:type="string">general_information</item>
<item name="template" xsi:type="string">templates/form/collapsible</item>
</argument>
<dataSource name="importui_form_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">VendorName\ModuleName\Model\ImportDataProvider</argument>
<argument name="name" xsi:type="string">importui_form_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">id</argument>
<argument name="requestFieldName" xsi:type="string">id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="submit_url" xsi:type="url" path="*/*/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>
</form>
This XML defines a form that will later include our downloadable link. You will add a field dynamically to this form in the next steps.
Step 2: Create the Data Provider
The data provider is responsible for fetching data from the database and providing it to the form. In this step, we create a custom data provider class to load the necessary data for the form.
File: app/code/VendorName/ModuleName/Model/ImportDataProvider.php
<?php
namespace VendorName\ModuleName\Model;
use VendorName\ModuleName\Model\ResourceModel\ImportProfile\CollectionFactory; // This my custom colelction file you can replace your class
use Magento\Ui\DataProvider\AbstractDataProvider;
use Magento\Ui\DataProvider\Modifier\ModifierInterface;
use Magento\Ui\DataProvider\Modifier\PoolInterface;
class ImportDataProvider extends AbstractDataProvider
{
private $pool;
public function __construct(
$name,
$primaryFieldName,
$requestFieldName,
CollectionFactory $collectionFactory,
PoolInterface $pool,
array $meta = [],
array $data = []
) {
parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
$this->collection = $collectionFactory->create();
$this->pool = $pool;
}
public function getData()
{
/** @var ModifierInterface $modifier */
foreach ($this->pool->getModifiersInstances() as $modifier) {
$this->data = $modifier->modifyData($this->data);
}
$items = $this->collection->getItems();
foreach ($items as $importProfile) {
$this->data[$importProfile->getId()] = $importProfile->getData();
}
return $this->data;
}
public function getMeta()
{
$meta = parent::getMeta();
/** @var ModifierInterface $modifier */
foreach ($this->pool->getModifiersInstances() as $modifier) {
$meta = $modifier->modifyMeta($meta);
}
return $meta;
}
}
Here, the ImportDataProvider
class is designed to fetch the required data for the form. It works by loading records from a custom collection and applying any modifiers defined for the form.
Step 3: Create the Modifier Class for the Dynamic Link
Now, we will create a custom modifier class that adds the dynamic download link to the form. This class will generate a clickable link based on a file path stored in the database.
File: app/code/VendorName/ModuleName/Ui/DataProvider/ImportForm/Modifier/AddLinkField.php
<?php
namespace VendorName\ModuleName\Ui\DataProvider\ImportForm\Modifier;
use Magento\Catalog\Model\Locator\LocatorInterface;
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
use Magento\Framework\Stdlib\ArrayManager;
use Magento\Framework\UrlInterface;
use Magento\Ui\Component\Container;
use Magento\Ui\Component\Form\Fieldset;
use Magento\Ui\Component\Form\Element\DataType\Number;
use Magento\Ui\Component\Form\Element\DataType\Text;
use Magento\Ui\Component\Form\Element\Input;
use Magento\Ui\Component\Form\Element\Select;
use Magento\Ui\Component\Form\Element\MultiSelect;
use Magento\Ui\Component\Form\Field;
class AddLinkField extends AbstractModifier
{
const CUSTOM_FIELDSET_INDEX = 'custom_fieldset';
const CONTAINER_HEADER_NAME = 'custom_fieldset_content_header';
const FIELD_NAME_TEXT = 'title';
/**
* @var \Magento\Catalog\Model\Locator\LocatorInterface
*/
protected $locator;
/**
* @var ArrayManager
*/
protected $arrayManager;
/**
* @var UrlInterface
*/
protected $urlBuilder;
/**
* @var array
*/
protected $meta = [];
/**
* @param LocatorInterface $locator
* @param ArrayManager $arrayManager
* @param UrlInterface $urlBuilder
*/
public function __construct(
LocatorInterface $locator,
ArrayManager $arrayManager,
UrlInterface $urlBuilder
) {
$this->locator = $locator;
$this->arrayManager = $arrayManager;
$this->urlBuilder = $urlBuilder;
}
/**
* Data modifier, does nothing in our example.
*
* @param array $data
* @return array
*/
public function modifyData(array $data)
{
return $data;
}
/**
* Meta-data modifier: adds ours fieldset
*
* @param array $meta
* @return array
*/
public function modifyMeta(array $meta)
{
$this->meta = $meta;
$this->addCustomFieldset();
return $this->meta;
}
/**
* Merge existing meta-data with our meta-data (do not overwrite it!)
*
* @return void
*/
protected function addCustomFieldset()
{
$this->meta = array_merge_recursive(
$this->meta,
[
static::CUSTOM_FIELDSET_INDEX => $this->getFieldsetConfig(),
]
);
}
/**
* Declare ours fieldset config
*
* @return array
*/
protected function getFieldsetConfig()
{
return [
'arguments' => [
'data' => [
'config' => [
'label' => __('Fieldset Title'),
'componentType' => Fieldset::NAME,
'provider' => 'importui_form_data_source', // your UI form data source name
'ns' => 'importui_form', // your UI form name
'collapsible' => true,
'sortOrder' => 10,
'opened' => true,
],
],
],
'children' => [
static::CONTAINER_HEADER_NAME => $this->getHeaderContainerConfig(10),
static::FIELD_NAME_TEXT => $this->getTextFieldConfig(20)
],
];
}
/**
* Get config for header container
*
* @param int $sortOrder
* @return array
*/
protected function getHeaderContainerConfig($sortOrder)
{
return [
'arguments' => [
'data' => [
'config' => [
'label' => null,
'formElement' => Container::NAME,
'componentType' => Container::NAME,
'template' => 'ui/form/components/complex',
'sortOrder' => $sortOrder,
'content' => __('You can write any text here'),
],
],
],
'children' => [],
];
}
/**
* Example text field config
*
* @param $sortOrder
* @return array
*/
protected function getTextFieldConfig($sortOrder)
{
$filePath = 'path/to/your/file.txt'; // Fetch this dynamically based on your needs
$fileUrl = $this->urlBuilder->getBaseUrl() . 'pub/media/' . $filePath;
// You can update This Method to get a dynamic URL and Add into additionalInfo
return [
'arguments' => [
'data' => [
'config' => [
'label' => __('Example Text Field'),
'formElement' => Field::NAME,
'componentType' => Input::NAME,
'dataScope' => static::FIELD_NAME_TEXT,
'dataType' => Number::NAME,
'additionalInfo' => "<a href='$fileUrl' target='_blank'>" . __('Download File') . "</a>",
'sortOrder' => $sortOrder,
],
],
],
];
}
}
Step 4: Configure the Modifier Class in di.xml
To register the modifier class, you need to configure it in the di.xml
file.
File: app/code/VendorName/ModuleName/etc/adminhtml/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<virtualType name="VendorName\ModuleName\Ui\DataProvider\Product\Form\Modifier\Pool" type="Magento\Ui\DataProvider\Modifier\Pool">
<arguments>
<argument name="modifiers" xsi:type="array">
<item name="AddLinkField" xsi:type="array">
<item name="class" xsi:type="string">VendorName\ModuleName\Ui\DataProvider\ImportForm\Modifier\AddLinkField</item>
<item name="sortOrder" xsi:type="number">10</item>
</item>
</argument>
</arguments>
</virtualType>
<type name="VendorName\ModuleName\Model\ImportDataProvider">
<arguments>
<argument name="pool" xsi:type="object">VendorName\ModuleName\Ui\DataProvider\Product\Form\Modifier\Pool</argument>
</arguments>
</type>
</config>
Step 5: Deploy and Clear Cache
Finally, run the following commands to deploy your changes and clear the cache.
php bin/magento setup:upgrade
php bin/magento setup:static-content:deploy
php bin/magento cache:clean
Conclusion
Congratulations! You have successfully added a dynamic downloadable link in your Magento 2 Admin UI form. This link will now point to a file stored in the pub/media/
directory and will be dynamically fetched based on the data from your database.
This approach can be extended to other dynamic content and fields. By modifying the AddLinkField
class, you can add more complex functionality to your Magento admin forms.
By following this guide, you can easily add dynamic downloadable links to your Magento 2 admin UI forms, streamlining file access for your team and improving the admin experience. This solution helps keep your store’s content management efficient and user-friendly. For more Magento tips and tricks, continue exploring our blog!
0 Comments