1 / 60

Widgets 101: Customizing and Creating Widgets with the ArcGIS API for JavaScript

Widgets 101: Customizing and Creating Widgets with the ArcGIS API for JavaScript. JC Franco – @arfncode Matt Driscoll – @driskull. Welcome. Agenda. Short URL: bit.ly/widgets101 About widgets Building blocks Building a widget 3.x 4.x Tips & best practices Resources Q & A. Widgets.

msampson
Download Presentation

Widgets 101: Customizing and Creating Widgets with the ArcGIS API for JavaScript

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Widgets 101: Customizing and Creating Widgets with the ArcGIS API for JavaScript JC Franco – @arfncode Matt Driscoll – @driskull

  2. Welcome

  3. Agenda Short URL: bit.ly/widgets101 About widgets Building blocks Building a widget 3.x 4.x Tips & best practices Resources Q & A

  4. Widgets What? Encapsulated Cohesive Single-purpose pieces of functionality User interface Why? Reusable Interchangeable Modular How? Different frameworks are available Focusing on Dijit

  5. Dojotoolkit Foundation of ArcGIS JavaScript API AMD support Class-based inheritance Internationalization

  6. Dijit Dojo’s UI Library Separate namespace (dijit) Built on top of Dojo Has themes

  7. Asynchronous Module Definition(AMD) Asynchronous loading Web-based solution Lazy loading Fewer globals Dependency handling

  8. define // moduleA.js define(["moduleB"], function (moduleB) { // module API return { _data: 100, calculate: function () { moduleB.calculate(this._data); } }; }); AMDexample require // main.js require(["moduleA"], function (moduleA) { moduleA.calculate(); });

  9. AMDPlugins text "dojo/text!./templates/WikiWidget.html" i18n "dojo/i18n!./nls/WikiWidget",

  10. Buildingblocks

  11. What you get Lifecycle constructor postMixInProperties buildRendering postCreate startup destroy Events Getters/Setters Property watching dijit/_WidgetBase

  12. Called immediately when widget is created Can be used for initialization Can be used to manipulate widget parameters constructor constructor: function(params) { // initialize private variables this._activeTasks = []; // manipulate user-provided params if (params && params.oldProp { params.newProp = params.oldProp; delete params.oldProp; } }

  13. Called after properties have been mixed into theinstance Can be used to access/alter properties after being mixed in, but beforerendering postMixInProperties postMixInProperties: function() { this.get("inherited"); this._initialTitle = this.title; } Forexample var myWidget = new MyWidget({ title: "myTitle" }, "sample-node"); myWidget.toUppercase(); console.log(myWidget.title); // MYTITLE console.log(myWidget._initialTitle); // myTitle

  14. buildRendering Widget template is parsed and its DOM is available Not attached to the DOM tree buildRendering: function() { this.get("inherited"); if (this.editMode) { // editor added before widget is displayed this._attachEditor(this.domNode); } }

  15. Most widget DOM nodes are ready at this point Widget not attached to the DOM yet Most common point for adding custom logic postCreate postCreate: function(){ this.get("inherited"); // set up eventlisteners // `this.own`disposeshandle this.own( on(this.inputNode,"input", ); whendestroyed this._handleInput) this._activeTasks.push( this._initialize() ); }

  16. startup Called manually or by dojo/parser, initializes all children Recommended point for doing size calculations Must always call when creating widgets programmatically startup: function() { this.get("inherited"); this._resize(); }

  17. Used for teardown logic • By default, destroys top-level support widgets Called manually to trigger widget disposal • All handles registered with this.own get removed destroy destroy: function() { this.get("inherited"); this._activeTasks.forEach(function(process) { process.cancel(); }); }

  18. // widget function startTimer: function() { setInterval(function() { this.emit("tick"); }.bind(this), 1000); } Events timerWidget.on("tick", function() { console.log("timer ticked!"); }); timerWidget.startTimer();

  19. Getters/Setters widget.get("title"); // old widget.set("title", "new"); widget.get("title"); // new

  20. Watch widget.watch("title", function(propName, oldValue, newValue) { console.log( propName + " changed from ", oldValue, " to ", newValue ); }); widget.get("title"); // old widget.set("title", "new"); // "title" changed from "old" to "new"

  21. Codeorganization Keep code modular andorganized

  22. Code organization:HTML Extract HTML to separate file Mix in dijit/_TemplatedMixin Renders HTML based on a template string (use dojo/text plugin) Create DOM node attachments

  23. Code organization:CSS Extract widget-specific styles to separatestylesheet @import widget stylesheet whereverapplicable

  24. /* ./MyWidget.js */ define([ "dijit/_WidgetBase", "dijit/_TemplatedMixin" ], function ( _WidgetBase, _TemplatedMixin ) { return _WidgetBase.createSubclass([_TemplatedMixin], { templateString: "<div style='background-color: chartreuse;'>" + "<label style='font-weight: bolder;'>°˖✧◝(⁰▿⁰)◜✧ "</div>"; }); }); Example:before

  25. Example:after MyWidget.html <div class="my-widget"> <label class="my-widgettext">°˖✧◝(⁰▿⁰)◜✧˖°</label> </div>

  26. Example:after MyWidget.css .my-widget { background-color: chartreuse } .my-widgettext { font-size: 1.5em; }

  27. MyWidget.js Example:after define([ "dijit/_WidgetBase", "dijit/_TemplatedMixin", "dojo/text!./templates/MyWidget.html" ], function ( _WidgetBase, _TemplatedMixin, template ) { return _WidgetBase.createSubclass([_TemplatedMixin], { templateString: template }); });

  28. CSS Useclasses <style> .my-widget{ background-color:chartreuse; } </style> <divclass="my-widget">...</div> and avoid inlinestyles <div style="background-color:chartreuse">...</div>

  29. Accessibility(a11y) Enable your application to be used by everyone Consider other input devices besides the mouse Keyboard Touch Screen reader semantic markup, ARIA roles dijit/a11yclick

  30. Internationalization(i18n) Keep text separate from application logic Support multiple languages Helps ease translation define({ root: ({ "button": "Home", "title": "Default extent" }), "ar": 1, ... "zh-cn": 1 });

  31. DOMmanipulation Here to help... dojo/dom dojo/dom-attr dojo/dom-class dojo/dom-construct dojo/dom-style (used sparingly)

  32. DOMmanipulation Here tohelp... // without `dojo/dom-class` document.getElementById("container-id") .classList.add("round-borders"); // with `dojo/dom-class` domClass.add("container-id", "round-borders");

  33. Let's build awidget!

  34. Use Wikipedia API to geosearch for entries Display results in a list List items should center on the map and display a popup The popup should have a link for more info (wiki page) Preview WikiWidget(requirements)

  35. Building WikiWidget the 3xway Steps

  36. That's all for3.x

  37. 4.xWidgets Widget Pattern View – the face ViewModel – the brain

  38. View Uses ViewModel APIs to render the UI View-specific logic resides here

  39. ViewModel Core logic of widget resides here Provides necessary APIs for the view to do it's thing No DOM/UI concerns (think data)

  40. Benefits Reusable Testable Logic without UI concerns Framework compatibility

  41. Let's updateWikiWidget Steps

  42. WikiWidget +React Demo

  43. Frameworkintegration Use ViewModels to create custom UIs in the framework of your choice Angular 2– demo React– demo Elm– demo Ember Rene Rubalcava - http://odoe.net/

  44. Tips & bestpractices

  45. Use astyleguide Defines rules for consistent code Naming conventions Whitespace Common patterns Etc... Some options Airbnb Google idiomatic jQuery Dojo

  46. Linting (codeanalysis) Highlight issues in your code based on predefined rules JSLint JSHint ESLint

  47. Formatting Format your code based on predefined rules ESLint JS Beautifier

  48. Taskrunners Automate all the things Grunt Gulp

  49. Testing Automated testing helps you catch regressions as you move forward Intern Jasmine QUnit Karma

  50. Features Variables Mixins @import & @extend Allow us to Restyle quickly Theme Write less code Flavors Sass Stylus Less Demo CSSpreprocessors

More Related