Search code examples
javascriptdojowidgetarcgisarcgis-js-api

Dojo widget not rendered correctly, when placed in inactive accordion container


I have a web application using the ArcGIS JS API with a bunch of custom widgets. If I place an esri/dijit/editing/TemplatePicker inside a ContentPane inside an Accordion container tab, which is inactive, when the page loads, the template picker does not render correctly.

Steps to reproduce:

  1. Load fiddle (http://jsfiddle.net/n9jwtgko/1/)
  2. Switch to the first accordion pane. The widget is just a border with no content
  3. Now change the selected pane by settings selected="true"

    <div data-dojo-type="dijit/layout/ContentPane" title="Heeh, this is a content pane" selected="true">
        <div id="templatePickerDiv"></div>
    </div>
    
  4. remove selected="true" from the second container
  5. refresh the fiddle

The widget now loads up correctly.

What exactly is happening here and how can I work around this?


Solution

  • The problem really seems to be either the templatepicker or the Accordion. If I remove either from the application it works just fine, so my plan was to make sure, the parser runs only after everything has finished - including events like layers-add-result.

    Since my application is already modularized into a mapLoader, widgets, services and so on, I decided to refactor the mapLoader into a deferred object.

    define([/*...*/, function(){
        var init = function() {
           return $.when(function(){
                     //bootstrap map
                     //bootstrap widgets
                     //create new Deferred object
                     var dfd = $.Deferred();
                     function initEditing() {
                        /*hook up the rest*/
                        //resolve promise once the templatepicker is up and running
                        dfd.resolve();
                     }
                     //return promise
                     return dfd.promise();
                  })
        };
        return {init: init}
    }])
    

    Now with that in place I can just go ahead in my startup file and call:

    define([
        "dojo/parser",
        "app/components/mapLoader.public",
        "dojo/domReady!"
    ], function (parser, MapLoader
    ) {
         //entry point into the application
         //authentication, configuration etc. omitted
    
         MapLoader.init().done(function () {
            parser.parse();
         });
    });
    

    This is the only way I found so far to make sure every widget is loaded, before the parser actually runs and does its black magic. Of Ccourse now I just need to clean everything up and replace jQuerys defferred object with the dojo implementation.