0

I'm currently making a custom ui-component for the adminhtml form which extends the default ui-select element. But the issue is that when I make a selection on this new ui-select all fields have their values cleared and if they are required the error appears.

I've been debugging for a while and have reached the conclusion that this issue appears down the line when the code gets to this.value(data) and also throws an exception.

Uncaught TypeError: Cannot read property 'click' of undefined

The element which is clicked in this case is the same element from the normal ui-select.

This is the component's xml through which it's added to the form. And yes the options shouldn't be there but I couldn't figure out where to put it otherwise to make it work.

<field name="programs" class="Mirasvit\Affiliate\Component\Filters\Type\MultiplePrograms">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string" translate="true">Programs</item>
                    <item name="componentType" xsi:type="string">field</item>
                    <item name="formElement" xsi:type="string">select</item>
                    <item name="elementTmpl" xsi:type="string">Mirasvit_Affiliate/form/elements/multiple-programs</item>
                    <item name="component" xsi:type="string">Mirasvit_Affiliate/js/component/multiple-programs</item>
                    <item name="filterOptions" xsi:type="boolean">true</item>
                    <item name="multiple" xsi:type="boolean">false</item>
                    <item name="options" xsi:type="object">Mirasvit\Affiliate\Ui\Account\Source\Program</item>

                    <item name="tableOptions" xsi:type="object">Mirasvit\Affiliate\Ui\Program\Source\ProgramsWithTiers</item>
                    <item name="tableValues" xsi:type="object">Mirasvit\Affiliate\Ui\Program\Source\AccountPrograms</item>
                    <item name="tableFields" xsi:type="array">
                        <item name="name" xsi:type="array">
                            <item name="label" xsi:type="string">Name</item>
                            <item name="type" xsi:type="string">text</item>
                        </item>
                        <item name="tier" xsi:type="array">
                            <item name="label" xsi:type="string">Tier</item>
                            <item name="type" xsi:type="string">select</item>
                        </item>
                        <item name="fixed" xsi:type="array">
                            <item name="label" xsi:type="string">Fixed tier</item>
                            <item name="type" xsi:type="string">checkbox</item>
                        </item>
                    </item>
                </item>
            </argument>
        </field>

This is the component's js file

define([
    'underscore',
    'jquery',
    'Magento_Ui/js/form/element/ui-select',
    'uiRegistry',
], function (_, $, Abstract, registry) {
    'use strict';

    return Abstract.extend({

        defaults: {
            optionsCache: [],
            options: [],
            listVisible: false,
            tableOptions: [],
            tableValues: [],
            tableFields: {},
            currentSelected: [],
        },

        toggleOptionSelected: function (data) {
            if (this.lastSelectable && data.hasOwnProperty(this.separator)) {
                return this;
            }

            this.options(this.options.without(data));

            /**
             * THIS IS WHERE THE COMPONENT BREAKS
             */
            this.value(data);

            this.listVisible(false);

            return this;
        },

        cleanHoveredElement: function () {
            if (this.hoveredElement) {
                $(this.hoveredElement)
                    .children(this.actionTargetSelector)
                    .removeClass(this.hoverClass);

                this.hoveredElement = null;
            }

            return this;
        },
    });
});

And this is the component's php file

class MultiplePrograms extends Select
{

    public function prepare() {
        $config = $this->getData('config');

        /** @var ArrayHelper $helper */
        $helper = ObjectManager::getInstance()->get(ArrayHelper::class);

        if (isset($config['tableOptions']) && $config['tableOptions'] instanceof ArrayInterface) {
            $config['tableOptions'] = $config['tableOptions']->toOptionArray();
        } else {
            throw new \Exception('Missing tableOptions tag for multiple-options field');
        }

        if (isset($config['tableFields'])) {
            $config['tableFields'] = $helper->nameToColumn($config['tableFields']);
        } else {
            throw new \Exception('Missing tableValues tag for multiple-options field');
        }

        if (isset($config['tableValues']) && $config['tableValues'] instanceof ArrayInterface) {
            $config['tableValues'] = $config['tableValues']->toOptionArray();
        }

        if (isset($config['options']) && $config['options'] instanceof ArrayInterface) {
            $config['options'] = $config['options']->toOptionArray();
        }

        $this->setData('config', (array)$config);

        parent::prepare();
    }
}

I wan't to be able to store information in the value of this component so that it can be passed to the controller later

0

I found out why this was happening. The reason it was throwing that error is because this.value() contained all the form data and thus by setting this.value({anything}) to anything, would clear all of the fields stored and trigger the errors and the observers.

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.