1

I'm trying to extend customer address page, but it's overriding. I want to inject in the middle of the address tab form.

My Code is:

Learning/CustomerAddress/composer.json

{
    "name": "learning/CustomerAddress",
    "description": "Customer Address",
    "require": {
        "php": "~5.5.0|~5.6.0|~7.0.0",
        "magento/framework": "100.0.*",
        "magento/module-ui": "100.0.*",
        "magento/module-config": "100.0.*",
        "magento/module-customer": "100.0.*"
    },
    "type": "magento2-module",
    "version": "100.0.0",
    "license": [
        "OSL-3.0",
        "AFL-3.0"
    ],
    "autoload": {
        "files": [ "registration.php" ],
        "psr-4": {
            "Learning\\CustomerAddress\\": ""
        }
    }
}

Learning/CustomerAddress/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Learning_CustomerAddress',
    __DIR__
);

Learning/CustomerAddress/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Learning_CustomerAddress" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Customer"/>
        </sequence>
    </module>
</config>

Learning/CustomerAddress/view/adminhtml/ui_component/customer_form.xml

0 Learning_Custom/form/my-template

Learning/CustomerAddress/view/adminhtml/web/template/form/my-template.html

  <h1>Magento 2 Customer Address </h1>
<div>
    <button type="button" onclick="test();">Click Me!</button>
</div>
<br/>
<script type="text/javascript">
    function test(){
        alert('Click Me!!!!!');
    }
</script>

Now it's showing my button, when I clicked on that it's not taken action.

enter image description here

Could you please suggest me how to do it?

  • @SohelRana, Any suggestions/help? – Bojjaiah Jan 21 '16 at 11:04
  • I want to inject in middle of the tab how to do it? -> What does it mean? could you share your screen? – Sohel Rana Jan 21 '16 at 17:35
  • @SohelRana, actually i'm trying to do like this thread. But I think directly inject the button is not possible. So, I'm planning to create a separate custom module then inject those customization without disturbing like you created AdditionalShippingBlock Custom Module. – Bojjaiah Jan 22 '16 at 5:28
  • @SohelRana, did you get a chance to look on my thread? – Bojjaiah Jan 29 '16 at 14:41
  • Sorry, Nope @magento two – Sohel Rana Jan 29 '16 at 16:33
2

Extending @magento two's answer, I've managed to find a way to somewhat extend the web/js objects while still maintaining the original JS object's constructors and functions are available.

I've done this by adding a RequireJS map of the core module name (internal to Magento, in this case it is a string "Magento_Ui/js/form/element/abstract") that points to my custom Javascript. This is exactly what @magento two did.

Although this works, I've commented that the core code at the path "dir/Magento_Ui/js/form/element/abstract.js" never gets loaded. To fix this, rather hackishly I'll admit, is to add a RequireJS path variable that points to the magento core Javascript file. I then inject it into my custom js (which initializes the core file, and gives me access to all of its properties / methods etc)

I extended adminhtml, but you could easily apply this to base, or frontend.

MyCompany/MyModule/view/adminhtml/requirejs-config.js

var fullHost;
if (!window.location.origin) {
    fullHost = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');
} else {
    fullHost = window.location.origin;
}


var config = {
    paths: {
        "originalAbstract": fullHost + "/pub/static/adminhtml/Magento/backend/en_US/Magento_Ui/js/form/element/abstract"
    },
    map: {
        '*': {
            default:    'Stti_Customer/js/default',
            'Magento_Ui/js/form/element/abstract':  'Stti_Customer/js/default'
        }
    }
};

MyCompany/MyModule/view/adminhtml/web/js/default.js

define(['jquery','originalAbstract'], function($, Abstract) {
"use strict";

return Abstract.extend({

    /**
     * Invokes initialize method of parent class,
     * contains initialization logic
     */
    initObservable: function () {
        // Add jquery event observers observers
        debugger;
        switch(this.index){
            // Do things related to the current object's name
        }

        this._super();

        return this;
    }
});

});

This workaround is probably due to an interesting conflict between Zend's "Where it is, is What it is, is What it does" naming conventions vs RequireJS module names. I'll also admit there is probably a better way to get the Filename for the core Javascript file, but I'm not there yet!

  • I will back after I tried – Bojjaiah May 9 '16 at 13:46
  • fixed a bug assigning fullhost using the else statement. You have to have it for it work. Also added this._super(); call. – CarComp May 9 '16 at 14:03
  • Hi the above two files is enough or I need to add my files also? – Bojjaiah May 9 '16 at 14:51
  • 1
    You will need your files to make the button work. Also, I'm working on a knockout implementation that will handle the click events. I think jQuery is not the right approach. I'm working on it. – CarComp May 9 '16 at 14:58
  • Ok, that's great. I will tried as your approach and back to you. – Bojjaiah May 9 '16 at 15:13
1

Finally I have solved my self by fallowing below steps:

Learning/CustomerAddress/view/base/requirejs-config.js

var config = {
    map: {
        '*': {
            'Magento_Ui/js/form/components/collection':  'Learning_CustomerAddress/js/form/components/collection'
        }
    }
};

Learning/CustomerAddress/view/base/web/js/form/collection.js

define([
    'underscore',
    'mageUtils',
    'uiRegistry',
    'uiComponent',
    'uiLayout',
    'Magento_Ui/js/modal/confirm'
], function (_, utils, registry, Component, layout, confirm) {
    'use strict';

    return Component.extend({
        defaults: {
            lastIndex: 0,
            template: 'Learning_CustomerAddress/form/components/collection'
        }

    });
});

Learning/CustomerAddress/view/base/web/template/form/components/collection.html

<div>
    <button type="button" data-bind="click: $parent.sendAddress.bind($parent, element)">
        Click Me!
    </button>
</div>
<br/>
  • You've essentially replaced the core capabilities with your custom collection.js. Watch out if you upgrade. – CarComp May 6 '16 at 19:43
  • 1
    @CarComp If you have better solutions please post your answer. – Bojjaiah May 9 '16 at 5:02
  • Sure... I'm working on the same problem. I'll post below. – CarComp May 9 '16 at 12:11
1
+50

I suppose you can expand an existing fieldset by adding Magento Ui Component Container. If you will look at Magento/Customer/view/base/ui_component/customer_form.xml, you can find an example of container usage:

<container name="street_container">
    <argument name="data" xsi:type="array">
        <item name="type" xsi:type="string">group</item>
        <item name="config" xsi:type="array">
            <item name="component" xsi:type="string">Magento_Ui/js/form/components/group</item>
            <item name="label" xsi:type="string" translate="true">Street Address</item>
            <item name="required" xsi:type="boolean">true</item>
            <item name="dataScope" xsi:type="string">street</item>
            <item name="sortOrder" xsi:type="string">45</item>
        </item>
    </argument>
    ...
</container>

To extend fieldset "address" you can add container your container as a child element of the fieldlist. Also you can define sort order of this conatainer (I put it just after the Street container):

Learning/CustomerAddress/view/adminhtml/ui_component/customer_form.xml

<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Ui/etc/ui_configuration.xsd">
    <fieldset name="address">
        <container name="custom">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="sortOrder" xsi:type="string">46</item>
                    <item name="template" xsi:type="string">Learning_Custom/form/my-template</item>
                </item>

                <item name="buttons" xsi:type="array">
                    <item name="add" xsi:type="array">
                        <item name="name" xsi:type="string">add</item>
                        <item name="label" xsi:type="string" translate="true">Add New Item</item>
                        <item name="class" xsi:type="string">primary</item>
                        <item name="url" xsi:type="string">*/*/new</item>
                    </item>
                </item>
            </argument>
        </container>
    </fieldset>
</form>
  • great work. It's working fine. But I want to insert a button on same location and when user clicks I want to call custom controller with parameter address_id. Can you please tell me how to do it?. – Bojjaiah Feb 1 '16 at 7:38
  • see my above thread. any help/suggestions? – Bojjaiah Feb 1 '16 at 9:49
  • 1
    I think you can add button in customer_form.xml (I've updated my answer). Also you can find more details at magento.stackexchange.com/questions/97291/… – Arkadii Chyzhov Feb 1 '16 at 9:56
  • it's creating button on top of the form. I'm created button inside the address form see my thread image. When I clicked on button just send the address_id to controller. that's it. – Bojjaiah Feb 1 '16 at 13:15
  • I've seen your another question. As there is no UI Component 'Button', you should try to create your own. Or find out a workaround with button in a template and add scripts to procced this button – Arkadii Chyzhov Feb 1 '16 at 22:47

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.