1

In my form.xml, I have used below code to show input field

<field name="price">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="label" xsi:type="string">Shipping Price</item>
            <item name="visible" xsi:type="boolean">true</item>
            <item name="dataType" xsi:type="string">text</item>
            <item name="formElement" xsi:type="string">input</item>
            <item name="elementTmpl" xsi:type="string">ui/form/element/price</item>
            <item name="currency_sign" xsi:type="string">$</item>
            <item name="source" xsi:type="string">shippingrates</item>
        </item>
    </argument>
</field>

As it was a price column I added below code to show currency symbol

<item name="elementTmpl" xsi:type="string">ui/form/element/price</item>
<item name="currency_sign" xsi:type="string">$</item>

Now the problem is that I want to pass the currency_sign dynamically using helper function, I was unable to call helper function here. I tried below to call helper function, but none of them worked.

<item name="currency_sign" xsi:type="helper" helper="Namespace\ModuleName\Helper\Data::getCurrencySymbol" />

I tried this too

<item name="currency_sign" xsi:type="helper" >Namespace\ModuleName\Helper\Data::getCurrencySymbol</item>

Anyone has idea how to get this working?

  • Have you tried this - <item name="currency_sign" xsi:type="string" >Namespace\ModuleName\Helper\Data::getCurrencySymbol</item> – mighty_hk Jun 25 '18 at 7:18
  • @mighty_hk Yes, if use xsi:type="string" then it will print the text defined in item tag not the helper function response – Piyush Jun 25 '18 at 7:19
  • 1
    @Piyush, I think the correct tool will be a DataModifier in this case. Do I understand correctly that you want the currency_sign to be provided, dependent on conditions, from the server? In other words, the end result will sometimes be $, sometimes , etc.? – bassplayer7 Jun 26 '18 at 16:54
  • @bassplayer7 Yes, you were right, DataModifier way worked here, Many Thanks. If you can add your comment as answer with some code or explanation, will be happy to accept it. :) – Piyush Jun 27 '18 at 8:12
  • Sure, I'll do that. – bassplayer7 Jun 27 '18 at 12:57
3
+50

The base layer of UI Component configuration is made up of static values in Javascript (per module, in the defaults object) and more specifically XML. This makes it easy build out new UI Components, but is not flexible. Magento processes all the XML configuration through PHP and provides a simple interface with which to modify, add, or delete configuration during the request. To integrate with this, use a DataModifier. It must implement \Magento\Ui\DataProvider\Modifier\ModifierInterface. There are also abstract classes that can be used for convenience as well, such as: \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier.

First, create a DataModifier class (these are usually placed within a Ui/ directory):

namespace SwiftOtter\Example\Ui\Modifiers;

use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;

class ProductForm extends AbstractModifier
{

    public function modifyData(array $data)
    {
        // modify data provided to UI Component here

        return $data;
    }


    public function modifyMeta(array $meta)
    {
        // modify currency_sign (or any field structure) here
        // Use \Magento\Framework\Stdlib\ArrayManager for diving deep into complex array structures

        return $meta;
    }
}

Next, configure the data modifier with the appropriate modifier pool. In the following example, I am adding a modifier for example-input on the Catalog Product manage page:

<virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool" type="Magento\Ui\DataProvider\Modifier\Pool">
    <arguments>
        <argument name="modifiers" xsi:type="array">
            <item name="example-input" xsi:type="array">
                <item name="class" xsi:type="string">SwiftOtter\Example\Ui\Modifiers\ProductForm</item>
            </item>
        </argument>
    </arguments>
</virtualType>

As you can imagine, this provides a great deal of flexibility for modifying various aspects of not only your UI Component but others, if necessary.


For more info, DevDocs has a good article on PHP Data Modifiers: https://devdocs.magento.com/guides/v2.2/ui_comp_guide/concepts/ui_comp_modifier_concept.html

3

I followed as suggested by @bassplayer7

Firstly Added Vendor/Module/Ui/DataProvider/Item/Form/DataProvider.php File with below code

namespace Vendor\Module\Ui\DataProvider\Item\Form;

use Vendor\Module\Model\ResourceModel\Item\CollectionFactory;
use Magento\Ui\DataProvider\AbstractDataProvider;
use Magento\Ui\DataProvider\Modifier\ModifierInterface;
use Magento\Ui\DataProvider\Modifier\PoolInterface;

class DataProvider extends AbstractDataProvider
{ 
    /**
     * @var PoolInterface
     */
    private $pool;

    /**
     * Construct
     *
     * @param string $name
     * @param string $primaryFieldName
     * @param string $requestFieldName
     * @param CollectionFactory $collection
     * @param PoolInterface $pool
     * @param array $meta
     * @param array $data
     */
    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        CollectionFactory $collection,
        PoolInterface $pool,
        array $meta = [],
        array $data = []
    ) {
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
        $this->collection = $collection->create();
        $this->pool = $pool;
    }

    public function getData()
    {
        /** @var ModifierInterface $modifier */
        /** the below foreach code you need to process modifier on your field */
        foreach ($this->pool->getModifiersInstances() as $modifier) {
            $this->data = $modifier->modifyData($this->data);
        }

        return $this->data;
    }

    public function getMeta()
    {
        $meta = parent::getMeta();

        /** @var ModifierInterface $modifier */
        foreach ($this->pool->getModifiersInstances() as $modifier) {
            $meta = $modifier->modifyMeta($meta);
        }

        return $meta;
    }
}

Then created Vendor/Module/etc/adminhtml/di.xml with below code

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="Vendor\Module\Ui\DataProvider\Item\Form\Modifier\Pool" type="Magento\Ui\DataProvider\Modifier\Pool">
        <arguments>
            <argument name="modifiers" xsi:type="array">
                <item name="price-modifier" xsi:type="array">
                    <item name="class" xsi:type="string">Vendor\Module\Ui\DataProvider\Item\Form\Modifier\PriceModifier</item>
                    <item name="sortOrder" xsi:type="number">20</item>
                </item>
            </argument>
        </arguments>
    </virtualType>
    <type name="Vendor\Module\Ui\DataProvider\Item\Form\DataProvider">
        <arguments>
            <argument name="pool" xsi:type="object">Vendor\Module\Ui\DataProvider\Item\Form\Modifier\Pool</argument>
        </arguments>
    </type>
</config>

And atlast added Modifier Vendor/Module/Ui/DataProvider/Item/Form/Modifier/PriceModifier.php File with below code

namespace Vendor\Module\Ui\DataProvider\Item\Form\Modifier;

use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;
use Magento\Framework\UrlInterface;

use Magento\Ui\DataProvider\Modifier\ModifierInterface;

    class PriceModifier implements ModifierInterface
    {

        public function __construct(
            \Magento\Store\Model\StoreManagerInterface $storeManager
            )
        {
            $this->_storeManager = $storeManager;
        }

        public function modifyMeta(array $meta)
        {
            $meta['fieldset'] = [ //here field set name
                'children' => [
                    'price' => [ //here price is field namme
                        'arguments' => [
                            'data' => [
                                'config' => [
                                    'currency_sign' => $this ->_storeManager-> getStore()->getBaseCurrency()->getCurrencySymbol()
                                ]
                            ]
                        ]
                    ]
                ]
            ];
            return $meta;
        }

        /**
         * {@inheritdoc}
         */
        public function modifyData(array $data)
        {
            return $data;
        }
    }

By this I was able to show base currency symbol in input field same as in edit product page price field.

  • 1
    Great example. One thing to keep in mind is that the contents of modifyMeta would override anything else you added to the XML. It might be better to use \Magento\Framework\Stdlib\ArrayManager to modify only the current_sign. The array tool makes it so you do not have to do a ton of isset() checks. – bassplayer7 Jun 28 '18 at 13:47
  • Hi @Piyush how to give reference of this class in our xml field ? I have tried like this but no effect: <item name="options" xsi:type="object">Ven\Mod\Ui\DataProvider\Item\Form\Modifier\PriceModifier</item> – Ajwad Syed Apr 29 at 14:38
  • I looking for same, Have a look pls magento.stackexchange.com/questions/272822/… – Ajwad Syed Apr 29 at 14:41
  • @AjwadTaqvi make you sure you have added correct elementTmpl in xml's field also the field name in datamodifier file – Piyush Apr 29 at 14:52
  • Yes rechecked, but no effect.. is it fine in item xsi:type="object" ? – Ajwad Syed Apr 29 at 15:02
0

I think you can not call direct helper function in UI component file.

If you want to get price with currency symbol then try with below way, it my help to you.

Give object to your ui component field.

<item name="options" xsi:type="object">{Vendorname}\{Modulename}\Model\Classname</item>

And, in your model source file code like this.

<?php
   namespace Yourmodule\Modulename\Model\Path;

   class ClassName 
   {

    public function __construct(        

    ) {

    }

    your code for get currency symbol.
  }
  • Can you give any working example where you have achieved this using model? – Piyush Jun 25 '18 at 7:16
  • I have no any working example related to price currency, but for any other data i use the model source. – Chirag Patel Jun 25 '18 at 7:21
  • I mean what function/method should I have in your code for get currency symbol. and how I will get its response in uiform? – Piyush Jun 25 '18 at 7:22
  • the code you shared can be used for dropdowns options, not sure how to use it for other – Piyush Jun 25 '18 at 7:24
0

Try using this :

<item name="curreny_sign" xsi:type="object">Namespace\ModuleName\Block\Adminhtml\Currency</item>  

Now create Namespace\ModuleName\Block\Adminhtml\Currency.php

<?php
namespace Namespace\ModuleName\Block\Adminhtml;


class Currency extends \Magento\Backend\Block\Template
{
    /**
     * Block template
     *
     * @var string
     */
    protected $_template = 'currency.phtml';
}

Now create Namespace\ModuleName\view\adminhtml\templates\currency.phtml

<?php 
// cal your helper function in phtml

In currency.phtml, call your helper method. I think this should work.

  • Were you able to try it? – mighty_hk Jun 25 '18 at 8:12
  • Thank you for efforts but it didn't worked for me, I did it using DataModifier. Will post the answer once I get some time for it – Piyush Jun 27 '18 at 12:47
  • Okay. Curious to know the answer. – mighty_hk Jun 27 '18 at 12:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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