How to load leaflet.js and leaflet plugins with dojo AMD

Reply
<script type="text/javascript">
var dojoConfig = {
  baseUrl: '/lib',
  async: true,
  packages: [
    {name: 'Leaflet', location: './Leaflet'}
  ],
  map: {
    // lets you switch between minified and source version of leaflet for development
    '*': {
      'Leaflet/leaflet': 'Leaflet/leaflet-src'
    }
  }
};
</script>
<script type="text/javascript" src="lib/dojo/dojo.js"></script>

<script type="text/javascript">
require([
  'require',
  'Leaflet/leaflet'
], function(require, L) {

  // load plugin after loading leaflet, because it's referenced by the draw plugin
  require(['Leaflet/plugins/draw/leaflet.draw'], function() {

    var drawControl = new L.Control.Draw({...}),
    map = L.map(...);
    ...

  }):
});

How to import c3.js with the dojo AMD loader

2 Replies

I came across the nice chart library c3.js, which is based on d3.js. In order to load it via an AMD require call with dojo, you also need to set the main property in the dojoConfig, e.g.:

dojoConfig = {
    packages: [
        { name: 'd3', location: '../../../d3', main: 'd3' }
        { name: 'c3', location: '../../../c3', main: 'c3' }
    ]
}

This will let you load c3.js in your module, e.g.:

define(['d3', 'c3', ...], function(d3, c3, ...) {
    ...
}

How to use Google Maps API with Dojo and AMD

Reply

If you are using AMD or RequireJS for your JavaScripts and you would also like to use the Google Maps JavaScript API you have a problem. You can’t just require in the script file and then access the google.maps object from within your script, e.g.:

require(['http://maps.googleapis.com/maps/api/js?client=YOUR_CLIENT_ID'], function() {
    var myMap = new google.maps.Map(mapDiv, mapOptions);
}

This doesn’t work because the map script itself loads another script, which might not have been loaded yet, when you access the google.maps.Map object.

Continue reading

Changing cursor to wait while request is in progress

Reply

Switching cursor to ‘wait’ and back to ‘default’ is tricky since some elements such as link, input or button have a different default style. Setting it back to ‘auto’ does not work in Firefox, but to an empty string works. Here’s how you would do it with dojo:

require(['dojo/_base/connect', 'dojo/query'], function(connect, query) {
	// change cursor on first ajax request
	connect.subscribe("/dojo/io/start", function() {
		query('*').style('cursor', 'wait'); // also when mouse is over buttons or inputs
	});
	// change cursor back on last ajax request
	connect.subscribe("/dojo/io/stop", function() {
		window.setTimeout(function() { // seems to fix FF not always setting cursor back to auto on some elements
			query('*').style('cursor', ''); // in FF auto would set default cursor, use '' instead
		}, 50);
	});
});

REST with dojo and PHP: Notes on using dgrid with a caching store

18 Replies

I would like to share some (personal) pitfalls I came across when creating the demo REST with dojo and PHP: Demo of a dgrid observing changes to the JsonRest store:

  • dojo/store/Observable only works correctly when the object has an id. Unfortunately, dojo/store/Memory.add(object) does not add the id to the object when creating it (as of 1.7.1) .  See bugs #12835 and #14281. For a fix see changeset #27072
  • Observable does only work correctly with a store, that provides a queryEngine. dojo/store/JsonRest does not have a queryEngine by default, so you will have to provide your own. If you are using a cache, observe the dojo/store/Memory directly. Upate 29.06.2012: For a fix see changeset #29069.
  • As stated in the docs, but easily missed: dojo/store/Cache automatically adds all returned objects from get() and query() calls to the cache, but only get() uses the cache, whereas query() directly uses the master store. If you want the query to come from the cache, directly call query() on the caching store, e.g. dojo/store/Memory.
  • In the demo, the PHP script responds to the GET 2 by returning a Json object with id 2 and to a GET 2/ by returning an array of objects with parent id 2. If you want to query the Memory store for 2’s children, you have to provide an object as an argument, e.g. storeMemory.query({parId: 2}), whereas the JsonRest store expects a string e.g. storeJsonRest.query(‘2/’);
  • JsonRest store’s methods do not return the same types as Memory store, which can be confusing…
    storeMemory.add(newObject) returns the id
    storeJsonRest.add(newObject) returns the response from the server (or rather a Deferred providing it)
    …, but makes sense, because it can save an extra round trip to the server.

Also see dojo/store/Observable and dojo/store/Cache more info.

 

Dojo Demo: Multiple file uploading with pause/resume

35 Replies

Update 09.2013: You can also use the file picker (file input) now.

I implemented a demo of a file uploader with dojo and PHP that lets you upload multiple files at once with drag and drop. The upload of each file can be paused/resumed thanks to the slice method of the new Blob interface.

Download: The php and js code is available for download on github.com.
More info: How to resume a paused or broken file upload Continue reading

Creating a ‘blocking’ confirm dialog with dojo

22 Replies

Update 30.03.2018: Version 1.10 of dojotoolkit includes a dijit/DialogConfirm now, which is simply a dijit/Dialog featuring ‘OK’ and ‘Cancel’ buttons, no blocking though.

Update 15.10.2012: Code is available on githup now. I also fixed updating the content of the dialog after creation (e.g. dialog.set(‘content’, newContent) overwrote the confirm/cancel buttons because they were part of the content.

Update 03.12.2011: I updated the code to use dojo 1.7 with AMD. I also moved the creation of the Deferred to the show() method as suggested by ben, which will make the instance of the dialog reusable. Added new property hasUnderlay: true, which can be set to false.

JavaScript has a window.confirm() method, which opens a dialog and stops code execution until the user presses either the ‘OK’ or ‘Cancel’ button. Dojo also comes with a dijit.Dialog widget, but that doesn’t exhibit the same blocking behavior. Since I needed to simulate the native blocking behavior for an application I am currently developing, I extended the widget and created the DialogConfirm widget with the following features:

  • shows an ‘OK’ and ‘Cancel’ button by default (can be set to false)
  • shows a check box, which when set will remember the decision and not ask again (can be set to false)
  • the show() method returns a dojo.Deferred() which allows you to simulate the code blocking
  • underlay can be hidden

The demo of the DialogConfirm widget shows you how to halt code execution by just using the then() method of the returned deferred as follows:

var dialog = new snet.DialogConfirm({
   title: 'Confirm',
   content: '<p>Dialog content lore ipsum</p>'
});
dialog.show().then(function(remember) {
   // user pressed ok button
   // remember is true, when user wants you to remember his decision (user ticked the check box)
   if (remember) {
      // do something and never show this dialog again
   }
   else {
      // do something
   }
}, function() {
   // user pressed cancel button
   // do something
});

phpStorm and documenting JavaScript

Reply

I’m awed again and again by phpStorm‘s features. I just came across this one: When I comment my JavaScript methods/functions with the @param, all IDEs I have tried out so far, let you only set a primitive type in curly braces, e.g.:

 /**
 * Some method description.
 * @param {Object} deferred dojo.Deferred
 **/
someMethod: function(deferrede) {
   // ...
}

Anything else would be marked as an error. But phpStorm is a lot, lot smarter.  When I’m using dojo it recognizes all classes and I can use them as a type, e.g.:

 /**
 * Some method description.
 * @param {dojo.Deferred} deferred
 **/
someMethod: function(deferred) {
  // ...
}