Select to view content in your preferred language

Template Picker not loading in hidden accordianpane, same code works if pane is vis

1637
5
Jump to solution
10-10-2013 12:00 PM
JeffPace
MVP Alum
So I have an Accordian Pane, in an Accordian Container, in a TabContainer, in an ExpandoPane

If I load an edit widget, the editbar loads, but the template picker is empty.  No amount of refreshing it makes it populate.

HOWEVER

If I click on the Editing Tab quick enough so that the pane is visible when the editor dijit creates, it loads fine.

??????

Code for editorWidget

 createEditing: function(fArray){               var layers = dojo.map(fArray, function(layer) {           var fieldInfos= dojo.map(layer.fields,function(field){             if(field.name === 'description'){               return {'fieldName': field.name,'label':'Details'};             }             else{               return {'fieldName': field.name,'label':field.alias};             }           });           return {featureLayer:layer,'fieldInfos':fieldInfos};         });            var settings = {           map: map,           enableUndoRedo:true,           layerInfos:layers,           toolbarVisible: true,           createOptions: {             polygonDrawTools: [                esri.dijit.editing.Editor.CREATE_TOOL_FREEHAND_POLYGON,               esri.dijit.editing.Editor.CREATE_TOOL_AUTOCOMPLETE             ]           },           toolbarOptions: {             reshapeVisible: true,             cutVisible: true,             mergeVisible: true           }         };         var params = {settings: settings};          editorWidget = new esri.dijit.editing.Editor(params,'editorDiv');                editorWidget.startup();            }


link to live

http://www.mymanatee.org/gisapps/mapviewer/mobile/mobiletest.html
0 Kudos
1 Solution

Accepted Solutions
MattLane
Frequent Contributor
I'm going to guess it's because the 'hidden' div has no height element yet.
You could try a couple things

  1. Mess with css until it has a height, like make the div and it's container(s) 100%. Will probably be a lot of trial and error.

  2. Don't call the createEditing function till the editing tab is selected

I would suggest option 2 because it reduces initial page load time, and never loads that stuff at all if the user never selects the editing tab.

View solution in original post

0 Kudos
5 Replies
MattLane
Frequent Contributor
I'm going to guess it's because the 'hidden' div has no height element yet.
You could try a couple things

  1. Mess with css until it has a height, like make the div and it's container(s) 100%. Will probably be a lot of trial and error.

  2. Don't call the createEditing function till the editing tab is selected

I would suggest option 2 because it reduces initial page load time, and never loads that stuff at all if the user never selects the editing tab.
0 Kudos
JeffPace
MVP Alum
I appreciate the insight.  I agree with #2, i lazy load in the background but maybe I shouldn't unless its needed.

Still think I should be able to load in the background.,.
0 Kudos
JeffPace
MVP Alum
#2 worked perfectly thank you
0 Kudos
BenFousek
Deactivated User
Hey Jeff,
This may or may not be of assistance to you in general; I assume you won't stretch out the seams in putting on the coat. Your post caught I attention, it's Friday, and I feel like sharing; so let me expand on Matt's concept a little bit and talk about loading content and functionality using on demand loading with content panes or any widget which extends dijit/_Container. You can load html, including widgets, and javascript placed in a html file by using the href property of a content pane. By default a content pane only loads the href on first show. So content loaded into a accordion pane via a href, which isn't initially visible, isn't loaded until the user clicks on it. As far as executing javascript on load there are a couple options available with dijit.layout.ContentPane and dojox.layout.ContentPane, which can be found in dojo docs.

This is especially handy in an app with a lot of little tasks and tools with varying levels of usage. Some might get used a few times daily or maybe once a week. Below is the html for my "poor developer's widget" for measuring, which is html/measure.html relative to the application. Measure is initiated from a toolbar button. The floating pane and button are created in the init of the application with the floating pane's href property set to the html file. It only loads when the user first shows the floating pane by clicking the button. Because I have one global variable/object app, which I create everything in, it's easy to extend as needed. You'll notice that I call a lot of functions and use objects which already exist as part of the application, e.g. functions for controlling map click events. This is one reason I started getting away from true widgets for this sort of thing; either I was using globals directly or passing them as variables to the widget. It always ended up being more code than doing it this way.

It's also a great way to load custom mods and widgets on demand too using the on load abilities of the content pane.

[HTML]<div class="dojoxFloatingPaneWrapper">
<div data-dojo-type="dijit/form/Button" data-dojo-props="label: 'Loacation', showLabel: false, title: 'Location', iconClass: 'iconMeasurePnt', onClick: app.measure.location"></div>
    <div data-dojo-type="dijit/form/Button" data-dojo-props="label: 'Distance', showLabel: false, title: 'Distance', iconClass: 'iconMeasureDist', onClick: app.measure.distance"></div>
    <div data-dojo-type="dijit/form/Button" data-dojo-props="label: 'Area', showLabel: false, title: 'Area', iconClass: 'iconMeasureArea', onClick: app.measure.area"></div>
    <div data-dojo-type="dijit/form/Button" data-dojo-props="label: 'Clear', showLabel: false, title: 'Clear', iconClass: 'iconCross', onClick: app.measure.clear"></div>
    <div id="measure-results" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="style: 'padding:6px 0 0'"></div>
</div>
<script>
app.measure = {
  loaded: false,
  load: function () {
    app.measure.results = dijit.byId('measure-results');
    app.map.addLayer(app.measure.layer = new esri.layers.GraphicsLayer(), 0);
    app.measure.loaded = true;
  },
  location: function () {
    if (!app.measure.loaded) {
      app.measure.load();
    };
    app.measure.layer.clear();
    app.utility.reset.start();
    app.map.setMapCursor('crosshair');
    app.map.toaster.setContent('Click on the map to return location.');
    app.measure.results.destroyDescendants();
    app.measure.results.set('content', 'Click on the map to return location.');
    app.map.drawToolbar.activate('point');
    var on = app.map.drawToolbar.on('draw-end', function (result) {
      on.remove();
      app.utility.reset.end();
      app.map.drawToolbar.deactivate();
      app.measure.layer.add(new esri.Graphic(result.geometry, new esri.symbol.SimpleMarkerSymbol('cross', 20, new esri.symbol.SimpleLineSymbol('solid', new dojo.Color([255, 0, 255]), 2), new dojo.Color([255, 0, 255, 1])), null, null));
      var lat = result.geometry.getLatitude();
      var lng = result.geometry.getLongitude();
      var pp = new esri.tasks.ProjectParameters();
      pp.geometries = [result.geometry];
      pp.outSR = new esri.SpatialReference({
        wkid: 26910
      });
      esri.config.defaults.geometryService.project(pp, function (results) {
        app.measure.results.set('content', '<b>Latitude-Longitude</b><br />' + lat + '<br />' + lng + '<br />' + app.utility.dms.lat(lat) + '<br />' + app.utility.dms.lng(lng) + '<br /><b>UTM Zone 10N</b><br />N: ' + (Math.round(results[0].y * 1000) / 1000) + '<br />E: ' + (Math.round(results[0].x * 1000) / 1000));
      }, function (error) {
        console.log(error);
        app.error('A geometry service projection error has occurred.');
        app.measure.clear();
      });
    });
    app.utility.reset.on.push(on);
  },
  distance: function () {
    if (!app.measure.loaded) {
      app.measure.load();
    };
    app.measure.layer.clear();
    app.utility.reset.start();
    app.map.setMapCursor('crosshair');
    app.map.toaster.setContent('Click to add vertex; double-click to end and return distance.');
    app.measure.results.destroyDescendants();
    app.measure.results.set('content', 'Click to add vertex; double-click to end and return distance.');
    app.map.drawToolbar.activate('polyline');
    var on = app.map.drawToolbar.on('draw-end', function (result) {
      on.remove();
      app.utility.reset.end();
      app.map.drawToolbar.deactivate();
      app.measure.layer.add(new esri.Graphic(result.geometry, new esri.symbol.SimpleLineSymbol('solid', new dojo.Color([255, 0, 255]), 2), null, null));
      var length = esri.geometry.geodesicLengths([esri.geometry.webMercatorToGeographic(result.geometry)], esri.Units.FEET);
      app.measure.results.set('content', '<b>Length</b><br />' + (Math.round(length[0] * 100) / 100) + ' feet<br />' + (Math.round((length[0] / 5280) * 100) / 100) + ' miles');
    });
    app.utility.reset.on.push(on);
  },
  area: function () {
    if (!app.measure.loaded) {
      app.measure.load();
    };
    app.measure.layer.clear();
    app.utility.reset.start();
    app.map.setMapCursor('crosshair');
    app.map.toaster.setContent('Click to add vertex; double-click to end and return area.');
    app.measure.results.destroyDescendants();
    app.measure.results.set('content', 'Click to add vertex; double-click to end and return area.');
    app.map.drawToolbar.activate('polygon');
    var on = app.map.drawToolbar.on('draw-end', function (result) {
      on.remove();
      app.utility.reset.end();
      app.map.drawToolbar.deactivate();
      app.measure.layer.add(new esri.Graphic(result.geometry, new esri.symbol.SimpleLineSymbol('solid', new dojo.Color([255, 0, 255]), 2), null, null));
      var area = esri.geometry.geodesicAreas([esri.geometry.webMercatorToGeographic(result.geometry)], esri.Units.SQUARE_FEET);
      app.measure.results.set('content', '<b>Area</b><br />' + (Math.round(area[0] * 100) / 100) + ' sq. feet<br />' + (Math.round((area[0] / 43560) * 100) / 100) + ' acres');
    });
    app.utility.reset.on.push(on);
  },
  clear: function () {
    app.utility.reset.all();
    if (app.measure.layer) {
      app.measure.layer.clear()
    }
    if (app.measure.loaded) {
      app.measure.results.destroyDescendants();
    }
  }
};
</script>[/HTML]

I checked out your app. You might be able to improve load time and performance by loading some of your functionalities on demand.

I'm not sure how all this will play out with AMD. I'm preparing for full conversion, which with 6k lines of code just to load the app, it's a bit nerve racking. No reason to keep putting off the inevitable. 🙂

Have a great weekend!
Ben
0 Kudos
BenFousek
Deactivated User

My problem is: How can I move the
myEditor.startup();
to the div container of the editor accordion pane, so that the editor only loaded after expanding this pane.


The easy solution is to connect to the editor pane's on show event to start the editor.

1. The pane must have an id.
[HTML]<div id="editorPane" data-dojo-type="dijit.layout.ContentPane" title="Editor Tool">
  <div id="templateDiv"></div>
  <div id="editorDiv"></div>
</div>[/HTML]

2. Connect to the on show event.
//replace this
//myEditor.startup();
//with this

var editorStartup = dom.byId('editorPane').on('show', function () {
  editorStartup.remove(); //remove event else it will be called every time pane is shown
  myEditor.startup();
});