Problem with custom modules

2041
6
10-16-2013 07:37 AM
PeterMcBride
New Contributor
Hi All,

I am trying to practice accessing content from custom modules using the Home Button sample from the API tutorials. I have saved the HomeButton.js and the HTML page in the folder structure which is attached as images.

I have written the following HTML page to load the HomeButton but I get an "Object doesn't support this action" error when the page attempts to create a new HomeButton object.

I suspect that the issue is with the way I have entered the path to my custom module but I have tried loads of combinations and cant seem to find a solution.

The code is below and any help would be greatly appreciated!

Peter

<!DOCTYPE HTML>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <title>Home Extent Button Dijit</title>
    <link rel="stylesheet" type="text/css" href="http://js.arcgis.com/3.7/js/esri/css/esri.css">
    <link rel="stylesheet" type="text/css" href="http://js.arcgis.com/3.7/js/dojo/dijit/themes/claro/claro.css">
    <link rel="stylesheet" type="text/css" href="./ERMWidgets/css/HomeButton.css">
    <style type="text/css">
    body{
            margin:40px;
            padding:20px;
        }
        .container{
            position:relative;
            padding: 10px;
            border: 1px solid #eee;
            -webkit-border-radius: 3px;
            border-radius: 3px;
        }
        #map{
            width:100%;
            height: 500px;
            position: relative;
        }
        #HomeButton{
            position: absolute;
            top:95px;
            left: 20px;
            z-index: 50;
        }
    </style>
</head>
<body class="claro">
    <div class="container">
        <div id="map" class="map">
            <div id="HomeButton"></div>
        </div>
    </div>
    <h2>All Options</h2>

    <script src="http://js.arcgis.com/3.7/" type="text/javascript"></script>
    <script type="text/javascript">

       var dojoConfig = {
            async: true,
            parseOnLoad: true,
            isDebug: true,
            packages:[{
                "name": "ERMWidgets",
                "location": location.pathname.replace(/\/[^/]+$/, '') + "/ERMWidgets/"
            }]
        };

        require(["esri/map", "ERMWidgets/HomeButton", "dojo/on"], function(Map, HomeButton, on){

            var myMap = new Map("map", {
                center: [-56.049, 38.485],
                zoom: 3,
                basemap: "streets"
            });

            
            
            var myWidget = new HomeButton({
                map: myMap
            },"HomeButton");
            
            myWidget.on('home', function(obj){
                 console.log(obj);
            });
            
            myWidget.startup();
            
            

        });
    </script>
</body>
</html>
0 Kudos
6 Replies
JeffPace
MVP Alum
why are you saving out the hombutton.js instead of just calling it?

require(["esri/dijit/HomeButton", ... ], function(HomeButton, ... ){ ... });
0 Kudos
by Anonymous User
Not applicable
Original User: peterm_erm

I am using the Home Button as a tester for defining custom modules. I know that it is now available as part of the latest API update but it is also the example used for defining custom modules in the API tutorials.

Thanks

Peter
0 Kudos
PeterMcBride
New Contributor
An update to this, I have done some more digging and using the developer tools in IE9 I can see that the requests are going to the right places so I am certain that my relative paths etc are working correctly. I have also updated the code to an example from the API samples so it now looks like this:

    <script>
          var package_path = window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')); 
          var dojoConfig = { 
          packages: [{        
          name: "ERMWidgets",        
          location: package_path + "/ERMWidgets"      
          }]    
          };    
          </script>
    <script type = text/javascript src="http://js.arcgis.com/3.7/"></script>
    <script type="text/javascript">


However I am still getting the 'Script445: Object doesn't support this action' error.

Any help would be gratefully recieved as I have been stuck on this for days!!

Peter
0 Kudos
by Anonymous User
Not applicable
Original User: mattdriscoll

An update to this, I have done some more digging and using the developer tools in IE9 I can see that the requests are going to the right places so I am certain that my relative paths etc are working correctly. I have also updated the code to an example from the API samples so it now looks like this:

    <script>
          var package_path = window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')); 
          var dojoConfig = { 
          packages: [{        
          name: "ERMWidgets",        
          location: package_path + "/ERMWidgets"      
          }]    
          };    
          </script>
    <script type = text/javascript src="http://js.arcgis.com/3.7/"></script>
    <script type="text/javascript">


However I am still getting the 'Script445: Object doesn't support this action' error.

Any help would be gratefully recieved as I have been stuck on this for days!!

Peter


Seems like it's probably something in the module then. Is it returning a define function correctly?
0 Kudos
PeterMcBride
New Contributor
Seems like it's probably something in the module then. Is it returning a define function correctly?


Hi Matt,

I think the module is working correctly. I have modified it slightly from your GitHub version (mostly changing the definedClass and I removed the esri namespace section at the bottom as I didnt think I needed that?). I have included the code below, would you mind taking a quick look at it?

Thanks for your help.

Peter

define([
    
    "dijit/_WidgetBase",
    "dijit/_OnDijitClickMixin",
    "dijit/_TemplatedMixin",

    "dojo/Evented",
    "dojo/_base/declare",
    "dojo/_base/lang",

    "dojo/on",
    // load template    
    "dojo/text!ERMWidgets/templates/HomeButton.html",
    "dojo/dom-class",
    "dojo/dom-style"
],
function (
    Evented, declare, lang,
    _WidgetBase, _OnDijitClickMixin, _TemplatedMixin,
    on,
    dijitTemplate, 
    domClass, domStyle
) {
    var Widget = declare([_WidgetBase, _OnDijitClickMixin, _TemplatedMixin, Evented], {
        declaredClass: "ERMWidgets.HomeButton",
        templateString: dijitTemplate,
        options: {
            theme: "HomeButton",
            map: null,
            extent: null,
            visible: true
        },
        // lifecycle: 1
        constructor: function(options, srcRefNode) {
            // mix in settings and defaults
            declare.safeMixin(this.options, options);
            // widget node
            this.domNode = srcRefNode;
            this._i18n = i18n;
            // properties
            this.set("map", this.options.map);
            this.set("theme", this.options.theme);
            this.set("visible", this.options.visible);
            this.set("extent", this.options.extent);
            // listeners
            this.watch("theme", this._updateThemeWatch);
            this.watch("visible", this._visible);
            // classes
            this._css = {
                container: "homeContainer",
                home: "home",
                loading: "loading"
            };
        },
        // start widget. called by user
        startup: function() {
            // map not defined
            if (!this.map) {
                this.destroy();
                console.log('HomeButton::map required');
            }
            // when map is loaded
            if (this.map.loaded) {
                this._init();
            } else {
                on(this.map, "load", lang.hitch(this, function() {
                    this._init();
                }));
            }
        },
        // connections/subscriptions will be cleaned up during the destroy() lifecycle phase
        destroy: function() {
            this.inherited(arguments);
        },
        /* ---------------- */
        /* Public Events */
        /* ---------------- */
        // home
        // load
        /* ---------------- */
        /* Public Functions */
        /* ---------------- */
        home: function() {
            var defaultExtent = this.get("extent");
            this._showLoading();
            if(defaultExtent){
                return this.map.setExtent(defaultExtent).then(lang.hitch(this, function(){
                    this._hideLoading();
                    this.emit("home", {extent: defaultExtent});
                }));
            }
            else{
                this._hideLoading();
                console.log('HomeButton::no home extent');
            }
        },
        show: function(){
            this.set("visible", true);  
        },
        hide: function(){
            this.set("visible", false);
        },
        /* ---------------- */
        /* Private Functions */
        /* ---------------- */
        _init: function() {
            this._visible();
            if(!this.get("extent")){
                this.set("extent", this.map.extent);   
            }
            this.set("loaded", true);
            this.emit("load", {});
        },
        _showLoading: function(){
            domClass.add(this._homeNode, this._css.loading);
        },
        _hideLoading: function(){
            domClass.remove(this._homeNode, this._css.loading);
        },
        _updateThemeWatch: function(attr, oldVal, newVal) {
            domClass.remove(this.domNode, oldVal);
            domClass.add(this.domNode, newVal);
        },
        _visible: function(){
            if(this.get("visible")){
                domStyle.set(this.domNode, 'display', 'block');
            }
            else{
                domStyle.set(this.domNode, 'display', 'none');
            }
        }
    });
    return Widget;
});
0 Kudos
by Anonymous User
Not applicable
Original User: mattdriscoll

Hi Matt,

I think the module is working correctly. I have modified it slightly from your GitHub version (mostly changing the definedClass and I removed the esri namespace section at the bottom as I didnt think I needed that?). I have included the code below, would you mind taking a quick look at it?

Thanks for your help.

Peter

define([
    
    "dijit/_WidgetBase",
    "dijit/_OnDijitClickMixin",
    "dijit/_TemplatedMixin",

    "dojo/Evented",
    "dojo/_base/declare",
    "dojo/_base/lang",

    "dojo/on",
    // load template    
    "dojo/text!ERMWidgets/templates/HomeButton.html",
    "dojo/dom-class",
    "dojo/dom-style"
],
function (
    Evented, declare, lang,
    _WidgetBase, _OnDijitClickMixin, _TemplatedMixin,
    on,
    dijitTemplate, 
    domClass, domStyle
) {
    var Widget = declare([_WidgetBase, _OnDijitClickMixin, _TemplatedMixin, Evented], {
        declaredClass: "ERMWidgets.HomeButton",
        templateString: dijitTemplate,
        options: {
            theme: "HomeButton",
            map: null,
            extent: null,
            visible: true
        },
        // lifecycle: 1
        constructor: function(options, srcRefNode) {
            // mix in settings and defaults
            declare.safeMixin(this.options, options);
            // widget node
            this.domNode = srcRefNode;
            this._i18n = i18n;
            // properties
            this.set("map", this.options.map);
            this.set("theme", this.options.theme);
            this.set("visible", this.options.visible);
            this.set("extent", this.options.extent);
            // listeners
            this.watch("theme", this._updateThemeWatch);
            this.watch("visible", this._visible);
            // classes
            this._css = {
                container: "homeContainer",
                home: "home",
                loading: "loading"
            };
        },
        // start widget. called by user
        startup: function() {
            // map not defined
            if (!this.map) {
                this.destroy();
                console.log('HomeButton::map required');
            }
            // when map is loaded
            if (this.map.loaded) {
                this._init();
            } else {
                on(this.map, "load", lang.hitch(this, function() {
                    this._init();
                }));
            }
        },
        // connections/subscriptions will be cleaned up during the destroy() lifecycle phase
        destroy: function() {
            this.inherited(arguments);
        },
        /* ---------------- */
        /* Public Events */
        /* ---------------- */
        // home
        // load
        /* ---------------- */
        /* Public Functions */
        /* ---------------- */
        home: function() {
            var defaultExtent = this.get("extent");
            this._showLoading();
            if(defaultExtent){
                return this.map.setExtent(defaultExtent).then(lang.hitch(this, function(){
                    this._hideLoading();
                    this.emit("home", {extent: defaultExtent});
                }));
            }
            else{
                this._hideLoading();
                console.log('HomeButton::no home extent');
            }
        },
        show: function(){
            this.set("visible", true);  
        },
        hide: function(){
            this.set("visible", false);
        },
        /* ---------------- */
        /* Private Functions */
        /* ---------------- */
        _init: function() {
            this._visible();
            if(!this.get("extent")){
                this.set("extent", this.map.extent);   
            }
            this.set("loaded", true);
            this.emit("load", {});
        },
        _showLoading: function(){
            domClass.add(this._homeNode, this._css.loading);
        },
        _hideLoading: function(){
            domClass.remove(this._homeNode, this._css.loading);
        },
        _updateThemeWatch: function(attr, oldVal, newVal) {
            domClass.remove(this.domNode, oldVal);
            domClass.add(this.domNode, newVal);
        },
        _visible: function(){
            if(this.get("visible")){
                domStyle.set(this.domNode, 'display', 'block');
            }
            else{
                domStyle.set(this.domNode, 'display', 'none');
            }
        }
    });
    return Widget;
});


Ah, it looks like the define arguments are out of order.

They should be like this:

_WidgetBase, _OnDijitClickMixin, _TemplatedMixin,
    Evented, declare, lang,
0 Kudos