Combine JavaScript Samples

1349
6
02-24-2012 07:29 AM
DanPajak
Occasional Contributor
I'm trying to combine 2 of the JavaScript samples, specifically the Identify & Find Results in DataGrid. I started with the latter and then tried to add/combine the identify. When I add the Identify HTML to the body at the bottom it appears on loading of the map. Any ideas on how to keep the identify pop-up hidden until it is clicked? I thought it might have something to do with a piece of code in the Find Sample near the top where it shows dojoConfig = { parseOnLoad:true } . I'm sort of new to Javascript and combining samples. I've been able to make a few of the others work together such as adding the Navigation toolbar but this is puzzling. I've attached the code as a .txt file. Ultimately I'd like to be able to use the Identify in multiple Apps and simply call it through the code from a particular source. Any help would be appreciated.
0 Kudos
6 Replies
DanPajak
Occasional Contributor
In the concepts section of the JavaScript API - Working with Dojo - Dojo Dijits it is stated:

If you have dijits that appear in your page when the application loads, you should include this line before adding the script tag that references the ArcGIS JavaScript API:
<script type="text/javascript">djConfig = { parseOnLoad: true }</script>

I have an Identify Tab Container that I do not want to appear on load, only when the user clicks the map. Is there a way to treat dijits individually? I have a another border container and content pain (search, map and datagrid) that I want to show on load, but I want my Identify tab container to be hidden until called.
0 Kudos
derekswingley1
Frequent Contributor
You want to create the dijits that will display in your info window programmatically (as opposed to declaratively, AKA with markup). This is shown in the InfoWindow with Chart sample.
0 Kudos
DanPajak
Occasional Contributor
Sorry for the delay in response Derek, I've been looking into the InfoWindow with Chart sample and also a simplified version of it from another thread by Kelly Hutchins @ http://forums.arcgis.com/threads/27337-Tabs-in-an-infoWindow.

Not sure if these are what I'm looking to do. I've used the Find Results in Datagrid to get a user to a particular address or property, then once there I'd like them to be able to click on multiple layers, i.e. Address and Parcel of adjacent locations. Just like the identify sample does, where I was able to have a tab for Address, Building, Street and Parcel. Being new to this and viewing the sample you linked me to I'm not sure how I can get multiple layer's rest endpoints to appear in specific tabs. Would I have to create multiple InfoTemplates? Or could I format the code to look at all the layers of a particular service?
0 Kudos
BenFousek
Occasional Contributor III
This is one method I use to add dijits to infoWindow template. This example loads a feature layer as part of the apps onLoad from a js object. The concept is the same for your needs.  Here's the object:
{
    type: 'feature',
    requireToken: true,
    url: 'http://SOME_URL/ArcGIS/rest/services/SOME_TOWN_IN_OREGON/Fire_Hydrants/MapServer/0',
    name: 'Fire Hydrants',
    id: 'fire_hydrants',
    outFields: ['*'],
    itTitle: 'Hydrant',
    itContentType: 'function', //'function' or 'text'
    itContent: '',
    itContentFunction: 'hydrant',
    visible: false,
    opacity: 1,
    legend: true,
    toc: true,
    info: false,
    infoHtml: ''
}

When it runs through this loop we set up the infoTemplate.
dojo.forEach(config.featureLayers, function(fl) {
    var url;
    if (fl.requireToken == true) {
        url = fl.url + '?token=' + config.app.token
    } else {
        url = fl.url
    }
    var it = new esri.InfoTemplate();
    it.setTitle(fl.itTitle);
    if (fl.itContentType == 'text') {
        it.setContent(fl.itContent);
    } else if (fl.itContentType == 'function') { //turns out we want some dijits in our infoWindow
        eval('it.setContent(viewer.itContentFunctions.' + fl.itContentFunction + ')') //set the content via a function; in this case viewer.itContentFunctions.hydrant; see below
    } else {
        it.setContent('There must not be any important info about this feature.');
    }
    var layer = new esri.layers.FeatureLayer(url, {
        mode: esri.layers.FeatureLayer.MODE_ONDEMAND,
        outFields: fl.outFields,
        infoTemplate: it,
        id: fl.id,
        visible: fl.visible,
        opacity: fl.opacity
    });
    if (fl.legend == true) { viewer.legendLayers.push({ layer: layer, title: fl.name }) }
    var info = '';
    if (fl.info == true) {
        info = fl.infoHtml
    }
    //toc controls
    viewer.map.addLayer(layer);
});

At this point the template is just a domNode and has not been rendered in a container object yet. Now when we click on a hydrant the infoWindow popups up because the graphic has a template, with that specific graphic's template domNode appearing in said infoWindow. In this example a function is connected to the buffer button's onClick event, which when clicked buffers the hydrant the specified distance and adds the geometry to the map.
[ATTACH=CONFIG]14868[/ATTACH]
var viewer = {
    itContentFunctions: {
        hydrant: function(graphic) {
            var x = Math.round(Math.random() * 1000000);
            var content = new dijit.layout.ContentPane({ style: 'padding:0;', content: '<div style="padding-bottom:6px;">Buffer this hydrant:</div><div id="hydrant_buffer_dist_' + x + '" dojoType="dijit.form.NumberSpinner" value="500" smallDelta="25" contraints="{min:100,max:1200,places:0}" style="width:80px;"></div>  <div id="hydrant_buffer_button_' + x + '" dojoType="dijit.form.Button">Buffer</div>' });
            dojo.connect(dijit.byId('hydrant_buffer_button_' + x), 'onClick', function() { viewer.itContentFunctions.hydrantBuffer(graphic.geometry, x); viewer.map.infoWindow.hide(); /* viewer.mapTipsShow('<img src="images/waiting_map_tips.gif" style="height:14px; width:14px;" /> Buffer in progress...');*/ });
            return content.domNode;
        },
        hydrantBuffer: function(geom, id) {
            viewer.map._layers.gl.clear();
            var params = new esri.tasks.BufferParameters();
            params.geometries = [geom];
            params.distances = [eval('parseInt(dijit.byId("hydrant_buffer_dist_' + id + '").value)')];
            params.unit = esri.tasks.GeometryService.UNIT_FOOT;
            params.outSpatialReference = viewer.map.spatialReference;
            viewer.geoSrv.buffer(params, function(geoms) {
                //viewer.mapTipsHide();
                var symbol = new esri.symbol.SimpleFillSymbol('solid', new esri.symbol.SimpleLineSymbol('solid', new dojo.Color([0, 0, 255]), 2), new dojo.Color([0, 0, 255, 0.25]));
                dojo.forEach(geoms, function(geometry) {
                    var graphic = new esri.Graphic(geometry, symbol, { ID: '7', __print: true, __whatAmI: 'a hydrant buffer', __addToMapSave: false, __style: { who: 'mxdSelect' }, __db: 'schema.gdb', __sdeDump: config.app.dumpUserGraphicsToSde });
                    viewer.map._layers.gl.add(graphic);
                    viewer.map.setExtent(graphic.geometry.getExtent(), true);
                });
            });
        }
    }
}

Here's the buffered hydrant:
[ATTACH=CONFIG]14874[/ATTACH]
Notice that I created a ContentPane and it's content in html. All the content could be created programmatically, but with simpler items it's easier to create a ContentPane and use it's content property. In your case, where you may have multiple tasks executing, a TabContainer and tabs I would probably build my own dijit (see No. 2 & 3 below).
You said you were just getting started. I don't know what your long term goals are, but if the shoe fits:
1) The arcgis js api just extends dojo. An above average understanding of how dojo works is important. http://dojotoolkit.org/documentation/ The reference guide and documentation are indispensable, as is the API reference.
2) Use Firefox for development with Firebug add-in. Use Firebug to dissect every last corner of the DOM related to the esri classes.
3) Creating modules, custom dijits, and working from a programmatic view point will make your life easier. For example, I've used the same custom measuring module for years. With two lines of code I can load the module and place it anywhere in the application (e.g. a tab, accordion pane, floating pane, etc). The three files for the module only exist once on my server. Write once, use many. Easy to update. Company A and Company B both have intranet web apps, but the measure module comes from the same place every time someone initiates its use. This same idea allows me to choose the api version for every app I have deployed by changing a single variable in one file on my server. When a new version comes out I test it out in the development environment and if there's no problems I update all my apps at once, by changing 2.7 to 2.8 for example.
4) All my apps' index.html look like this:
[HTML]<!DOCTYPE HTML>
<html>
    <head>
    </head>
    <body>
    </body>
</html>[/HTML]
The rest is programmatic. Many of my apps have measuring capabilities, but the module and the controls are only downloaded when the user first uses the module. This on-demand method keeps the app lean and quick. The code samples above come from a app I'm currently working on that has 20+ dynamic layers, 5+ feature layers, more tasks than I can count and 28 geoprocessing tasks. If I had to load all that onLoad it would take forever to load and be slow. Not to mention taxing on bandwidth.

Well Jeremy, I hope I didn't confuse you. I never post on the forum, but I noticed your post just as I was finishing up the hydrant buffer and thought I might weigh in for once. Good luck!
0 Kudos
DanPajak
Occasional Contributor
Thanks Ben,

I'll take some time to digest this. I agree with the your points 1 thru 4, concerning creating a file once and using it many times, makes perfect sense. I'm still getting acquainted with javascript, dojo and programming with the ArcGIS API for Javascript. I'll post back if I have any more questions.
0 Kudos
JohnnyPenet
New Contributor
Sometime ago I had to create a framework in Silverlight to replace the Web ADF development as it will be obsolete in future versions of ArcGis.
Afterwards I migrate this framework towards JavaScript keeping the same application patterns of Silverlight.
In my blog �??jpenet.blogspot.com�?? I describe how a possible framework could be build. The purpose was not to develop some general application
but a study how you can create libraries that could help you in making applications like was possible in web adf.
Little focus was done on visual aspects, keeping a very clean html page.

Hope this will illustrate how to start with ArcGis Javascript API.
0 Kudos