Magento 2 – Extend/Inject to Customer Address

customer-addressmagento-2.0magento2php-5.4uicomponent

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?

Best Answer

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!