6

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?

  • I had tried to keep button code directly into the magento2\app\code\Magento\Ui\view\base\web\templates\form\components\collection\preview.html file. after execute grunt for backend its seem as button. Have you tried it ? – Praful Rajput Oct 24 '15 at 12:04
  • 1
    Command seem fine. You are neaer around your solution now. Are you using master or develop branch? No matter , please run composer update command. – Praful Rajput Oct 26 '15 at 7:05
  • 1
    have you follow gruntjs.com/getting-started for grunt ? Because there might be some issue from grunt installation. Please install it proper and then try. you can try grunt exec:all – Praful Rajput Oct 26 '15 at 8:37
  • 1
    devdocs.magento.com/guides/v2.0/frontend-dev-guide/css-topics/… please read here about grunt installation and its uses. – Praful Rajput Oct 26 '15 at 8:39
  • 1
    Empty your pub/static/ (do not delete .htaccess). Refresh your browser. Error should not be come there while you execute grunt. Please resolve your grunt issue. php bin/magento setup:static-content-deploy – Praful Rajput Oct 26 '15 at 9:10
3

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.

  • Thanks for reply. after modifying collection.html file I run grunt exec:backend command but it's returning grunt is not recognize internal or external command error. – Bojjaiah Oct 26 '15 at 5:03
  • 1
    First you must install npm and grunt tool. gruntjs.com/getting-started – Yogesh Karodiya Oct 26 '15 at 5:32
  • I ran after installing grunt. it's returning error Loading "Gruntfile.js" tasks...ERROR >> Error: Cannot find module 'magento2-develop' Warning: Task "exec:backend" not found. Use --force to continue. Aborted due to warnings. when i ran C:\xampp\htdocs\magento2-develop>grunt exec:backend – Bojjaiah Oct 26 '15 at 6:21
  • 1
    confirm you have package.json and Gruntfile in your root folder and and after completing all steps given in above link you should have 'node_modules' folder in your root folder and all grunt plugins should installed in it which are defined in package.json. – Yogesh Karodiya Oct 26 '15 at 8:46
  • Generatefile.js, package.json and node_modules folders are created and installed all grunt commands after that I got Error: grunt exec:backend Loading "Gruntfile.js" tasks...ERROR >> TypeError: _.each is not a function Running "clean:backend" (clean) task >> 0 paths cleaned. Done, without errors. Gathering css/styles-old.less sources. Successfully processed dynamic stylesheet into CSS Gathering css/styles.less sources. Successfully processed dynamic stylesheet into CSSDone, without errors.. – Bojjaiah Oct 26 '15 at 9:06
4
+25

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.

  • thanks for answering. I will get back to you after I tried. – Bojjaiah Oct 23 '15 at 10:45
  • I have updated as you instructed and it's running without errors but it's showing textbox instead of button. I have updated my post please look on that. – Bojjaiah Oct 23 '15 at 14:18
  • @magentotwo did you add the definition for the element template? – David Manners Oct 23 '15 at 14:35
0

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

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.