Question

I'm trying to add button in customer address form. But I don't know how to do it from customer_form.xml file. If any one knows please suggest me.

enter image description here

I have registered button control on ui_definition.xsd and ui_components.xsd file but still it's showing like textbox instead of button.

My Code is

Magento/Ui/etc/ui_definition.xsd

<xs:complexType name="definition">
        <xs:annotation>
            <xs:appinfo>Registering components in the system and basic setup</xs:appinfo>
            <xs:documentation>Registering components in the system and basic setup</xs:documentation>
        </xs:annotation>
        <xs:all>
            <!-- Components list -->
            <xs:element type="tab" name="tab"/>
            <xs:element type="dataSource" name="dataSource"/>
            <xs:element type="paging" name="paging"/>
            <xs:element type="massaction" name="massaction"/>
            ..... etc
            <!--Custom Button Start-->
            <xs:element type="button" name="button"/>
            <!--Custom Button End-->
        </xs:all>
    </xs:complexType>

Magento/Ui/etc/ui_components.xsd

<!--Custom Button Start-->
    <xs:complexType name="button">
        <xs:complexContent>
            <xs:extension base="ui_element">
                <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:group ref="configurable"/>
                </xs:choice>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <!--Custom Button End-->

and I have created Class Button.php from Magento/Ui/Component/Form/Element

<?php

namespace Magento\Ui\Component\Form\Element;

/**
 * Class Button
 */
class Button extends AbstractElement
{
    const NAME = 'button';

    /**
     * Get component name
     *
     * @return string
     */
    public function getComponentName()
    {
        return static::NAME;
    }
}

and finally I have created field from customer_form.xml file

<field name="button">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="visible" xsi:type="boolean">true</item>
                    <item name="dataType" xsi:type="string">button</item>
                    <item name="formElement" xsi:type="string">input</item>
                </item>
            </argument>
        </field>

Running without errors but it's showing textbox instead of button. Could you please suggest me where I went wrong?

Was it helpful?

Solution

I am not sure it is correct way but it worked for me

app/code/Magento/Ui/view/base/web/templates/form/components/collection.html

<li class="address-list-item" data-bind="css: { 'ui-state-active': element.active }, click: activate">
          // put your code here

but best way is not change directly here you can override this file in your custom module.

do not forget to flush cache folder as well as static content and run grunt exec:backend command after change this file.

OTHER TIPS

Sorry that this is not a complete answer but more a pointing in the "right" direction.

There are a set of elements that can be called inside the Magento/Ui system. These can be found under app/code/Magento/Ui/Component/Form/Element/.

Here by default you will see:

  1. Checkbox.php
  2. Input.php
  3. Multiline.php
  4. MultiSelect.php
  5. Radio.php
  6. Range.php
  7. Select.php
  8. Textarea.php

These elements are set-up in the definition file app/code/Magento/Ui/view/base/ui_component/etc/definition.xml. For example the checkbox looks like the following:

<checkbox class="Magento\Ui\Component\Form\Element\Checkbox">
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="component" xsi:type="string">Magento_Ui/js/form/element/boolean</item>
            <item name="config" xsi:type="array">
                <item name="template" xsi:type="string">ui/form/field</item>
                <item name="elementTmpl" xsi:type="string">ui/form/element/checkbox</item>
            </item>
        </item>
    </argument>
</checkbox>

From what I can see from my quick looking around it should be possible to add your own type via this sort of definition, though I am not sure about the workings. You will need to add your own element template here, the defaults can be found under app/code/Magento/Ui/view/base/web/templates/form/element/*.html

You can see that the definition.xml file is added via di as follows:

<virtualType name="uiDefinitionFileCollector" type="Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollector">
    <arguments>
        <argument name="searchPattern" xsi:type="string">etc/definition.xml</argument>
    </arguments>
</virtualType>

So you should be able to add your own definition.xml file to your module and it will be picked up.

Sorry this is not a complete answer but it should be a good start in the "right" direction.

I have written today a simple way of implementing your requirement using mixins.

to setup the mixin, create a requirejs-config.js file in your view/base folder of a module that will host the mixin

var config = {
    config: {
        mixins: {
            'Magento_Ui/js/form/components/collection': {              
            'Mbs_AddButtonInCustomerAddressForm/js/address/collection':true
            }
        }
    }
}

then in the js file defined in the mixin above: you may overwrite the template so that it does use a template in your module

a sample of the js file is below:

define([], function () {
    'use strict';

    return function (addressCollection) {
        const orig = addressCollection.defaults;
        orig.template = 'Mbs_AddButtonInCustomerAddressForm/collection';
        orig.buttonExtraLabel = 'Click Me';

        return addressCollection;
    }
});

finally in the custom template, you can add the button.

This solution will not touch the core file from Magento and therefore you will remain compliant with further releases from Magento

I have a full code repository showing how to do the url keys and url rewrite at: https://bitbucket.org/magstaging/addbuttonincustomeraddressform

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top