GIS Life Blog

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Other Boards in This Place

Latest Activity

(450 Posts)
ReneRubalcava
Frequent Contributor

In the ArcGIS API 4 for JavaScript, a new layer type was introduced to help you do manage grouping your layers into like-minded categories. The GroupLayer provides some really interesting functionality for you to do pretty much exactly what it says, group your layers.

Let's assume you have a Dynamic Map Service, like say this NOAA Storm Reports service. This is a handy little service that gives a quick overview of storm reports. However, it is a dynamic map service, which would normally be displayed in a MapImageLayer, however this layer type (formerly known as ArcGISDynamicMapServiceLayer) doesn't support popups in the initial 4.0 release.

It's conceivable that the data behind these points might prove useful, so you may want to display popups for them in your application.

There's an easy way around that, you could just use each individual layer in the service as a FeatureLayer and you can define popups and the world is right again. But maybe you have some logic in your application that requires you to treat this data as a single layer, such as turn them all off at the click of a button.

Now you'll want to hug your GroupLayer.

Let's look at what the code for that might look like.

require([
  "esri/Map",
  "esri/views/MapView",
  "esri/layers/FeatureLayer",
  "esri/layers/GroupLayer"
], function (Map, MapView, FeatureLayer, GroupLayer) {
  var url = "http://tmservices1.esri.com/arcgis/rest/services/LiveFeeds/NOAA_storm_reports/MapServer/";

  var map = new Map({
    basemap: "streets"
  });

  var view = new MapView({
    container: "viewDiv",
    map: map,
    center: [-98.648, 36.374],
    zoom: 5,
    ui: {
      components: ["zoom", "attribution", "compass"]
    }
  });

  var titles = [
    "NOAA HAIL Storm Reports (24 hours)",
    "NOAA TORNADO Storm Reports (24 hours)",
    "NOAA WIND Storm Reports (24 hours)",
    "NOAA TORNADO Storm Reports (past week)"
  ];

  var layers = ["0", "1", "2", "3"].map(function(index, idx) {
    return new FeatureLayer({
      url: url + index,
      outFields: ["*"],
      popupTemplate: {
        title: titles[idx],
        content: "{*}"
      }
    });
  });

  var groupLayer = new GroupLayer({
    layers: layers,
    visibilityMode: "inherited",
    visible: true
  });
  map.add(groupLayer);

  view.then(function() {
    var btn = document.createElement("div");
    btn.className = "esri-button esri-widget-button esri-interactive esri-icon-feature-layer";
    btn.title = "Toggle Storm Data";
    view.ui.add(btn, "top-right");
    btn.addEventListener("click", function() {
      groupLayer.visible = !groupLayer.visible;
    });
  });
});

What we've done here is added the Storm Report data as individual FeatureLayers, but we've wrapped them in a GroupLayer. Then we added a simple button to the UI that does one thing. It toggles the the visibility of the grouped storm data on and off. Notice that I set the visibilityMode of the GroupLayer to "inherited". This means that all the sublayers will inherit their visibility from the parent GroupLayer. You could change this if you wanted to some conditional visibility of layers in the GroupLayer and get fancy, but for this use case, everything just works.

You can see a live demo of this application here.

You aren't limited to wrapping FeatureLayers with the GroupLayer, you could group any layer types, which could prove very convenient when controlling the visibility of multiple map services in your application.

So take the GroupLayer for a spin in your next ArcGIS API 4 for JavaScript application!

For more geodev tips and tricks, check out my blog.

Title photo via Mel Aclaro at group hug | Flickr - Photo Sharing!

more
0 0 971
ReneRubalcava
Frequent Contributor

It's that time of year again! We're in June, will it be hot, will we see the sun? It's always a coin-toss, but one things for sure, the 2016 Esri UC is right at the end of this month and if you aren't attending, someone in your organization probably is, maybe even you boss.

So you're a developer or maybe you work with developers or manage developers in your organization. As developers, we get hung up on learning the latest tech, just to learn it, but sometimes we need to step back and look at what we are doing with that tech, or what we could do.

A quick look at the agenda and you can already tell it's going to be a jam-packed week. You probably haven't even begun to think about what sessions you're planning to see, much less think about what you could see.

Before joining Esri, I think I've been to about half a dozen UCs, I even had a booth and each year it was always a mad rush to try and figure out what I should spend my time learning.

Relax. Don't be like me.

Personally, I would be remiss if I didn't mention that you should check out the sessions I'm involved in. I'm lucky, I get to co-present with some great people during these sessions.

Learn from your peers

I'll admit, I'm more a Dev Summit kind of guy, but the UC is a great opportunity to see how all the cool technology that we like to build on actually gets used. Yes, all the cool SDKs and APIs we developers get so excited about actually have to be proven useful or we're just wagging our keyboards around.

If you happen to be around on Monday night, the Lightning Talks are a great way to hear from other users on some cool stuff they've done or tips and tricks. These aren't typically done by Esri employees, these are users sharing real world experiences.

The next thing I would recommend are the moderated paper sessions. The moderated paper sessions are where you can find some real gems. Plus, you get to support your peers working in your field or a particular industry. Remember, plenty of these presenters don't present often, some for the first time, so there may be some nerves, but I've learned so much over the years from users in these sessions, it's invaluable. Struggled with integrating that asset management system and massive infrastructure data into your GIS? Someone may have done just that, so go learn how they overcame similar challenges.

Here are just a few sessions that stood out to me.

Again, if you are a developer I highly recommend popping in to a couple of the moderated paper sessions and see how users are actually using the technology and learn from their work. You may even find inspiration for your next project!

Get the deets!

The Esri UC is where you'll learn about all the latest on the ArcGIS platform, ranging from topics for the developer to the techs, to cartographers and analysts. It's a great time, if you are a developer, to brush up on some analysts skills. You may have been nose-deep in code so long you forgot how to do population projections or maybe you never touched the analysis part of GIS, go learn a little!

I haven't done nose-to-the-stones geo analysis in a long time. I've done my fair share of hydro analysis and creating watersheds and all kinds of other tasks from my analysis days, but I like to at least brush up on these things once or twice a year so I don't lose touch.

Here are some cool tech sessions from Esri you may want to check out.

Remember, these tech sessions are done by Esri employees, working directly with the tech on a first-hand basis. Take notes, ask questions, that's what we're there for!

Although I have at least one session where I'll have to book it from one side of the convention center to the hotel at the other end in like 10 minutes, so if I'm in a rush at that time, sorry in advance.

Protip - If you manage developers, don't go back to the office and make them learn all the cool stuff you saw. Give them a summary, ask them to investigate some subjects further, put them in contact with presenters you may have talked to. If they see a solution to a problem, trust me, they'll learn it! And if you really want to them to learn the details of the tech, approve their Dev Summit requests.

Socialize

Don't be a hermit. People attending the Esri UC are your peers, these are our peeps. Get to know some new people, attend a Special Interest Group, look up any social activities. Hang out in lounge areas and get to know some folks.

Make sure to check out the Map Gallery to check out some cool cartographic maps. There's a reception on Monday afternoon where you can mingle.

Wander the Expo and check out all the vendors. There's usually some cool schwag you can pick up and you'll probably see some vendors you can partner with to help you accomplish some tasks in your organization.

There's also a GeoDev Meetup on Weds night that I highly recommend!

I'm sure plenty of people will stay connected throughout the week on Twitter, so keep an eye out for what's going on. Watch the #EsriUC hashtag to see where people are drinking or just hanging out for the night.

I would also use Twitter all the time at the UC to check if people were talking about one particularly cool presentation that I might want to jump in if the current one I was in wasn't doing it for me.

Most of all, enjoy the UC. Learn a thing or two and have fun!

For more geodev tips and tricks, check out my blog.

Title photo via Gary J Wood San Diego Convention Center | Flickr - Photo Sharing!

more
0 0 1,731
ReneRubalcava
Frequent Contributor


So last week at DevSummit, there was a lot of solid information being dropped as to the new ArcGIS API for JavaScript 4.0 features and capabilities. Let me tell ya, there's a lot of cool stuff to look forward to!

You can get a pretty good overview of 4.0 via this slide deck.

One recurring theme I thought came up a lot is the introduction of View Models in the API. You can read more about View Models and developer friendly widgets here. Basically, View Models separate the business logic of the Widget from the View of the Widget.

To keep it simple, let's look at the Zoom widget. To give developers a better idea of how the View Models are used, the Widget View source code is included in the SDK. You can use this as a guide to build your own widgets. If we look at the Zoom ViewModel, it's pretty simple. It has two methods, zoomIn and zoomOut. That gives you a lot of room to build your own Zoom interface for your application. You could have a single button to only zoomIn when cities are visible and maybe switch to zoomOut when building footprints are visible. Like I said, it gives you a lot of freedom to build your interface as you want.

I have this little sample using React with View Models. You can see a custom Zoom component here. Here's the portion that renders the component.

render() {
  let btnstyle = this.state.updating ? 'zoom-btns' : 'zoom-btns view-busy';
  let maxstate = this.state.maxZoomed ? 'button raised grey narrow disable' : 'button raised grey narrow';
  let minstate = this.state.minZoomed ? 'button raised grey narrow disable' : 'button raised grey narrow';
  return (
    <div className={btnstyle}>
      <div className={maxstate} onClick={this.zoomIn}>
        <div className="center"><i className="material-icons">add</i></div>
      </div>
      <div className={minstate} onClick={this.zoomOut}>
        <div className="center"><i className="material-icons">remove</i></div>
      </div>
    </div>
  );
}

What this does is gray out the zoom buttons when you hit the min/max zoom levels. You can see the live demo here.

I talked a lot about integrating the API with multiple frameworks in a session last week. You can see the slides here. A lot of this framework integration really hangs on using View Models to power the inner guts of the JS API and simply wraps new components around the View Models to create new interfaces.

There was a really great session on building your own widgets last week that everyone interested in building widgets should look over. Here are the slides. It doesn't only cover custom widgets, but styling and css stuff, it's full of really great info.

I'm pretty excited about View Models in the 4.0 API. I imagine people doing some really cool stuff with View Models because technically you don't need a View for your Widget. You could activate View Model methods via an Arduino that may be used for voice recognition. Maybe using some VR tech to allow you to call View Model methods via gestures or some other mechanism. Like I said, the View Models provide the business logic of interacting with a MapView or SceneView, how you use them is up to you.

So hack away, build some cool apps and see what you can do!

For more geodev tips and tricks, check out my blog!

more
1 3 2,246
ReneRubalcava
Frequent Contributor

amd-packages.png

Maybe you're new to the ArcGIS API for JavaScript or maybe you're even a seasoned user, but at some point I'm sure you've dug deep into AMD and modular JavaScript.

I've written a few posts about this before, one being Embrace your AMD modules, as well as a post on custom builds. I even recorded a video about using the Bower release of the ArcGIS JS API.

One question seems to pop up quite a bit and that is a question about packages.

What are they and why do they matter?

Don't worry, packages are a concept that confused me at one point as well. Packages can be thought of as namespaces, similar to what you might see in Java or another language.

Let's break down a couple of some statements, using default ES5 syntax.

define(["esri/map"], function(map) {});

What we are doing here is requesting the map module from the esri package. The entire ArcGIS API for JavaScript s inside the esri package. There are other dependencies from other packages like dojo or dojox.

Typically, you don't need to concern yourself too much with packages if you are building a simple application. If you're using the CDN of the API, you are probably familiar with this little hack to use your local code.

Using packages

That's all fine and dandy, but if you are using the Bower release of the API and you want to do custom local builds, this is when packages matter. Because you need to let the Dojo build system know what packages it should be aware of. The easiest way to do this is to add the esri and it's dependency packages under a source folder. Your application code should go into an app folder.

This means you would end up with an application structure similar to this.

src
  ├── app
  ├── dgrid
  ├── dijit
  ├── dojo
  ├── dojox
  ├── dstore
  ├── xstyle
  ├── put-selector
  ├── esri

You can read this guide to find out how to have Bower install to your source directory. Now you can tell the Dojo build system what packages it should be aware of in your build profile.

  packages: [
    // 'app' is a sample path for your application
    // set this accordingly
    'app',
    'dijit',
    'dojo',
    'dojox',
    'dstore',
    'dgrid',
    'xstyle',
    'put-selector',
    'esri'
  ],

You can see a sample build profile here. If you add more libraries, like Bootstrap and jQuery, you can just add them to them to the packages list.

So at the end of the day, packages are nothing more than a way to keep your code organized.

Now that's not the end of the story for packages. There are more details you can learn about to let the Dojo build system know that a folder is a package and that it is an AMD package. There's even stuff you can do to ignore any tests directories that may reside inside your package folder.

I'll cover those details next time!

For more geodev tips and tricks, check out my blog.

more
1 0 1,705
ReneRubalcava
Frequent Contributor

esrijs-scheduler.png

The ArcGIS JS API 4.0 Beta is still getting some love. Lots of updates with each beta release. Updated features, new features, updated docs and all that good stuff.

But there are still some dark corners of the API that are yet be completed...or doc'd! This is where I live.

When the 4.0 beta first came out, I did a cool blog post on using Accessors to record the camera of a view and play it back. It works pretty well, but I always felt it could be a little better. You'll notice the sample in that post, I'm using this odd module called esri/core/Scheduler.

What is that?

That is some low-level API goodness is what that is. The Scheduler is a modified version of the Scheduler found in Dojo2. It's basically a way to work with requestAnimationFrame. It's not doc'd yet, because beta, things could change.

So what you can do is schedule for stuff to happen during the next frame of your application. This is used for ... can you guess ... animations! Here is a cool little tutorial on requestAnimationFrame.

When you're working with 3D maps, you're working with animations. You don't need to concern yourself about the details, but if you want to do something to stay in sync with a 3D map, you should get familiar with requestAnimationFrame.

Scheduler can help with this.

In my old sample, I was still crutching on setInterval, so here's how I would do it all with Scheduler.

require([
  "esri/Map",
  "esri/views/SceneView",
  "esri/core/watchUtils",
  "esri/core/Scheduler",
  "dojo/on",
  // Widget items
  'dojo/_base/declare',
  'dojo/dom-class',
  'dijit/_WidgetBase',
  'dijit/_TemplatedMixin',
  "dojo/domReady!"
], function (Map, SceneView, watchUtils, Scheduler, on, declare, domClass, _WidgetBase, _TemplatedMixin){

  var template = '' +
  '<div>'+
    '  <input class="camera-slider" data-dojo-attach-point="slider"'+
    '  type="range" min="1" max="1" step="1" value="1">'+
    '  <a href="javascript:void(0)" data-dojo-attach-point="reverseBtn"'+
    '    data-dojo-attach-event="click:playReverse"'+
    '    title="Play views in reverse"'+
    '    class="btn btn-info btn-fab btn-raised mdi-av-fast-rewind"></a>'+
    '  <a href="javascript:void(0)" data-dojo-attach-point="playBtn"'+
    '    data-dojo-attach-event="click:play"'+
    '    title="Play views"'+
    '    class="btn btn-info btn-fab btn-raised mdi-av-play-arrow"></a>'+
    '  <a href="javascript:void(0)" data-dojo-attach-point="stopBtn"'+
    '    data-dojo-attach-event="click:stop"'+
    '    title="Pause recording view"'+
    '    class="btn btn-info btn-fab btn-raised mdi-av-pause"></a>'+
    '</div>';

  var CameraRecorder = declare([_WidgetBase, _TemplatedMixin], {
    templateString: template,
    constructor: function() {
      this.cameras = [null];
      this.timer = null;
      this.watcher = null;
      this.handler = null;
      this.isPlaying = false;
    },
    clear: function() {
      if (this.watcher) {
        this.watcher.remove();
      }
      if (this.handler) {
        this.handler.remove();
      }
      if (this.timer) {
        this.timer.remove();
      }
      this.recordStart();
    },
    recordStart: function() {
      if (this.isPlaying || this.isPaused) {
        return;
      }
      this.timer = Scheduler.schedule(function() {
        this._cameraWatch();
        this._sliderWatch();
      }.bind(this));
    },
    play: function() {
      if (this.isPlaying) {
        return;
      }
      domClass.toggle(this.playBtn, 'btn-info btn-success');
      this._play(false);
    },
    stop: function() {
      this.isPaused = !this.isPaused;
      domClass.toggle(this.stopBtn, 'btn-info btn-danger');
      if (!this.isPaused) {
        this.recordStart();
      }
    },
    playReverse: function() {
      if (this.isPlaying) {
        return;
      }
      domClass.toggle(this.reverseBtn, 'btn-info btn-success');
      this._play(true);
    },
    _cameraWatch: function() {
      var view = this.get('view');
      var cameras = this.cameras;
      var slider = this.slider;
      this.watcher = view.watch('camera', function(val) {
        cameras.push(val.clone());
        slider.max = slider.value = cameras.length;
        this.clear();
      }.bind(this));
    },
    _sliderWatch: function() {
      var view = this.get('view');
      var cameras = this.cameras;
      this.handler = on(this.slider, 'input', function(e) {
        var val = parseInt(e.target.value);
        view.camera = cameras[val] || view.camera.clone();
        this.clear();
      }.bind(this));
    },
    _play: function(inReverse) {
      this.isPlaying = true;
      var slider = this.slider;
      var view = this.view;
      var cameras = this.cameras;
      var len = cameras.length;

      var i = 0;
      var task = Scheduler.addFrameTask({ update: function() {
        if (!inReverse) {
          slider.value = i;
          view.camera = cameras[i++] || view.camera.clone();
          if (i === len) {
            task.remove();
            task = null;
            domClass.toggle(this.playBtn, 'btn-info btn-success');
            this.isPlaying = false;
            this.recordStart();
          }
        } else {
          slider.value = len;
          view.camera = cameras[len--] || view.camera.clone();
          if (len < 1) {
            task.remove();
            task = null;
            domClass.toggle(this.reverseBtn, 'btn-info btn-success');
            this.isPlaying = false;
            this.recordStart();
          }
        }
      }.bind(this)});
    }
  });
  
  var map = new Map({
    basemap: "dark-gray"
  });

  var view = new SceneView({
    container: "viewDiv",
    map: map,
    scale: 240000000
  });

  var camRecorder = new CameraRecorder(
    { view: view }, document.getElementById('recorder')
  );

  view.then(function() {
    camRecorder.recordStart();
  });

});

What I'm doing here is two things.

I'm using Scheduler.schedule() here to schedule some methods to occur on the next frame. These are the methods that store the camera or slider changes to record the view.

Then when you play the recorded camera views in sequence, I use Scheduler.addFrameTask({update: function(){}}) to add a function when the view is updated, basically rendered. There is some internal lifecycle stuff at work here in the addFrameTask, but I'm just shooting at the hip here, so let's go with update as the one to hook into.

If you don't sync operations like this that have to do with animation, you'll end up with a stuttering map. My first draft of this app was strictly working on watching for property changes, but it jacked up my app. Now it is much smoother.

You can see this updated example here.

So if you are interested with playing around with animating the view, playing with the camera or working in sync with animateTo to enrich your app, play around with Scheduler or just requestAnimationFrame if you like.

For more geodev tips and tricks, check out my blog.

more
0 0 757
ReneRubalcava
Frequent Contributor

esri-sceneview.png

The ArcGIS 4.0 Beta 2 is out and it's another step forward in what you can expect in the next generation of the ArcGIS JavaScript API.

I talked about the general updates in this release here and a bit more about Vector Tiles here.

So if you haven't been paying attention, a big new feature in the 4.0 version of the API is 3D support. The 4.0 beta doesn't currently support Web Maps,(it will) but it does now support Web Scenes. You can create a Web Scene in the ArcGIS Online SceneViewer. Now you can take those scenes create in the SceneViewer and use them in your 4.0 beta application.

Once you have a Scene created, just use the item id like you would use for any ArcGIS Online item and pass it into the WebScene.

Here is a demo pretty much just like the Esri sample.

require([
  "esri/views/SceneView",
  "esri/portal/PortalItem",
  "esri/WebScene",
  "dojo/domReady!"
], function(SceneView, PortalItem, WebScene) {
  var scene = new WebScene({
    portalItem: new PortalItem({
      id: "94b0da9f133947089773a681523882e7"
    })
  });
  var view = new SceneView({
    map: scene,
    container: "viewDiv"
  });
});

Notice that you technically create a PortalItem with your item id and you pass that PortalItem into the WebScene. That WebScene can then be used as the map to power the SceneView. To get a refresher on how the Map and View relationship works in the ArcGIS JS API 4.0 beta, you can take a look at this blog post.

Here is a sample of this scene.

3D Scene Sample on jsbin.com

Not only do you get Web Scenes, you get Local Scenes. Here is a sample of a local scene. Soak that in folks. I know you oil and gas people are salivating. You can basically clip a 3D scene to localize an area and view underground data. You can then load this data into your application view the WebScene module.

Who needs 2D maps.

So take a crack at the SceneViewer and turn some of your stale old 2D data into a 3D masterpiece!

For more geodev tips and tricks, check out my blog.

more
1 0 1,853
ReneRubalcava
Frequent Contributor

esri-builder.png

Earlier this week, Esri announced the release of a Bower package for the ArcGIS API for JavaScript. This opens up another channel by which users can leverage to create custom builds of their applications.

Currently, you can use the JavaScript Optimizer to create and host a custom build of the ArcGIS JS API. If you wanted to take it a bit further and try to create a custom build of your entire application, there has been esri_slurp that let you download a version of the API from the CDN that was meant for testing purposes, but allowed users to create local custom builds of their applications.

The Bower package is a perfect drop-in tool you can use to create local builds.

I go in to a lot more detail in this blog post and video about how to use the Bower package to create your custom builds.

You can simply do:

bower --save arcgis-js-api

You can find more detailed samples in the guide. These samples demonstrate how to use the Bower package to install directly into your working directory, set up your development environment and do a local build of your application in both Dojo and RequireJS.

In many cases, you may not need to create a custom build of the application using the Bower package. If you're development has been working fine using the CDN, there is probably no need for you to use the Bower package. The JavaScript Optimizer makes it pretty easy to create custom builds of the ArcGIS JS API and even to get that specific build hosted in a CDN. If however, your applications need to sit inside a sandboxed environment where you can't use a CDN or maybe your applications are quite extensive and could benefit from a custom build, then the Bower package may be for you.

Whatever you decide, you are still building awesome apps!

For more geodev tips and tricks, check out my blog.

more
0 0 1,701
ReneRubalcava
Frequent Contributor

218583023_54bef6f263_z.jpg

https://www.flickr.com/photos/thewavingcat/218583023

So this isn't a new feature at all, it's been around almost as long as the API has, but I figured it was one of those things that may have been lost among all the other cool features of the ArcGIS API for JavaScript...

Changing the map cursor.

It's such a simple task, yet can add so much to your users experience when working with your application.

There is a method specifically for this. setMapCursor.

It's not difficult to do, you just pass the type or cursor you want into your app.

Maybe you've added the ability to click on the map open a Google Street View in a new window.

Well, hey, make a cursor that can specifically show that you are in the middle of a picking a spot on the map to do this.

Here is a demo of what this might look like.

Just do it!

Like I said, this isn't a new fancy functionality of the API and setting cursors in web apps is typically done via CSS. But, when you are performing certain actions within your application it would be nice to provide your users with some form of feedback that something is happening and one way to do this is via the map cursor.

For more geodev tips and tricks, check out my blog.

more
1 0 497
ReneRubalcava
Frequent Contributor

accessor-binding.png

So yeah, I have something of an affinity for Accessors in the ArcGIS JS API 4.0 beta.

I've written about them a lot.

Their incredibly versatile, allowing you to do things you couldn't do with regular event watching in the 3.x API. You can play with the camera, save the state of your application and much much more.

Lately I've been thinking about possible editing and drawing scenarios you can get out of Accessors. Lots of times, you aren't just editing geometry, you are editing attributes. I've been toying around with how you as a developer can leverage Accessors to get this done.

I won't go into details here, you can get the details for fields from the layer data returned from the ArcGIS REST API. This will tell you what fields are available, what's editable, what the field type is, which is really powerful information used for editing. You can leverage this information to dynamically create your edit forms for your application.

We'll simplify this scenario a bit.

Let's just assume, you want to do the following:

  • Display inputs for each attribute field
  • Bind changes in the input to the attributes
  • Display those changes

Accessors can let us do this.

Let's look at creating an input that binds changes to the input to the Accessor.

  function createInput(/*Accessor*/target, /*FieldName*/name) {
    var node = document.createElement('div');
    node.setAttribute('class', 'form-group');
    var lbl = document.createElement('label');
    lbl.innerText = name;
    var input = document.createElement('input');
    input.setAttribute('class', 'form-control');
    input.setAttribute('type', 'text');
    input.setAttribute('name', name);
    input.setAttribute('value', inputValue(target, name));
    node.appendChild(lbl);
    node.appendChild(input);
    on(input, 'keyup', function(e) {
      // update the accessor
      target[e.target.name] = e.target.value;
    });
    return node;
  }

In this sample, we listen for the keyup event of the input and update the Accessor. Pretty simple.

Now you can watch for changes done to the accessor and do something with that. You would probably want to send an update to a FeatureService and simply sync every update to the service.

To demonstrate this binding, I'll bind the dynamically generated form to another form that is disabled to show the updates.

  qTask.execute(query).then(function (results) {
    var feature = results.features[0];
    var attr = new Accessor(feature.attributes);
    Object.keys(attr).sort().map(function(key) {
      // only display certain fields
      if (key !== 'OBJECTID' && key !== '_accessorProps') {
        var node = createInput(attr, key);
        var elem = document.getElementById(key);
        elem.value = inputValue(attr, key);
        // watch for updates and update the disabled form
        attr.watch(key, function(val) {
          elem.value = val;
        });
        entryForm.appendChild(node);
      }
    });
  });

This method does the query of the service and turns attributes into an Accessor. It also creates the dynamic form, but notice that it watches for changes to the Accessor and updates the disabled form. This is where you could pass updates to a FeatureService as well if you wanted to, maybe using the edit tools here.

You can see this in action in this JSBIN.

Here is a bit of an optimized version of this sample.

  qTask.execute(query).then(function (results) {
    var feature = results.features[0];
    var attr = new Accessor(feature.attributes);
    var props = Object.keys(attr).filter(function(key) {
      return key !== 'OBJECTID' && key !== '_accessorProps';
    }).sort();
    var nodeCache = {};
    attr.watch(props, function(val, _, name) {
      var elem;
      if (nodeCache[name]) {
        elem = nodeCache[name];
      } else {
        elem = document.getElementById(name);
        nodeCache[name] = elem;
      }
      elem.value = val;
    });
    props.map(function(prop) {
      var node = createInput(attr, prop);
      var elem = document.getElementById(prop);
      elem.value = inputValue(attr, prop);
      entryForm.appendChild(node);
    });
  });

That really isn't too difficult when you look at. You can basically delegate the updates to the Accessor to some other methods and simply watch for when changes take place on it.

Play around with this, get your hands deep in the Accessors and let it sink in, you won't be disappointed.

For more geodev tips and tricks, check out my blog.

more
0 0 631
ReneRubalcava
Frequent Contributor

esrijs-resources.jpg

Earlier this week, Esri announced the release of a developer support repository on github.

This is a really interesting repo, as it covers the gamut of APIs and SDKs that Esri provides. It covers stuff from Python and Java to SQL and JavaScript. It's well worth going through here to find some examples for stuff you might be working on. There's some solid ArcObjects stuff in there if you're getting hardcore. I notice MapObjects is missing (I kid, I kid). But don't worry, Flex and Silverlight are represented (still kidding). Seriously though, there's some R goodness in there, which if you didn't know, is a thing. Python folks should check it out, as there are some good scripts in here.

There are tons of really great resources for Esri devs on github. If you are a JavaScript developer, we've covered specifically how you can increase your JavaScript skills.

Last month I attended the TC Disrupt Hackathon in San Francisco. I was there to help out devs on their hacks using Esri APIs and SDKs. This was a lot of fun and I prepared the JS and Framework Integration resources repo to help developers get up and running with the ArcGIS API for JavaScript.

The goal here is to show developers how to use the ArcGIS JS API with multiple frameworks. There are resources for React, Angular, Ember and Polymer.

You can even use the JS API with other JS utility libraries like Ramda and RxJS.

It's not just other libraries you can use with the JS API, but there are resources to write your apps in TypeScript. I haven't really delved into using PureScript or ClojureScript with the JS API, although there might be a path with ClojureScript, and some post-processing that could be done with PureScript... maybe.

The point of all this is that there are lots of resources out there for Esri devs to learn from. Whether you're a novice or a pro, I'm sure you'll find something out there that can help you out.

For more geodev tips and tricks, check out my blog.

more
1 0 1,770
63 Subscribers