Working with new promise-based Worklight APIs

17 Apr

Certain new Worklight APIs, such as the new JSONStore features (which allow synchronisation of JSON data with a remote adapter), have been enhanced to return Promises as their result.

These are “Promises” in the duck-typing sense – they implement the Promise standard.

However, the attentive among you will have noticed some extra convenience functions on the Worklight promises:

  • done(successFnOrDeferred) equivalent to then(successFnOrDeferred, null)
  • fail(failureFnOrDeferred) equivalent to then(null, failureFnOrDeferred)

At first glance, these look useful. However, I’d recommend against usage of these convenience functions. When chaining promises, they are likely to confuse your developers – who may be suckered into thinking they’re available on all Promises, not just those available from Worklight.

Dojo widget property setters and attributeMap’s replacement

9 Jan

As we create widgets to accomplish a task, we often need to contain other widgets. Creating a simple way to configure contained widgets via the containing widget’s API is often accomplished using custom _setXXXAttr functions.

However, Dojo provides alternative methods to achieve this. It provides the attributeMap feature, though this is deprecated and shall be removed in version 2.0. Since version 1.7, Dojo has provided a new syntax for _setXXXAttr that allows usage of attributeMap-style configurations.
Continue reading 

Working around portrait-landscape text rendering discrepancies in Mobile Safari

12 Nov

WARNING – the below sample may have serious effects on other CSS3 transforms & transitions on your page. Use with caution (potentially as a last resort), and if you see any strange effects, try removing it first.

My current project uses landscape-mode iPads almost exclusively, and I noticed a text rendering weirdness whereby bold fonts render differently in landscape and portrait mode.

This bug report outlines the underlying issue.

This wouldn’t be too bad, but a side-effect of this issue is that the fonts in question “flash” – from normal to fat – whenever a dojox.mobile.View transition is playing, which can be distracting.

I’ve found the simplest workaround is to add the following to my app’s stylesheet:

/* Fix weird font rendering and flashing during transitions in landscape mode */
html {
	-webkit-transform: translate3d(0,0,0);
}

This fixes the appearance issue and doesn’t appear to have much impact on performance. However, I have seen serious side-effects when it comes to CSS3 transitions.

Functional Mapping Across Object Attributes in Dojo

13 Sep

Recently I discovered the very useful function dojox/lang/functional.mapIn(). This allows you to functionally transform one object to another by mapping each value in the object using a callback function. It’s similar to dojo/_base/array.map() but works on objects instead.

For example, let’s define an object like this that contains some values that are integers, and others that are strings:

var x = { "A": 1, "B": "2" };

We can convert (or normalize) all of these to strings by executing the following code:

require(["dojox/lang/functional", function(functional) {
    x = functional.mapIn(x, function(value) { return value.toString(); });
});

Now, x looks like this:

{"A":"1","B":"2"}

Using dojox “hold” gestures inside Scrollable areas

7 Aug

I have recently needed to embed widgets that react to “hold” gestures in ScrollablePanes.

Particularly when the widgets fill the ScrollablePane, this can create some problems where a user drags the ScrollablePane to scroll.  Often, a “hold” event is generated for a contained widget during the scrolling action, which may be undesired.

The following code uses dojo/aspect to monitor the scrolling state of all ScrollablePanes on the page.

require(["dojo/aspect", "dojox/mobile/ScrollablePane"], function(aspect, ScrollablePane) {
    // For demonstration purposes, we use a global variable here to hold the scrolling state for all ScrollablePanes
    // You may wish to track by ScrollablePane instance instead
    mypackage.myapp.isScrolling = false;
    aspect.before(ScrollablePane.prototype, "addCover", function() {
        // "this" is the ScrollablePane instance
        mypackage.myapp.isScrolling = true;
    });
    aspect.after(ScrollablePane.prototype, "removeCover", function() {
        // "this" is the ScrollablePane instance
        mypackage.myapp.isScrolling = false;
    });
});

Once this monitoring has been added, it is now simple to guard the contained widgets’ “hold” event handlers by inspecting mypackage.myapp.isScrolling.

Bootstrapping Dojo for debug, and CSS3 PIE

10 Jul

Dojo debug bootstrap

I often find that I need to get really basic console access to a Dojo bootstrap page, to test out Dojo’s core functions, etc. Finding a page where I can do this quickly can be a pain.

With this in mind, I’ve put together a barebones page that will load a requested version of Dojo core into memory. It supports all the versions of Dojo hosted by the Google Libraries API.

You can access this page here:

http://dojobootstrap.tk

To load a specific version of Dojo, try appending the version to the path like so:

http://dojobootstrap.tk/1.5

CSS3 PIE

The eagle-eyed among you will notice that in Internet Explorer < 9, elements in the bootstrap page still have rounded corners. This is down to use of CSS3 PIE, a great project that aims to retrofit the more useful (read: requested by clients) CSS3 decorations to IE 6-9; border-radius, box-shadow and linear-gradient backgrounds.

The project just works and the documentation is great. This finally puts to bed the spectre of ugly background-image hacks in IE. Give it a try.

Loading page specific AMD code by body id

6 Jun

So I have been writing a website recently for a local primary school. Naturally Dojo was the way forward.

I had a few server side problems to solve as it is to be running on a pretty basic RM school server, so I decided to host the “CMS” in a google spreadsheet. (subject for a later post).
Anyway, long story short, each page of the website need to pull down its appropriate data from the spreadsheet and render this on the page. This code could easily have been put into the page head of each page or split into separate JS files, but I thought, NO, I’ve seen jquery code (in my distant travels to dark lands) that uses the Id tag of the page body to pull code in from an array, maybe I’ll take that approach.
Seemed to make sense and have some pros

  • only need to load the JS once
  • caching of the JS file (unlikely to change much)
  • shared code
  • simple to edit, blocks of code in a single file

So, I set About moving all of my individual page code into a single file, this file held an object, with the appropriate page Id take used as an array reference to its initialisation function.

inits = {
    homePage : function() { },
    eventsPage : function() { },
   ...etc...
}

Problem I found, was that each of my functions was pre firing as soon as he code was read in, and why I hear you ask, because they weren’t just functions, they were calls out to require.js using the Dojo AMD format. So naturally they were self firing… which caused problems. Ie.

define([],function(){
   return {
      homePage : require(["dojo/dom", "dojo/ready"], function(dom, ready) { },
   ...etc...
   }
});

So, thinking hat back on. Decided to split each of my init functions up into separate array of requires and callback function. Simple enough idea, but effective. Ie.

define([],function(){
	return {
		homePage : {	"requires": ["dojo/io/script", "dojo/_base/array"],
						"callback" : function(ioScript, arrayUtil) {
							//Do stuff
						}
					},

		eventsPage : {	"requires" : ["dojo/dom-construct", "dojo/json"],
						"callback" : function(domConstruct, json) {
							//Do stuff						
						}
					}
	}
});

So now it plays nice!
each page now pulls in a single init.js script that pulls in a ‘run everytime’ requires / callback combo to set up side wide alerts, and then gathers the id of the body tag, and pulls in the appropriate requires / callback combo and runs it.

require(["dojo/ready", "um/inits"], function(ready, initFuncs){
	ready(function(){
		
		require(initFuncs.globalAlert.requires, initFuncs.globalAlert.callback);

		//call global alert setup
		var bodyId = window.document.body.id;
		if (bodyId && initFuncs[bodyId]) {
			require(initFuncs[bodyId].requires, initFuncs[bodyId].callback);
		}

	});
});

Thought it was a nice and simple single page, multi initialisation function AMD loaded approach.
Would appreciate feedback ladies and gentlemen.

Full google spreadsheet explanation in a later post!!

Follow

Get every new post delivered to your Inbox.

Join 62 other followers