skip to Main Content

I am making a form using UiComponent. In options.js, I would like to make an ajax call. However It’s getting 404 not found error. I would like to know how we can get the right url.

In the form:

<field name="attribute_id">
    <argument name="data" xsi:type="array">
        <item name="options" xsi:type="object">VendorModuleModelSourceMyvalues</item>
        <item name="config" xsi:type="array">
            <item name="dataType" xsi:type="string">text</item>
            <item name="label" translate="true" xsi:type="string">Attribute</item>
            <item name="component" xsi:type="string">Vendor_Module/js/form/element/options</item>
            <item name="formElement" xsi:type="string">select</item>
            <item name="sortOrder" xsi:type="number">210</item>
        </item>
    </argument>
</field>

In options.js

define([
    'jquery',
    'underscore',
    'uiRegistry',
    'Magento_Ui/js/form/element/select',
    'Magento_Ui/js/modal/modal',
    'mage/url'
], function ($, _, uiRegistry, select, modal, url) {
    'use strict';

    return select.extend({

        /**
         * On value change handler.
         *
         * @param {String} value
         */
        onUpdate: function (value) {
            console.log('Selected Value: ' + value);

            var field1 = uiRegistry.get('index = field1');

  var field2 = uiRegistry.get('index = field2');
  field2.hide();
  var field3Depend1 = uiRegistry.get('index = field3Depend1');


console.log(field2.visibleValue);
 var linkUrl = url.build('customajax');
  console.log('linkurl='+linkUrl);

 //var name = document.getElementsByName("product[name]")[0].value;
   // var type = document.getElementsByName("product[product_category_type]")[0].value;

    $.ajax({
        url: 'BASEURL????'+linkUrl,
        showLoader: true,
        data: {form_key: window.FORM_KEY, 'value':value},
        type: "POST",
          dataType : 'json',
        success: function(result){

            alert(result);
        }
    });


         return this._super();
        },
    });
});

It gives 404 not found error. I would like to make an ajax call.

2

Answers


  1. I have tried various method to bring a url dynamically into a UI component, but the standard and safe way I think is to add via meta data of the UI xml component itself.

    To inject the dynamic data (not needed if you just want to added a static URL) in the component use the following code:

    Form DataProvider.php:

    <?php
    
    namespace VendorModuleUiDataProviderProfile;
    
    use MagentoFrameworkUrlInterface;
    
    class DataProvider extends MagentoUiDataProviderAbstractDataProvider
    {
        public $collection;
    
        /**
         * @var $addFieldStrategies
         */
        public $addFieldStrategies;
    
        /**
         * @var $addFilterStrategies
         */
        public $addFilterStrategies;
    
        /** @var UrlInterface  */
        public $url;
    
        public function __construct(
            $name,
            $primaryFieldName,
            $requestFieldName,
            UrlInterface $url,
            VendorModuleModelResourceModelMyModelCollectionFactory $collectionFactory,
            $addFieldStrategies = [],
            $addFilterStrategies = [],
            $meta = [],
            $data = []
        ) {
            parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
            $this->url = $url;
            $this->collection = $collectionFactory->create();
            $this->addFieldStrategies = $addFieldStrategies;
            $this->addFilterStrategies = $addFilterStrategies;
        }
    
        /**
         * @return array
         * @throws MagentoFrameworkExceptionLocalizedException
         */
        public function getMeta()
        {
            $meta = parent::getMeta();
            // general -> fieldset name
            // attribute_id -> field name
            $meta["general"]['children']["attribute_id"]['arguments']['data']['config']['url'] =
                $this->url->getUrl('myfrontname/mycontroller/myaction', ['_nosid' => true]);
    
            return $meta;
        }
    
        /**
         *
         * @return array
         */
        public function getData()
        {
            if (!$this->getCollection()->isLoaded()) {
                $this->getCollection()->load();
            }
    
            /** @var array $items */
            $items = $this->getCollection();
            $data = [];
    
            foreach ($items as &$item) {
                $item->setData("id_field_name", 'id');
                $data[$item->getId()] = $item->getData();
            }
            return $data;
        }
    }
    
    

    Here, function getMeta() is injecting the URL value.

    UI Component xml field:

    <field name="attribute_id">
        <argument name="data" xsi:type="array">
            <item name="options" xsi:type="object">VendorModuleModelSourceMyvalues</item>
            <item name="config" xsi:type="array">
                <item name="url" xsi:type="string" />
                <item name="url" xsi:type="url" path="mymodule/mycontroller/myaction">
                            <param name="_nosid">1</param>
                        </item>
                <item name="dataType" xsi:type="string">text</item>
                <item name="label" translate="true" xsi:type="string">Attribute</item>
                <item name="component" xsi:type="string">Vendor_Module/js/form/element/options</item>
                <item name="formElement" xsi:type="string">select</item>
                <item name="sortOrder" xsi:type="number">210</item>
            </item>
        </argument>
    </field>
    

    Here, I have added <item name="url" xsi:type="url" path="mymodule/mycontroller/myaction">
    <param name="_nosid">1</param>
    </item>
    the url key will have the dynamic URL and will be available on JS UI component.

    Now in options.js, use the url field as below:

    define([
        'jquery',
        'underscore',
        'uiRegistry',
        'Magento_Ui/js/form/element/select',
        'Magento_Ui/js/modal/modal',
        'mage/url'
    ], function ($, _, uiRegistry, select, modal, url) {
        'use strict';
    
        return select.extend({
    
            /**
             * On value change handler.
             *
             * @param {String} value
             */
            onUpdate: function (value) {
                // As `this` context will not be available inside ajax,
                // so either use local variable `self` or prepare the URL outside the `$.ajax`  
                var self = this;
    
                console.log('Selected Value: ' + value);
    
                var field1 = uiRegistry.get('index = field1');
    
                var field2 = uiRegistry.get('index = field2');
                field2.hide();
                var field3Depend1 = uiRegistry.get('index = field3Depend1');
                var linkUrl = url.build('customajax');
    
                $.ajax({
                    url: self.url + linkUrl,
                    showLoader: true,
                    data: {form_key: window.FORM_KEY, 'value':value},
                    type: "POST",
                    dataType : 'json',
                    success: function(result) {
                        alert(result);
                }
             });
    
    
             return this._super();
            },
        });
    });
    

    Edit: I have updated the answer with the below answer.

    Login or Signup to reply.
  2. It can also be added via url xml datatype (Only static urls can be added. No need to modify meta in this case.).

    UI Component xml field:

    <dataSource name="your_module_data_source">
            <argument name="dataProvider" xsi:type="configurableObject">
                <argument name="class" xsi:type="string">YourModuleDataProvider</argument>
                <argument name="name" xsi:type="string">your_module_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 name="validate_url" xsi:type="url" path="*/*/validate"/>
                        <item name="get_custom_url" xsi:type="url" path="your/custom/url"/>
                    </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>
    

    Here, I have added get_custom_url of type url which will have the URL and will be available on JS.

    Now in options.js, use the url field as below:

    define([
        'jquery',
        'underscore',
        'uiRegistry',
        'Magento_Ui/js/form/element/select',
        'Magento_Ui/js/modal/modal',
        'mage/url'
    ], function ($, _, uiRegistry, select, modal, url) {
        'use strict';
    
        return select.extend({
    
            /**
             * On value change handler.
             *
             * @param {String} value
             */
            onUpdate: function (value) {
                console.log('Selected Value: ' + value);
    
                var field1 = uiRegistry.get('index = field1');
    
                var field2 = uiRegistry.get('index = field2');
                field2.hide();
                var field3Depend1 = uiRegistry.get('index = field3Depend1');
                var linkUrl = url.build('customajax');
    
                var source = uiRegistry.get(this.provider);
                var ajaxUrl = source.get_custom_url;
                $.ajax({
                    url: ajaxUrl + linkUrl,
                    showLoader: true,
                    data: {form_key: window.FORM_KEY, 'value':value},
                    type: "POST",
                    dataType : 'json',
                    success: function(result) {
                        alert(result);
                }
             });
    
    
             return this._super();
            },
        });
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search