Adding button in Magento 2
-
13-12-2019 - |
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.
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?
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:
- Checkbox.php
- Input.php
- Multiline.php
- MultiSelect.php
- Radio.php
- Range.php
- Select.php
- 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