|
POST
|
I wrote a couple of blog posts that list some areas to get started with Dojo. Be a Dojo developer and more Getting your Dojo on - odoenet I think the main places to look are going to be the update Dojo docs. Dojo Tutorials - Dojo Toolkit They have really organized stuff much nicer than before. I think the modules section is important, especially the CDN lesson. But there is a plethora of good info in all the docs for you get familiar with it. There is also the sitepen blog. Hope that helps.
... View more
04-21-2015
02:02 PM
|
3
|
0
|
1719
|
|
BLOG
|
This is something you would manually set yourself. You can see how this is done in the sample on github. esri-layertoc-sample/run.js at master · odoe/esri-layertoc-sample · GitHub This can also be done when adding the layer via a JSON object that matches the webmap spec. ArcGIS web map JSON format - layer
... View more
04-16-2015
02:14 PM
|
0
|
0
|
1358
|
|
POST
|
Esri has an offline-editor-js library. Esri/offline-editor-js · GitHub I'm using an older version of this library in production and it works pretty well. I had some issues with it thinking it was offline when it wasn't that I had to tweak, but that is probably fixed by now. You could also DIY it using PouchDB, which I really like for offline editing. Taking it offline - odoenet
... View more
04-16-2015
10:44 AM
|
2
|
0
|
1229
|
|
POST
|
Code School has a free course on how to use Chrome Dev Tools. Chrome Dev Tools Tutorial - Code School FireBug and the newer IE11 debug tools are similar, so I think once you learn one, it's fairly easy to transition to others if you need to.
... View more
04-16-2015
07:55 AM
|
2
|
0
|
2330
|
|
BLOG
|
Esri-Leaflet is a fantastic library that will let you use ArcGIS Services with Leaflet. I won't go in to detail about Leaflet itself, you can read plenty about it online, but the main thing is that it has a very easy to understand API and a thriving community. It may not have all the bells and whistles that the ArcGIS API for JavaScript has to work with ArcGIS data, such as many of the ArcGIS widgets, but it does have a very extensive list of community maintained plugins and controls. I've talked about how to write a custom Leaflet control before. These extensive plugin and control libraries can also be used pretty seamlessly with Esri-Leaflet as well, after all, it's just another plugin built on top of Leaflet and that opens a wide door of possibilities! Swimming in Cache Let's start with an easy one. Say for example you needed to add some sort of offline functionality to your webmap, such as storing the tiles in case you lose a connection. There's a plugin for that! This plugin also requires that you add PouchDB to your application. PouchDB is great as it makes it very easy to handle the little nuances involved with browser support for various storage options, especially important on mobile devices. I've written about using PouchDB for ArcGIS JavaScript apps before. For this plugin, all you have to do is add it via a script tag and magically it will start storing the tiles in a local database for you when you add a single useCache:true option the basemapLayer. L.esri.basemapLayer('Topographic', {
useCache: true
}).addTo(map); Here is a demo. If you use something like the Chrome DevTools to view the IndexedDB for example, you can see the tile data being stored. That is pretty cool and all you have to do is pass an option the basemapLayer. The Plugin extends the TileLayer and so does the basemapLayer in Esri-Leaflet, so you get this functionality for free. Keeping it realtime Another neat plugin for Leaflet is the realtime plugin. The realtime plugin is cool because it can do realtime by either working with a pub/sub service or by polling a service that will provide updates. It's flexible in this regard. Of course ideally you would want your service to return data in GeoJSON. Once you have added this plugin to your project, you can just add it like any other layer and when it's updated, have the map follow the latest location. For fun, in this example, we are drawing a line as the location is updated to trace it's route. Now you can feel like you're working with Jack Bauer! var realtime = L.realtime({
url: 'https://wanderdrone.appspot.com/',
crossOrigin: true,
type: 'json'
}, {
interval: 3 * 1000
}).addTo(map).on('update', function(data) {
// trace the update path on the map
var coords = data.features.undefined.geometry.coordinates;
polyline.addLatLng(L.latLng(coords[1], coords[0]));
map.fitBounds(realtime.getBounds(), {
maxZoom: 3
});
}); Here is a working demo of this in action. Baby, it's cold outside There are a plenty of controls available for Leaflet as well. A control is usually distinguished from a plugin as a visual component that you can interact with or displays some information on the map (think widgets). Plugins usually provide some enhanced map functionality. A simple, yet useful control is the Weather widget. This widget requires jQuery and it's own css file, but once those are added, you can use it in your application. L.control.weather({
lang: "es",
units: "metric"
}).addTo(map); Here is a demo of the widget. Lean on your friends This is only a tiny sample of how you can incorporate plugins and controls into your application. Leaflet has a very active community and there are lots of plugins and controls available for it. So if you are using the Esri-Leaflet plugin to work ArcGIS Online or ArcGIS Server services, you now have access to a whole variety of tools you just might find useful. Esri-Leaflet even has components that are separate plugins like a Heatmap FeatureLayer. For more geodev tips and tricks, check out my blog.
... View more
04-15-2015
01:16 PM
|
1
|
0
|
2261
|
|
BLOG
|
Every now and then I'm asked to make a map do something it normally wouldn't do, but actually makes perfect sense. Astonishing, I know. A while ago a user asked if the map could save some information if they had to close the browser and come back later. One of these things was the maps last location. They also wanted auto-save in edits and other things, but the same methods applied here will work for that as well. So I set out like a happy little developer and of course I thought, I'll just use windows.onunload, actually onbeforeunload is the recommended way, and to be safe I'll dojo/_base/unload to handle any quirks. I figured I'll just use LocalStorage and voila, super-happy customer. And it really is that simple... unless you're using an iOS device (or course it had to be an iOS issue). So onbeforeunload isn't supported in mobile Safari, that was a bummer. Then I figured, well, why not update the location on each extent-change event when using an iOS device. This worked and I spent a good five minutes giving myself pats on the back (I also had an itch). So what does all this madness look like? I present some code! require([
'esri/map',
'dojo/on',
'dojo/_base/unload',
'dojo/domReady!'
], function (
Map, on, baseUnload
) {
var supports_local_storage = function supports_local_storage() {
var test = 'has_local';
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch (e) {
return false;
}
};
var map = new Map("mapDiv", {
center: [-118, 34.5],
zoom: 8,
basemap: "topo"
});
if (supports_local_storage()) {
var vals, data, iOS, handler;
vals = localStorage.getItem(location.href + '--location');
if (vals) {
data = JSON.parse(vals);
map.centerAndZoom(data.center, data.zoom);
}
// handle this bug https://bugs.webkit.org/show_bug.cgi?id=19324
// In my testing, a refresh of the browser in iOS will not fire
// window.onbeforeunload, so if iOS, use map event to write
// zoom and center to localStorage
iOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
handler = function() {
var loc = {
center: map.extent.getCenter(),
zoom: map.getLevel()
};
localStorage.setItem(location.href + '--location', JSON.stringify(loc));
};
if (!iOS) {
baseUnload.addOnUnload(handler);
} else {
on(map, 'extent-change', handler);
}
}
}); Depending on browser support, you may need to use dojo/json instead of the native JSON to get this working you poor poor soul. And that's all there is to it. The location gets saved to LocalStorage as needed and when the application starts again, it checks to see if there is a saved location and will load it up again. Easy sauce. You can see a demo in action here. For more geodev tips and tricks, check out my blog.
... View more
04-08-2015
09:13 AM
|
0
|
0
|
2371
|
|
POST
|
Make sure you're logged in with your ArcGIS Developers account. An AGO or global esri acct won't cut it and there's no indication on the page to let you know that unfortunately.
... View more
04-01-2015
10:23 AM
|
1
|
0
|
1367
|
|
BLOG
|
Not too long ago, I did a blog post on using the ArcGIS JavaScript API with ReactJS for widgets. I've been talking to a few people about React lately, so I thought I might revisit the subject here. The biggest question you might ask, is why use React? Personally, I think React has a really elegant API. When you start using it and begin to find how easy it is to compose your components that make up the user interface, I think that's when React really shines. A neat feature of React is the use of a virtual DOM. Basically, if you update the state of your application at the root, it will rerender the entire applications DOM. It sounds like it would be slow, but it's really not. It can be, if you do something silly like try to create a very large JSON editor **ahem**. You can read more about how the updates occur here. It's all just DOM If you are familiar with working with Dijits and the Dijit lifecycle, React components have a similar lifecycle. In both cases it's beneficial to get to know them. React uses an optional syntax called JSX. It's important to remember that JSX is totally optional. Some folks get all up in arms about mixing DOM with JavaScript, but that's not the case. JSX is simply used to help you define your DOM structure. It still has to be compiled to pure JavaScript in order to in the browser and there are tools for that. Widgets for the masses The source code for the sample application is available here. I won't go over the entire application in detail, but I do want to highlight the widgets. First off there is a widget called Locator that simply displays the map coordinates of the cursor. /** @jsx React.DOM */
define([
'react',
'dojo/topic',
'helpers/NumFormatter'
], function(
React,
topic,
format
) {
var fixed = format(3);
var LocatorWidget = React.createClass({
getInitialState: function() {
return {
x: 0,
y: 0
};
},
componentDidMount: function() {
this.handler = this.props.map.on('mouse-move', function(e) {
this.update(e.mapPoint);
}.bind(this));
},
componentWillUnMount: function() {
this.handler.remove();
},
update: function(data) {
this.setState(data);
topic.publish('map-mouse-move', data);
},
render: function() {
return (
<div className='well'>
<label>x: {fixed(this.state.x)}</label>
<br/>
<label>y: {fixed(this.state.y)}</label>
</div>
);
}
});
return LocatorWidget;
}); So this component is pretty simple. It will just display coordinates and uses dojo/topic to publish those coordinates to the application. I've talked about dojo/topic before. The next component is a little more interesting. It has a button that will activate a draw tool and a label that will display the distance being drawn. /** @jsx React.DOM */
define([
'react',
'esri/toolbars/draw',
'esri/geometry/geometryEngine',
'dojo/topic',
'dojo/on',
'helpers/NumFormatter'
], function(
React,
Draw, geomEngine,
topic, on,
format
) {
var fixed = format(3);
var DrawToolWidget = React.createClass({
getInitialState: function() {
return {
startPoint: null,
btnText: 'Draw Line',
distance: 0,
x: 0,
y: 0
};
},
componentDidMount: function() {
this.draw = new Draw(this.props.map);
this.handler = this.draw.on('draw-end', this.onDrawEnd);
this.subscriber = topic.subscribe(
'map-mouse-move', this.mapCoordsUpdate
);
},
componentWillUnMount: function() {
this.handler.remove();
this.subscriber.remove();
},
onDrawEnd: function(e) {
this.draw.deactivate();
this.setState({
startPoint: null,
btnText: 'Draw Line'
});
},
mapCoordsUpdate: function(data) {
this.setState(data);
// not sure I like this conditional check
if (this.state.startPoint) {
this.updateDistance(data);
}
},
updateDistance: function(endPoint) {
var distance = geomEngine.distance(this.state.startPoint, endPoint);
this.setState({ distance: distance });
},
drawLine: function() {
this.setState({ btnText: 'Drawing...' });
this.draw.activate(Draw.POLYLINE);
on.once(this.props.map, 'click', function(e) {
this.setState({ startPoint: e.mapPoint });
// soo hacky, but Draw.LINE interaction is odd to use
on.once(this.props.map, 'click', function() {
this.onDrawEnd();
}.bind(this));
}.bind(this))
},
render: function() {
return (
<div className='well'>
<button className='btn btn-primary' onClick={this.drawLine}>
{this.state.btnText}
</button>
<hr />
<p>
<label>Distance: {fixed(this.state.distance)}</label>
</p>
</div>
);
}
});
return DrawToolWidget;
}); This component is a little more involved, but it will use the geometryEngine to calculate the distance between the start point and the end point in a straight line. I do some ugly hacky-ness to stop the drawing interaction after a single line segment, because single drawing with the Draw tool is a little odd behavior (in my opinion). If you wanted to track the total distance of the polyline segments while being drawn, it's a little more involved and you would need to update the start point with the last end point and accumulate the distances as you go along. Sounds like a nice reduce function. I'll leave that exercise up to you. If I spent more time on this, I might separate some of the logic happening here into helper methods and maybe clean up some listeners, but as it stands, it works pretty well. The last thing you need to do is actually render these components on the page. /** @jsx React.DOM */
define([
'react',
'dojo/query',
'dojo/dom',
'dojo/dom-construct',
'./components/Locator',
'./components/DrawTools'
], function(
React,
query, dom, domConstruct,
Locator, DrawTools
) {
var createContainer = function() {
var c = query('.widget-container');
if (c.length) {
return c.shift();
}
var container = domConstruct.create('div', {
className: 'widget-container'
}, dom.byId('map_root'), 'first');
return container;
};
var addContainer = function(map) {
React.render(
<div>
<Locator map={map} />
<DrawTools map={map} />
</div>,
createContainer());
};
return {
addContainer: addContainer
};
}); This is where React will render the components to the defined DOM element on the page and I can pass the map to my widgets as properties. I didn't really discuss props or propTypes, but you can read more how they work here. Also here is a nice write-up on Properties vs State. Get hacking You can see a demo of this application in action here. In case you missed it the source code is here. As you can see, this is just another example of being able to integrate any library or framework of your choice in your ArcGIS API for JavaScript applications. There are certain parts of Dojo that you need to use (and some are very handy, such as dojo/topic), but beyond that it's not too hard to mix-n-match your JavaScript libraries. React is not a total framework, and the FB devs will be the first to tell you that, but it does do the V in MVC very well. So hack away folks and most of all enjoy it! For more geodev tips and tricks, check out my blog.
... View more
04-01-2015
09:55 AM
|
1
|
0
|
7241
|
|
BLOG
|
Are you using the ArcGIS API for JavaScript on a regular basis? Do you want to take your development skills to the next level? Maybe you want to use the Web App Builder and create custom widgets. Maybe you're happy just throwing in some jQuery into your application and calling it day. Or maybe you want to push your skills a little further. I've said it before, but if you want to learn how to use the ArcGIS API for JavaScript, you need to learn yourself some Dojo. Where to start To get your feet wet, Esri provides a couple of quick guides on writing a class. By the way, JavaScript doesn't really have classes, but we can fake it. They even have a quick tutorial on writing a custom widget. I will disagree with one thing in that sample though. In the constructor: this.domNode = srcRefNode; The Dijit module _WidgetBase will handle this for you as part of the Dijit life cycle. You can read more about the lifecycle of a widget here. Which brings me to the next resource I would recommend. The Dojo tutorials. The tutorial section covers everything from transitioning from 1.6 Dojo to modern Dojo to even creating builds. Although if you want custom builds of your app, I highly recommend grunt-esri-slurp or the ArcGIS JavaScript Web Optimizer. You will probably also spend a lot of time in the Dojo reference guide. The samples in the reference guide are meant to introduce you to the concepts of the modules and at times may be a little confusing. If I had one wish, it would be to have both DOM attributed and pure code samples for some Dijit stuff.. Then there is the API documentation. The API docs can be a little difficult to navigate depending on your browser, but they do provide the nitty-gritty of what properties/methods are available. I've spent many a sunny afternoon in the dojox/lang/functional docs. If you're thinking oh man, I don't want to spend a lot of time in docs, I don't know what to tell you. I work with a lot of different libraries, frameworks and languages and docs are the lifeblood of every single one of them. Roll up your sleeves, dig in and find some diamonds. Next level Another great resource for modern Dojo development, including updates to familiar modules is the Sitepen blog. You can learn more about the new Dojo testing tool called intern as well as dstore and dmodel. You'll even learn more about using modules like xstyle to do some really cool stuff. And of course, if you really want to dig in and see how things work, you can look at the Dojo source code. This is how I was able to figure out how to extend dojo/on for my purposes. You could even check out a very new framework using Dojo called Mayhem. It is still baking and in development, but it has some very nice tooling included. I'm still wading through this one myself. I also wrote an intro ArcGIS Web Development book that includes a lot of Dojo basics to get you up to speed for building ArcGIS API for JavaScript applications. The point If you want to really push your skills in working with the ArcGIS API for JavaScript, one of the first steps you need to do is get familiar with Dojo and it's capabilities. I promise you will improve your overall skills more than you imagined. You can still use other JavaScript libraries in your ArcGIS JS API apps, like React, Angular or Backbone, but Dojo is foundational to that knowledge and will only help you in the long run. Don't settle for meh, shoot for HELLZYEAH! For more geodev tips and tricks, check out my blog.
... View more
03-25-2015
08:51 AM
|
6
|
2
|
2725
|
|
POST
|
The cluster layer you are trying to use is specific to Leaflet and Esri-Leaflet. To do clustering in the ArcGIS API for JavaScript, try this layer out. It's still in development, but Esri has forked it and there are already some pull requests to clean it up a bit.
... View more
03-24-2015
12:30 PM
|
2
|
3
|
2777
|
|
POST
|
Yeah, it's a little odd. I think the JSO is still a project in progress, as there should probably be a notification of some sort to let you know you need a developer account to use it. I had the same issue first time I tried it.
... View more
03-24-2015
06:50 AM
|
0
|
0
|
1983
|
|
BLOG
|
Every now and then a question comes up in the forum about how to do selections of geometries or graphics after they've run some sort of analysis, such as a buffer or drive-time. It makes sense, you've got this nice new polygon or something added to your map after you ran your fancy-schmancy analysis and you want to make it mean something. The thing to remember is that the results from your analysis are just more geometries and there are tools in the API to deal with it. Polygon Circus Let's look at a common one, the Polygon. A Polygon has some methods built it into it that let you extract geometries so you can do something with them. There is the getCentroid method, which uses the maths here. If my memory serves me correctly, you could get a point returned from outside the polygon if the polygon is some odd u-shape. I'm sure someone will correct me if I'm wrong. There is also the getExtent method, which you may have used to set the extent of the map to a polygon, this just returns a rectangular extent of the polygon. A more interesting one is the contains method. It makes sense to have this on the Polygon as it's a quick way to check if your point is inside the polygon. You could iterate over a list of geometries and check them like polygon.contains(point). Simple enough. There are lots of other interesting methods you may find useful in the Polygon module. Just select the things A lot of times, if i know I have a layer that will provide some sort of value to my map after I perform an analysis, I'll add it as a FeatureLayer so that I can use the selectFeatures method when I need it. So let's say you do a viewshed analysis in your map and you want to see what points, such as parcels or schools are within that viewshed. You can run your analysis, grab the geometries from the result of the analysis and select the features from the layer to display them on the map. Again, those selected features are just geometries, so you can use those geometries to do further analyses such as find the nearest hospitals or fire stations, whatever floats your boat. You could do something like this after doing a viewshed analysis. var analysisTool = new CreateViewshed(params, "toolPane");
analysisTool.startup();
analysisTool.on("job-result", function(result) {
analysisTool.set("disableRunAnalysis", false);
var resultLayer = new FeatureLayer(result.value.url || result.value, {
outFields: ['*'],
infoTemplate: new InfoTemplate()
});
map.addLayer(resultLayer);
if (result.value.featureSet) {
// get features from the result
var features = result.value.featureSet.features;
// only need the geometries, not full graphic
var geometries = features.map(function(x) {
return x.geometry;
});
// union geometries with geometryEngine
var geometry = geometryEngine.union(geometries);
var query = new Query();
query.geometry = geometry;
// select the things
census.selectFeatures(query, FeatureLayer.SELECTION_NEW);
}
}); * This sample is available on jsbin, modified from an esri example. Requires an ArcGIS Online/Developers login for analysis tools. That's not too difficult to do. Notice the use of the geometryEngine in there. This is still in beta, but it's in 3.13 and I'm just starting to mess around with it. In the case above, you don't really need it, but it comes in handy when you have multiple geometries of the same type and you just need to mash them together to further analysis, such as a selection. If you were not using a FeatureLayer and only dealing with graphics on the map, the geometryEngine would be the go-to tool to do stuff like this. As I use it more, I'll post more about it. So give it a shot, there are a lot of tools and options available to you when you need to make sense of your geometries in your application. Don't be afraid to experiment and see what you can break. For more geodev tips and tricks, check out my blog.
... View more
03-18-2015
08:24 AM
|
0
|
0
|
1394
|
|
BLOG
|
I'm sitting here at the keynote (CEO of Taqtile) for the 10th annual Esri Developer Summit. I've spent the last couple of days in sessions, and the plenary and enjoying all the geo-goodness of those around me. There are a lot of developer conferences throughout the year, but what makes the Developer Summit special is the industry focus and niche of this community. The other big geodev conference is FOSS4G, which unfortunately was at the same time as devsummit this year. But that's okay. It's always a blast to see some familiar faces and to put some faces to those that I interact with online in some way. I really enjoy the work I do. I like the problem solving and I particularly like working with maps. I also really enjoy contributing to the geo-community as a whole. Some folks here have stopped to simply say thank you for those contributions. I just want to say thank you for reading. Go hack at things and build cool stuff folks. For more geodev tips and tricks, check out my blog.
... View more
03-11-2015
08:46 AM
|
0
|
0
|
1197
|
|
BLOG
|
If you've never used Leaflet, it's a fantastic lightweight mapping library that has grown in popularity over the years, mainly due to the simplicity of the API. It has tons of plugins and controls that can be used with it, including the Esri-Leaflet plugin that let's you work with ArcGIS Server and ArcGIS Online services. There is plenty of great stuff in the examples for Esri-Leaflet on how to get started with it, but sometimes I get asked how a developer might incorporate it into their development workflow. Examples are great for getting familiar with the project, but as an application grows, things could get a little complicated. I just wanted to show you how you might get started from scratch with a more robust solution. Get the bits For this demo, you're going to need node and npm. Let's not worry about the whole io.js thing. Once you have node and npm installed, create a directory on your machine for your project. It doesn't need to be on a local server, we'll take care of that with node. With that directory created, open a terminal in it and run the following command in your command line tool of choice: npm init Accept the defaults for the prompts you are given. When that is done, you will have a package.json file in your directory. Now we need to install a couple of modules to help us during development, including Leaflet and Esri-Leaflet. npm install watchify --save-dev npm install http-server --save-dev npm install leaflet --save npm install esri-leaflet --save Basic setup With the modules we'll need installed, let's get some basic files set up. Create an index.html file in your directory that will look like this, nothing fancy. <!DOCTYPE html>
<html>
<head>
<title>Starting Esri Leaflet</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<link rel="stylesheet" href="css/main.css" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1.0 maximum-scale=1.0">
</head>
<body>
<script src="bundle.js"></script>
</body>
</html> Next create a css directory and let's make a simple main.css file in there. html, body, .map-div {
width : 100%;
height : 100%;
margin : 0;
} Next create a src directory in your project and inside the src directory create an index.js file and a popup.js file. We'll come back to this file in a second. Automate it Now open the package.json file and let's make some edits to the scripts section. "scripts": {
"start": "http-server",
"watch": "watchify src/index.js src/popup.js -o bundle.js -dv",
"start-dev": "npm start | npm run watch"
} This scripts section will let you run commands using npm. This is really handy for setting up quick development environments. The start section will run a local development server on localhost:8080. The watch section will check for changes to the files specified and output them using browserify to a bundle.js file that will compile all the required JavaScript into a single file. Note - If you are not on Windows, you should be able to change the line to watchify src/*js instead of listing each file, but on my Windows machine, I needed to list each file to watch. At this point, your development environment is all set up to automate bundling your JavaScript and to run a local server. Run the following command and let's move on: npm run start-dev Write some code Open the src/popup.js file and lets write some code. var L = require('leaflet');
var popupTemplate = '<h3>{NAME}</h3>{ACRES} Acres<br><small>Property ID: {PROPERTYID}<small>';
module.exports = function(feature){
return L.Util.template(popupTemplate, feature.properties);
}; If this looks odd to you, don't worry. This is commonjs syntax for writing modular JavaScript. Here is a great intro to commonjs modules on egghead.io. If you are used to using AMD with Dojo in the ArcGIS API for JavaScript this might throw you off a bit, but it works pretty nicely. In a module, whatever you define as the module.exports is what get's exported from this module. In this case, we are exporting a function that returns a popup template for Leaflet. Now open up src/index.js and lets edit this file. var L = require('leaflet'); // bring in Leaflet
require('esri-leaflet'); // add esri-leaflet
var popupTemplate = require('./popup.js'); // bring in our popup we just defined
var node = L.DomUtil.create('div', 'map-div', document.body); // create the node for the map
var map = L.map(node).setView([45.528, -122.680], 13);
L.esri.basemapLayer('Gray').addTo(map);
var parks = new L.esri.FeatureLayer('http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/Portland_Parks/FeatureServer/0', {
style: function () {
return { color: '#70ca49', weight: 2 };
}
}).addTo(map);
parks.bindPopup(popupTemplate); All of this is standard code you would see in the Esri-Leaflet examples. The only difference is we are using require to add modules to the application. We even added the popup.js file we created earlier. Notice, require behaves differently here from how it does in Dojo. What just happened? You may not have noticed, but while you were editing your JavaScript files, you should have seen some messages in your terminal about a bundle.js file being created. That's because the npm scripts we wrote earlier are set up to watch for any changes in these JavaScript files and to recompile the them into single bundle.js file your application needs. If you open your browser to localhost:8080 *crosses fingers* you should seem something like this. Congratulations! You just set up a very simple development environment to build your Esri-Leaflet applications. As you add more modules or organize your code, just edit the watch script in package.json as needed and keep on coding. Here is the full application on github. This is a very simplistic set up, but honestly you could do a lot with the npm scripts as they are currently designed. If you wanted to dive in with more robust tools, you could look at things like gulp, grunt or webpack. Get knee deep and learn to love your build tools. For more geodev tips and tricks check out my blog.
... View more
03-03-2015
10:09 AM
|
1
|
0
|
3256
|
|
BLOG
|
A while back I did a post on my own blog on using Dojo Bootstrap with the ArcGIS API for JavaScript. I showed how you can incorporate it to do an autocomplete search that works pretty well and looks good. I've used Dojo Bootstrap pretty extensively in my app development and I've found a few quirks that require a little work on my part. If you layout your HTML with the property attribute tags and load the library you should not have any real issues beyond a little learning curve. I've found that I've had to do a couple of work-arounds when I wanted to programatically create elements as widgets. An easy demonstration of this can be seen when creating a Modal. Modals, you're own way I typically want to treat my Modal popups as a widget and that means I may want to customize the look of the Modal a little bit. In the sample I'll show, this is the template I use for the widget. var tpl = [
'<div class="modal fade popup-container" id="myModal" tabindex="-1" role="dialog"',
'data-dojo-type="Modal" data-dojo-props="header:My Modal, modalClass: fade"',
'aria-labelledby="myModalLabel" aria-hidden="true" data-dojo-attach-point="modalNode">',
'<div class="modal-dialog">',
'<div class="modal-content" data-dojo-attach-point="contentNode">',
'<div class="modal-header">',
'<h4 id="myModalLabel"></h4>',
'<span data-dojo-attach-point="labelNode">${title}</span>',
'<a href="javascript:void(0)" class="glyphicon glyphicon-remove pull-right popup-close" data-dismiss="modal" aria-hidden="true"></a>',
'</div>',
'<div data-dojo-attach-point="bodyNode" class="modal-body">',
'</div>',
'</div>',
'/div>',
'</div>'
].join(""); A lot of this is pretty standard, but I wanted to dynamically set the title and add a bodyNode attach-point that I could add the content to. Instead of interacting directly with the Modal module, I wrap it in a separate widget that allows me to do things like set the title and update the content. This custom widget for the Modal looks like this. var Popup = declare([_WidgetBase, _TemplatedMixin, Evented], {
templateString: tpl,
loaded: false,
constructor: function() {
this.set('content', '');
this.set('title', 'Popup Window');
},
postCreate: function() {
this.modal = new Modal(this.domNode);
var watchContent = this.watch('content', function(_, __, value) {
domConstruct.empty(this.bodyNode);
this.bodyNode.appendChild(domConstruct.toDom(value));
}.bind(this));
var watchTitle = this.watch('title', function(_, __, value) {
this.labelNode.innerHTML = value;
}.bind(this));
var onHide = on(this.modal.domNode, 'hide.bs.modal', function() {
this.emit('hide', {});
}.bind(this));
this.own(watchContent, watchTitle, onHide);
this._init();
},
show: function() {
this.modal.show();
},
hide: function() {
this.modal.hide();
},
_init: function() {
this.set('loaded', true);
this.emit('loaded', true);
}
}); So what's happening here is you create a new Modal using the domNode of the widget as the target. You set up a watcher for when the Modal is hidden and propagate that event up from the widget. This required looking at the tests for the Modal to find event names, as some of the docs are still being updated. Then you set up watchers for the title and the content, the latter being converted to a DOM element and added to the bodyNode of the widget. The result will look similar to this. To demo this, I just took an existing InfoWindow sample and modified it in this JSBin. Dojo Bootstrap Sample There's not much happening in that Modal window, but think about what you could do with that extra real estate. You could display image attachments, or provide nicely formatted details of the data or related table data. You'd have room to even add other widgets in there to display nice charts in the window. I use this to provide full edit forms with nice big buttons and even other Modal popups as picklists. The power is in your hands. Hack and slash This may not be groundbreaking work here, but adding little touches like moving InfoWindow content to a Modal popup are the types of things that add a bit of flair to your applications. You could use dijit/Dialog as well and tweak the styling as well if you like, the idea is to test this type of interaction out and see if it provides a more fluid experience for your users. You could even style the Modal popups to take up the whole page and provide some nice looking transitions on a mobile device. You're writing the code, make it you own. Big thanks to Tom Wayson for helping me dig into the Dojo Bootstrap guts to get things done. For more geodev tips and tricks, check out my blog and hack your maps.
... View more
02-25-2015
08:16 AM
|
2
|
1
|
2941
|
| Title | Kudos | Posted |
|---|---|---|
| 2 | a week ago | |
| 1 | a month ago | |
| 2 | 3 weeks ago | |
| 2 | 05-19-2026 02:12 PM | |
| 1 | 04-24-2026 11:01 AM |
| Online Status |
Offline
|
| Date Last Visited |
9 hours ago
|