Customizing and Creating Widgets with the Arcgis API for Javascript

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 What? Encapsulated Cohesive Single-purpose pieces of functionality User interface Why? Reusable Interchangeable Modular How? Different frameworks are available Focusing on Dijit Dojo toolkit Foundation of ArcGIS JavaScript API AMD support Class-based inheritance Internationalization Dijit Dojo’s UI Library Separate namespace (dijit) Built on top of Dojo Has themes Asynchronous Module Definition (AMD) Asynchronous loading Web-based solution Lazy loading Fewer globals Dependency handling AMD example define // moduleA.js define(["moduleB"], function (moduleB) { // module API return { _data: 100, calculate: function () { moduleB.calculate(this._data); } }; }); require // main.js require(["moduleA"], function (moduleA) { moduleA.calculate(); }); AMD Plugins text "dojo/text!./templates/WikiWidget.html" i18n "dojo/i18n!./nls/WikiWidget", Building blocks dijit/_WidgetBase What you get Lifecycle constructor postMixInProperties buildRendering postCreate startup destroy Events Getters/Setters Property watching constructor Called immediately when widget is created Can be used for initialization Can be used to manipulate widget parameters constructor: function(params) { // initialize private variables this._activeTasks = []; // manipulate user-provided params if (params && params.oldProp { params.newProp = params.oldProp; delete params.oldProp; } } postMixInProperties Called after properties have been mixed into the instance Can be used to access/alter properties after being mixed in, but before rendering postMixInProperties: function() { this.get("inherited"); this._initialTitle = this.title; } For example var myWidget = new MyWidget({ title: "myTitle" }, "sample-node"); myWidget.toUppercase(); console.log(myWidget.title); // MYTITLE console.log(myWidget._initialTitle); // myTitle 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); } } postCreate Most widget DOM nodes are ready at this point Widget not attached to the DOM yet Most common point for adding custom logic postCreate: function() { this.get("inherited"); // set up event listeners // `this.own` disposes handle when destroyed this.own( on(this.inputNode, "input", this._handleInput) ); this._activeTasks.push( this._initialize() ); } 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(); } destroy 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: function() { this.get("inherited"); this._activeTasks.forEach(function(process) { process.cancel(); }); } Events // widget function startTimer: function() { setInterval(function() { this.emit("tick"); }.bind(this), 1000); } timerWidget.on("tick", function() { console.log("timer ticked!"); }); timerWidget.startTimer(); // timer ticked! // timer ticked! // timer ticked! Getters/Setters widget.get("title"); // old widget.set("title", "new"); widget.get("title"); // new 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" Code organization Keep code modular and organized 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 Code organization: CSS Extract widget-specific styles to separate stylesheet @import widget stylesheet wherever applicable Example: before /* ./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: after MyWidget.html <div class="my-widget"> <label class="my-widget text">°˖✧◝(⁰▿⁰)◜✧˖°</label> </div> Example: after MyWidget.css .my-widget { background-color: chartreuse } .my-widget text { font-size: 1.5em; } Example: after MyWidget.js define([ "dijit/_WidgetBase", "dijit/_TemplatedMixin", "dojo/text!./templates/MyWidget.html" ], function ( _WidgetBase, _TemplatedMixin, template ) { return _WidgetBase.createSubclass([_TemplatedMixin], { templateString: template }); }); CSS Use classes <style> .my-widget { background-color: chartreuse; } </style> <div class="my-widget">...</div> and avoid inline styles <div style="background-color: chartreuse">...</div> 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 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 }); DOM manipulation Here to help... dojo/dom dojo/dom-attr dojo/dom-class dojo/dom-construct dojo/dom-style (used sparingly) DOM manipulation Here to help... // without `dojo/dom-class` document.getElementById("container-id") .classList.add("round-borders"); // with `dojo/dom-class` domClass.add("container-id", "round-borders"); Let's build a widget! WikiWidget (requirements) 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 Building WikiWidget the 3x way Steps That's all for 3.x 4.x Widgets Widget Pattern View – the face ViewModel – the brain View Uses ViewModel APIs to render the UI View-specific logic resides here ViewModel Core logic of widget resides here Provides necessary APIs for the view to do it's thing No DOM/UI concerns (think data) Benefits Reusable Testable Logic without UI concerns Framework compatibility Let's update WikiWidget Steps WikiWidget + React Demo Framework integration 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/ Tips & best practices Use a styleguide Defines rules for consistent code Naming conventions Whitespace Common patterns Etc... Some options Airbnb Google idiomatic jQuery Dojo Linting (code analysis) Highlight issues in your code based on predefined rules JSLint JSHint ESLint Formatting Format your code based on predefined rules ESLint JS Beautifier Task runners Automate all the things Grunt Gulp Testing Automated testing helps you catch regressions as you move forward Intern Jasmine QUnit Karma CSS preprocessors Features Variables Mixins @import & @extend Allow us to Restyle quickly Theme Write less code Flavors Sass Stylus Less Demo CSS methodologies Establish guidelines/rules for maintainable CSS CSS & HTML best practices Naming conventions Ordering/grouping of CSS rules Help dealing with specificity Flavors Block-Element-Modifier (BEM) Scalable and Modular Architecture for CSS (SMACSS) Object Oriented CSS (OOCSS) SUIT CSS Atomic OOBEMITSCSS No silver bullet - choose what's best for your project/team Use the source, Luke. Use GitHub to browse code and learn more about existing projects dojo dijit dojox etc... Wrapping up Suggested sessions Wednesday Operations Dashboard: Extending with Custom Widgets Thursday Web AppBuilder for ArcGIS: Customizing and Extending Web AppBuilder for ArcGIS: Build your First Widget in 15 mins Extending the Operations Dashboard for ArcGIS ArcGIS API 4.0 for JavaScript: Patterns and Best Practices Additional resources Understanding dijit/_WidgetBase ArcGIS API for JavaScript 3.0 SDK 3.x Calcite dijit theme (3.x) 4.x ArcGIS API for JavaScript 4.0 SDK Styling (4.0) Get The Code bit.ly/widgets101 Please take our survey Your feedback allows us to help maintain high standards and to help presenters Q & A Questions? Bonus: Haiku user conference— attended widget session satisfaction now .

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    60 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us