Sie sind auf Seite 1von 140

appliness

FEBRUARY 2013 TABLE OF CONTENTS

BOOKMARK / SHARE / TOC

CODING

DEFERREDS AND PROMISES IN JAVASCRIPT

jQUERY MOBILE AND BACKBONE INTEGRATION

BACON.JS MAKES FUNCTIONAL REACTIVE PROGRAMMING SIZZLE

BUILDING A UNIT TEST IN JASMINE, PART 1.

@
BUBBLING IN ENYO, PART 2. THE FUTURE OF JAVASCRIPT

THINGS ABOUT THE WEBKIT INSPECTOR

MO

PS BILE AP

- ANG FOCUS

ULARJS

MY WORKFLOW FOR DEVELOPING PHONEGAP APPS

INTERVIEW MISKO HEVERY

ANDROID PUSH NOTIFICATIONS WITH PHONEGAP

BUILDING HUUUUGE APPS WITH ANGULARJS

WEB DE

SIGN

RESPONSIVE FORM VALIDATION

FORM ELEMENTS AND CSS3 TO REPLACE JS

MAKING THE TRANSITION TO DESIGN

ICONS AND ICON FONTS

CONDITIONAL LOADING WITH MEDIA QUERIES

DESIGN IS NOT VENEER

by Brian Rinaldi

NEWS

appliness

appliness

TUTORIALS JAVASCRIPT

BOOKMARK / SHARE / TOC

Deferreds and Promises in JavaScript


by Flavio Copes

TUTORIALS DEFERREDS AND PROMISES IN JAVASCRIPT

by Flavio Copes
INTRODUCTION

I think it generates way more readable code, and its less quikky.

Promises are a relatively new approach to async management, and they can be really helpful to structure your code. A Promise is an object representation of an event. In the course of its life, a Promise goes from a pending state, when its called, to a resolved or rejected state, when its been completed, or it could also stay pending forever and is never resolved. Its a sort of new approach to javascript events, but I think it generates way more readable code, and its less quirky. At the moment there are 2 slightly different main implementations of Promises in javascript: those libraries that follow the Promises/A spec, and jQuery. First Ill take jQuery into consideration as its everywhere and I use it, so if you dont want another external library, you can use it. JQUERY PROMISES Lets introduce the concept of Deferred. First, a Deferred is a Promise, with in addition the fact that you can trigger a Deferred (resolve or reject it), while with a Promise, you can only add callbacks and it will be triggered by something else. A Promise, if you want, is a listen-only part of a Deferred. A clear example of this is this function:
var promise = $(div.alert).fadeIn().promise();

You can now add .done() & .fail() to handle the callbacks. This is just a call example, promises for animations have become a real deal in jQuery 1.8, also with callbacks for progress. Another example of a promise is an AJAX call:
var promise = $.get(url); promise.done(function(data) {});
2 of 11

TUTORIALS DEFERREDS AND PROMISES IN JAVASCRIPT

A deferred is something you create, set the callbacks and resolve, like:
var deferred = new $.Deferred(); deferred.done(function(data) { console.log(data) }); deferred.resolve(some data);

The state of a deferred can be triggered using .resolve() or .reject(). Once a deferred state has been changed to one of the final stages (resolved/rejected), it cant be changed any more.
var deferred = new $.Deferred(); deferred.state(); // pending deferred.resolve(); deferred.state(); // resolved

We can attach the following callbacks to a promise:


.done() //will run when the promise has been executed successfully .fail() //will run when the promise has failed .always() //will run in either cases

Those callbacks can be called together using .then(), like:


promise.then(doneFunc, failFunc, alwaysFunc);

This is just an intro to the jQuery implementation of Promises and Deferreds. Lets write some real-word examples. (if executing in node, you can import jQuery by using $ = require(jquery); ) SOME JQUERY EXAMPLES For example, here we execute a function, and when its finished it calls dfd.resolve(). Similar to doing a callback, but more structured and reusable.
$.when(execution()).then(executionDone); function execution(data) { var dfd = $.Deferred(); console.log(start execution); //in the real world, this would probably make an AJAX call. setTimeout(function() { dfd.resolve() }, 2000); return dfd.promise();
3 of 11

TUTORIALS DEFERREDS AND PROMISES IN JAVASCRIPT

} function executionDone(){ console.log(execution ended); }

Here the elements of an array are processed, and once all of them are fine (e.g. a request has returned), I call another function. We start to see the real benefits of the Deferred usage. The $.when.apply() method is used to group the dfd.resolve() in the loop.
var data = [1,2,3,4]; // the ids coming back from serviceA var processItemsDeferred = []; for(var i = 0; i < data.length; i++){ processItemsDeferred.push(processItem(data[i])); } $.when.apply($, processItemsDeferred).then(everythingDone); function processItem(data) { var dfd = $.Deferred(); console.log(called processItem); //in the real world, this would probably make an AJAX call. setTimeout(function() { dfd.resolve() }, 2000); } return dfd.promise();

function everythingDone(){ console.log(processed all items); }

A slightly more complex example, here the elements of the array are fetched from an external resource, using var fetchItemIdsDeferred = fetchItemIds(data) and fetchItemIdsDeferred.done()
var data = []; // the ids coming back from serviceA var fetchItemIdsDeferred = fetchItemIds(data); // has to add the ids to data function fetchItemIds(data){ var dfd = $.Deferred(); console.log(calling fetchItemIds); data.push(1);
4 of 11

TUTORIALS DEFERREDS AND PROMISES IN JAVASCRIPT

data.push(2); data.push(3); data.push(4); setTimeout(function() { dfd.resolve() }, 1000); return dfd.promise();

fetchItemIdsDeferred.done(function() { // if fetchItemIds successful... var processItemsDeferred = []; for(var i = 0; i < data.length; i++){ processItemsDeferred.push(processItem(data[i])); } $.when.apply($, processItemsDeferred).then(everythingDone); }); function processItem(data) { var dfd = $.Deferred(); console.log(called processItem); //in the real world, this would probably make an AJAX call. setTimeout(function() { dfd.resolve() }, 2000); } return dfd.promise();

function everythingDone(){ console.log(processed all items); }

Those last 2 examples explain how to compute a for cycle and then wait for the end of the processing execution to do something. Its the less hacky way of doing this:
var allProcessed = false; var countProcessed = 0; for (var i = 0, len = theArray.length; i < len; i++) { (function(i) { // do things with i if (++countProcessed === len) allProcessed = true; })(i); }

5 of 11

TUTORIALS DEFERREDS AND PROMISES IN JAVASCRIPT

Now another example of how Deferreds can be used for: take a look at this
var interval = setInterval(function() { if (App.value) { clearInterval(interval); // do things } }, 100);

This is a construct that evaluates a condition; if the condition is true, the code clears the interval and executes the code contained in the if. This is useful for example to check when a value is not undefined any more:
var DeferredHelper = { objectVariableIsSet: function(object, variableName) { var dfd = $.Deferred(); var interval = setInterval(function() { if (object[variableName] !== undefined) { clearInterval(interval); console.log(objectVariableIsSet); dfd.resolve() } }, 10); return dfd.promise(); }, arrayContainsElements: function(array) { var dfd = $.Deferred(); var interval = setInterval(function() { if (array.length > 0) { clearInterval(interval); console.log(arrayContainsElements); dfd.resolve() } }, 10); } return dfd.promise();

var executeThis = function() { console.log(ok!); }


6 of 11

TUTORIALS DEFERREDS AND PROMISES IN JAVASCRIPT

var object = {}; object.var = undefined; var array = []; $.when(DeferredHelper.arrayContainsElements(array)).then(executeThis); $.when(DeferredHelper.objectVariableIsSet(object, var)).then(executeThis); setTimeout(function() { object.var = 2; array.push(2); array.push(3); }, 2000);

The above example is in fact 3 examples in one. I created a DeferredHelper object and its methods arrayContainsElements and objectVariableIsSet are self-explaining. Keep in mind that primitive types are passed by value, so you cant do
var integerIsGreaterThanZero = function(integer) { var dfd = $.Deferred(); var interval = setInterval(function() { if (integer > 0) { clearInterval(interval); dfd.resolve() } }, 10); return dfd.promise(); }; var variable = 0; $.when(integerIsGreaterThanZero(variable)).then(executeThis);

nor you can do


var object = null; var variableIsSet = function(object) { var dfd = $.Deferred(); var interval = setInterval(function() { if (object !== undefined) { clearInterval(interval);

7 of 11

TUTORIALS DEFERREDS AND PROMISES IN JAVASCRIPT

} }, 10);

console.log(variableIsSet); dfd.resolve()

return dfd.promise(); }; $.when(variableIsSet(object)).then(executeThis); setTimeout(function() { object = {}; }, 2000);

because when doing object = {}, the object reference is changed, and as Javascript actually references variables by copy-reference, the reference of the object variable inside the variableIsSet function is not the same as the outer object variable. AN EMBER.JS EXAMPLE A thing I use with Ember.js is
App.DeferredHelper = { /** * Check if an array has elements on the App global object if object * is not set. * If object is set, check on that object. */ arrayContainsElements: function(arrayName, object) { var dfd = $.Deferred(); if (!object) object = App; var interval = setInterval(function() { if (object.get(arrayName).length > 0) { clearInterval(interval); dfd.resolve() } }, 50); return dfd.promise(); }, /** * Check if a variable is set on the App global object if object * is not set.

8 of 11

TUTORIALS DEFERREDS AND PROMISES IN JAVASCRIPT

* If object is set, check on that object. */ variableIsSet: function(variableName, object) { var dfd = $.Deferred(); if (!object) object = App; var interval = setInterval(function() { if (object.get(variableName) !== undefined) { clearInterval(interval); dfd.resolve() } }, 50); } return dfd.promise();

so I can do in my client code:


$.when(App.DeferredHelper.arrayContainsElements(itemsController.content)) .then(function() { //do things });

and
$.when(App.DeferredHelper.variableIsSet(aVariable)) .then(function() { //do things }); //& $.when(App.DeferredHelper.variableIsSet(aVariable, anObject)) .then(function() { //do things });

All those examples were made using the jQuery deferreds implementation. Additional resources on them: http://robdodson.me/blog/2012/06/03/make-your-own-jquery-deferreds-andpromises/ http://msdn.microsoft.com/en-us/magazine/gg723713.aspx
9 of 11

TUTORIALS DEFERREDS AND PROMISES IN JAVASCRIPT

If youre not willing to use the jQuery deferred implementation, maybe because youre not using jQuery and loading it just for the deferreds is overkill, or youre using another library that does not have a deferred implementation, you can use other libraries specialized in this, such as Q, rsvp.js, when.js. USING WHEN.JS For example, I have the ID of an item, and I want to call the API endpoint to get more detail about it. Once the AJAX call returns, continue processing.
function processItem(item) { var deferred = when.defer(); var request = $.ajax({ url: /api/itemDetails, type: GET data: { item: item } }); request.done(function(response) { deferred.resolve(JSON.parse(response)); }); request.fail(function(response) { deferred.reject(error); }); } return deferred.promise;

var item = { id: 1 } processItem(item).then( function gotIt(itemDetail) { console.log(itemDetail); }, function doh(err) { console.error(err); } );

10 of 11

TUTORIALS DEFERREDS AND PROMISES IN JAVASCRIPT

I got some ID values from a server, process them using the processItem() function from above, and then once finished processing ALL of them, I can do something
function processItems(anArray) { var deferreds = []; for (var i = 0, len = anArray.length; i < len; i++) { deferreds.push(processItem(anArray[i].id)); } } return when.all(deferreds);

var anArray = [1, 2, 3, 4]; processItems(anArray).then( function gotEm(itemsArray) { console.log(itemsArray); }, function doh(err) { console.error(err); } );

The when.js library provides some utility methods such as when.any() and when. some(), that let the deferred callback run when 1) one of the promises has been solved 2) at least a specified number of promises have returned.

Flavio Copes
Frontend engineer

HIS BLOG

SHARE

TWITTER

GITHUB

appliness

TUTORIALS JAVASCRIPT

BOOKMARK / SHARE / TOC

jQuery Mobile and jQuery Mobile and BackBackbone.js Integration bone.js Integration with a with a Simple FAQ App. Simple FAQ App.
by Thibault Durand

TUTORIALS JQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

by Thibault Durand
GETTING STARTED

Using the Backbone routing approach gives you much more maintainable code.

This project is hosted on github here: http://github.com/tdurand/faq-app-clientmobile-comparison UPDATE (26/10/12) : Jquery Mobile Team added a sample in the offical docs which is using one of the methods presented below: Backbone Based Routing (+ here you will found some tips for transition management ) : http://jquerymobile.com/test/docs/ pages/backbone-require.html ABOUT Disclaimer: Im not an expert on the subject, and maybe Im wrong or incomplete on some points, I would really appreciate some feedback. Context: This small FAQ app will be used in production by Mosalingua, if youre interested in a great apps to learn languages, you should definitely check out http:// www.mosalingua.com. This project aims to compare two different methods to integrate Backbone.js with jQuery Mobile (currently v 1.1.1). Its a basic FAQ visualization app which consume webservice from this project: http:// github.com/tdurand/faq-app-server. Two different approaches: keep jQuery Mobile default router and use the jquery-mobile router project which extend the native jQMobile router giving the possibility to pass parameters. (Project on github) disable jQuery Mobile default router and use Backbone for routing. (based on addyosmanI works)

2 of 10

TUTORIALS JQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

DEMOS Jquery mobile routing : link Backbone.js routing : link

COMPARISON ROUTING DECLARATION Backbone routing Backbone based routing is way better is this point, you can specify your routes like this:
routes: { : :lang: :lang/category/:id: :lang/category/:id/entry/:idEntry: }, index, index, category, category,

And then you can access the parameters in your handlers:


3 of 10

TUTORIALS JQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

category:function(lang,id,idEntry) { var categoryView=new CategoryView({id:id,lang:lang,idEntry:idEntry}); faq.appView.show(categoryView); this.changePage(categoryView,transition); $.mobile.showPageLoadingMsg(); },

You can have really cleans and REST Like urls. jQuery Mobile Router jQM router doesnt give you the possibility to do pretty routing like this. More info here on why. Example of an url:
#category?param1=qsj&params2=sj

The routes declaration looks like this, you specify a regex to get the parameters:
#index(?:[?](.*))?: { handler: index, events: bs }, #category(?:[?](.*))?: { handler: category, events: bs }

And then you can access the parameters in your handlers:


index:function(type,match){ //Default lang var lang=fr; if(match[1]!==undefined) { var params=Router.getParams(match[1]); //GET the params lang=params.lang; } this.indexView=new IndexView({lang:lang}); },

ROUTING : URL HASH UPDATING A good web application design rule is that you can bookmark any page. For a front-end application it implies that you can easily manage the window.location object to update the current url.
4 of 10

TUTORIALS JQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

Backbone routing Backbone provides a really nice way to do it with the navigate function of the router (http://backbonejs.org/#Router-navigate). You can update the url and choose if you want to trigger the route, and even if you want to add the action in the history. In the demo apps is particularly useful to be able to bookmark a particular entry:
//Update the url without triggering the route faq.routers.router.navigate(#+Entries.lang+/category/+Entries. idCategory+/entry/+expandedEntryId,{replace: true}); //Attach a collapsed handler expandedElement.on(collapse.expanded,function() { //Update the url when collapsing faq.routers.router.navigate(#+Entries.lang+/category/+Entries. idCategory,{replace: true}); $(this).off(collapse.expanded); });

jQuery Mobile Router With jquery mobile router youll need to do all by hand. And yet i didnt find how to use windows.location.replace() without causing a jQM triggering a new rendering.
//Change url TODO: SEE HOW TO DO NOT TRIGGER ROUTER window.location.replace(#category?lang=+Entries.lang+&id=+Entries. idCategory+&idEntry=+expandedEntryId); //Attach a collapsed handler expandedElement.on(collapse.expanded,function(e) { $(this).off(collapse.expanded); window.location.replace(#category?lang=+Entries. lang+&id=+Entries.idCategory); });

TRANSITIONS MANAGEMENT Backbone routing I think is the ugliest part of backbone routing based integration.

5 of 10

TUTORIALS JQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

Because you manually change the page in the router , you need to know the transition at this moment of the execution. But when the handler corresponding to your route is called by the Backbone Router, you do not have this information.
$.mobile.changePage($(view.el), { transition:NEEDTONOWTHETRANSITION, changeHash:false, reverse:true or false });

TRANSITION AS PARAMETERS A solution is to pass the transition as a parameter, its ugly because you pollute your url with transition data which you need to clean after. Router:
:lang: :lang/:transition: :lang/:transition/reverse/:reverse: index, index, //Handle specific transition index, //Handle reverse

Links:
<a href=#fr/slide/reverse/true>Back</a> //Back button link

An you handle transition in the router like this


index:function(lang,transition,reverse){ //Set lang if given if(lang) { this.lang=lang; } //Clean the url ( #fr/slide/reverse/true -> #fr) this.navigate(#+this.lang, {replace: true}); var indexView=new IndexView({lang:this.lang}); this.changePage(indexView,transition,reverse); }

In reality, you dont need to specify the transition every time, you can define a default transition (for example slide) and just specify the transition if you dont want the default transition. Although for backbutton you must specify the reverse transition

6 of 10

TUTORIALS JQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

HANDLING CLICKS OR TOUCHS ON LINKS TO GET THE TRANSITION A better solution ive found is to attach an handler on all links of the views and set a global var lastTransition which is updated every time a link is triggered.
initialize:function() { var me=this; //Global Transition handler $(a).live(touch click,function(e) { me.setNextTransition(this); }); }, setNextTransition:function(el) { faq.nextTransition.type=$(el).attr(data-transition); faq.nextTransition.reverse=$(el).attr(data-reverse); }

The change page method:


changePage:function (view) { //Defaults var reverse=faq.defaults.reverse; var transition=faq.defaults.transition; //Get last transition information if exists if(faq.nextTransition.type!=undefined) { if(faq.nextTransition.reverse!=undefined) { reverse=true; } transition=faq.nextTransition.type; } $.mobile.changePage($(view.el), { transition:transition, changeHash:false, reverse:reverse }); },

And the links are like jQM with the data-transition attribute, and we can add the data-reverse attribute if we want a reversed transition
<a href=#fr data-transition=slide data-reverse=true data-icon=back >Back</a>

This method is much more cleaner in term of boilerplate code, but its still not perfect. Im open to better propositions ;-).
7 of 10

TUTORIALS JQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

JQUERY MOBILE ROUTER Like native jQM, youll just need to put a data-transition attribute on the link and jQM will handle the rest. Additionally, jQM will detect that you need a reverse transition when you press back button. EVENTS BACKBONE ROUTING Unlike jQuery Mobile Router, you cant trigger the routes handler on jquery mobile events (backbone trigger the routes on url changes), but you always can access to this events by putting a handler if you need it. JQUERY MOBILE ROUTER The main reason is to preserve the granularity offered by jQuery Mobile while giving the programmer a simple way to tap into unusual page transition states, such as pageinit or pageremove, as if they were standard routes. The outcome is a controller which is more powerful and versatile, in the jQM realm, than its purely hashchange based counterpart. With jQuery Mobile Router you can trigger the routes on some precise events:
bc c i bs s bh h rm bC bl l => => => => => => => => => => => pagebeforecreate pagecreate pageinit pagebeforeshow pageshow pagebeforehide pagehide pageremove pagebeforechange pagebeforeload pageload

With the transition management this one of the main advantage of using jQuery Mobile Router.
8 of 10

TUTORIALS JQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

MISCELLANEOUS REUSABILITY Using backbone for routing clearly separe your view logic from you app logic, you can easily reuse you code to build a new interface (for Desktop, Tablet ) COMPABILITY Do not use jQM default routing and you can forget the B and C grade support : http://jquerymobile.com/demos/1.2.0/docs/about/platforms.html CONCLUSION Depending on your project requirements, both solution can be adopted. If you are doing only a phonegap app, maybe you just dont care to have pretty urls, and you want to use most of the jQM features. Using Backbone for routing makes use of jQMobile only as an UI framework from that you can switch to build other interface to your app. I think that for a big project, backbone routing approach will gives you a code much more maintainable, and if you are doing a web app clean url are priceless. I will really appreciate some feedback! FEEDBACK From Andrea Zicchetti, main developer of jquery mobile router. I was discussing certain aspects of routing with John Bender, the jQM developer responsible of these things (for the 1.2.1 release he promised to clean things up and fix some nasty bugs related to routing), and I think he should read from your article where the framework fails to support programmers: clean urls bookmarking of internal page states

9 of 10

TUTORIALS JQUERY MOBILE AND BACKBONE.JS WITH A SIMPLE FAQ APP

It would be great if you could stress a little bit more that jQM is currently posing some limitations that are not easy to circumvent at the moment. For instance, you could achieve clean urls with a (complex) technique that involves disabling push-state, using ajax-mode and preventing the default loadpage behavior. This is done by binding to the pagebeforeload event. In practice, you inject the page into the dom yourself without performing the ajax call and, since youre in ajax mode, your can shape your urls as you please.

Thibault Durand
Freelance Software Developer

HIS BLOG

SHARE

TWITTER

GITHUB

appliness

TUTORIALS JAVASCRIPT

BOOKMARK / SHARE / TOC

Bacon.js Makes Functional Reactive Programming Sizzle


by Ville Lautanala

TUTORIALS BACON.JS MAKES FUNCTIONAL REACTIVE PROGRAMMING SIZZLE

by Ville Lautanala
GETTING STARTED

At Flowdock, weve been using Bacon to handle all kinds of things...

Like most other JavaScript developers, weve been in a callback hell. Functional Reactive Programming (FRP) is one, and in our opinion rather powerful, tool to improve the structure of your web app. This blog post introduces FRP concepts and benefits with Bacon.js, an FRP library for both browsers and server-side JS. Weve been using Bacon.js in the new Flowdock. Reactive programming is different from event-driven programming in the sense that it focuses on data flows and propagation of change instead of handling single events. Photo by the Pug Father For example, in an imperative world, there could be a statement that sums up two variables and produces a third variable. If either of the variables change, you wouldnt expect the value of the result variable to change. If youre using reactive building blocks, the result variable would always be the sum of the two variables. In this sense, reactive programming is almost like a spreadsheet. FRP implements reactive programming with functional building blocks. Referential transparency is strictly enforced, which prohibits the use of variables. An alternative way has to be used to handle time-varying values. The main concepts in FRP are properties (not to be confused with JavaScript properties) and event streams. There are different names for these in different implementations. Signal and event are commonly used, but well stick with Bacon.js nomenclature. EventStreams are sources of events. These can be mouse clicks, keyboard events or any other input. The power of EventStreams is that they are composable. It is possible to use similar tools that are used to handle arrays for event streams: you can filter events, map event values to other values or reduce events to a property. Property is used as an abstraction for a time-varying value. Properties are similar to EventStreams, but they also have the notion of current value. Most of the functionality is shared with EventStreams.
2 of 6

TUTORIALS BACON.JS MAKES FUNCTIONAL REACTIVE PROGRAMMING SIZZLE

STREAMS AND PROPERTIES IN BACON Lets try out this FRP thing by figuring out if the user is active on a web page. This is something weve had to do in Flowdock to determine what kind of notifications we should play. For example, we dont want to bother users with sound notifications when they are participating actively in the current discussion. The easiest thing that could work is to use focus and blur events. A pretty standard approach to this, using jQuery would be
var focused = true; $(window).on(blur, function() { focused = false; }); $(window).on(focus, function() { focused = true; });

Not that bad, but how about the FRP approach then?
var blur = $(window).asEventStream(blur).map(function() { return false; }); var focus = $(window).asEventStream(focus).map(function() { return true; }); var focused = focus.merge(blur).toProperty(true);

Two Bacon.js EventStreams are defined: blur that emits falses and focus that emits trues. Then the streams are combined using using merge and converted to a Property that captures the value of focus. true is defined as initial value. If you want to inspect the value, a listener to the Property can be bound using onValue
focused.onValue(function(focus) { console.log(focus, focus); });

Theres one gotcha: Bacon.js is lazy. Before the stream or property has any subscribers, it wont do anything. The current value of the property wont update and event listeners arent bound to the DOM. This can be very useful since it means creating streams causes zero overhead. HANDLING STATE WITH SWITCHING STREAMS The focus/blur idea to handle activity state is usually not good enough. The focus and blur events arent always reliable and we wont have any idea if the user has left the computer three hours ago. How about using keyboard and mouse activity then? Lets say that users are active
3 of 6

TUTORIALS BACON.JS MAKES FUNCTIONAL REACTIVE PROGRAMMING SIZZLE

when they have moved the mouse pointer or pressed some key within the last 30 seconds. For comparison, this could be implemented in plain old jQuery as follows:
var active = true; var timeout = null; function setInactive() { active = false; } $(window).on(keydown mousemove, function() { active = true; clearTimeout(timeout); timeout = setTimeout(setInactive, 30000); })

A Bacon EventStream of user activities is a good start.


var activity = $(window).asEventStream(mousemove keydown)

The stream only contains events of the positive case. Negative case requires you to detect when there is no activity. Heres where stream switching becomes useful.
var active = activity.flatMapLatest(function(event) { return Bacon.once(true).merge(Bacon.later(30000, false)); }).toProperty(true);

Here stream switching is used to implement state in a functional world. In Bacon, flatMap maps each event in the stream to a new stream of events. flatMapLatest works like flatMap, except that only events from the latest spawned stream are included. So, the value is true for 30 seconds after the last user interaction. This isnt the only, or even the simplest, way to implement such an activity property. Bacon throttle could be used to only emit events after a quiet period.
activity.map(function() { return true; }).merge( activity.throttle(30000).map(function() { return false; }) ).toProperty(true);

If this is compared to the event-driven solution, youll see that the FRP solution looks more desirable. There are less moving parts and the code is more focused on the logic rather than implementation details.
4 of 6

TUTORIALS BACON.JS MAKES FUNCTIONAL REACTIVE PROGRAMMING SIZZLE

COMPOSING PROPERTIES The activity based solution might be more resilient than using window blur and focus events, but blur is still useful. Since focus is typically reliable, maybe it could be improved by combining the two solutions: users are actively viewing the page when the window is focused and they have moved their mouse in the past 30 seconds. Luckily, composing properties in Bacon is extremely easy.
focused.combine(active, function(focus, active) { return focus && active; })

Even better, there are methods to combine properties with basic boolean operators.
focused.and(active)

The jQuery implementation is left as an exercise for the reader. DECOUPLING APPS WITH BACON There are other data sources that we could use for user activity monitoring. The Page Visibility API is a more reliable alternative for focus and blur. If this API is available in the browser, we can use an implementation based on that instead. Bacon makes it easy to switch out parts of the implementation when constructing EventStreams and Properties. Lets say that weve implemented a Bacon property from Page Visibility state as visibility.
function windowFocus() { if (document.hidden === undefined) { return visibility; else { return focused; } } function activity(focus) { var stream = $(window).asEventStream(mousemove keydown); return stream.flatMapLatest(function(event) { return Bacon.once(true).merge(Bacon.later(30000, false)); }).toProperty(true).and(focus); } activity(windowFocus());

5 of 6

TUTORIALS BACON.JS MAKES FUNCTIONAL REACTIVE PROGRAMMING SIZZLE

Decoupling the stream and application logic also makes it easier to test components that depend on the activity. You can give the state as argument to other components and dont need to write complex objects to encapsulate the state.

ON THE ROAD TO A BYPASS SURGERY At Flowdock, weve been using Bacon to handle all kinds of things: autocompleting UI components with asynchronous results, synchronising Backbone models over Socket.IO and handling keyboard shortcuts. This blog post didnt cover much of the Bacon.js API. The Bacon.js readme is the most comprehensive source of documentation. The Bacon.js wiki has also excellent visualisations of the few important methods and their implications.

Ville Lautanala
Developer at Flowdock

HIS BLOG

SHARE

TWITTER

GITHUB

appliness

TUTORIALS JAVASCRIPT

BOOKMARK / SHARE / TOC

Building a Unit Test in Jasmine, Part 1.


by David Posin

TUTORIALS BUILDING A UNIT TEST IN JASMINE, PART 1

by David Posin

Unit testing and I have had a tumultuous affair until now.

(Thanks to Dustin Butler for the inspiration that led me down this path. His great and more in-depth article is at Unit Test JavaScript Applications with Jasmine) Unit testing and I have had a tumultuous affair until now. Every few months I would pick up a book, go on a blog reading binge, or try out a framework. It would never work out. I would get frustrated or work would intervene and off I went. Unit testing and I were almost fated to always be apart... <cue the romantic music> An opportunity came at work to create a new feature on our web platform. I decided to take a chance and build it from unit tests. It was a great opportunity to start clean with very few dependencies to worry about. The lack of entanglements made it easier for me to understand how unit testing would work to describe this new piece. After some web research, I decided on Jasmine. I dont know enough about unit testing yet to speak about which platforms are best suited for what. What I do know is that Jasmine was recommended in some trustworthy sources, and I could grasp its syntax readily. My first hurdle was understanding how it worked. Beginning can be the hardest part, so I started simple....2+2=4. GETTING STARTED The first step was to create a testing space and adding the necessary Jasmine files to it. The latest zip can be downloaded at https://github.com/pivotal/jasmine/downloads. The files that are necessary to get started are: SpecRunner.html jasmine.css jasmine.js jasmine-html.js

2 of 4

TUTORIALS BUILDING A UNIT TEST IN JASMINE, PART 1

I put everything in one folder when I first started with Jasmine. Later, I created an appropriate folder structure to host my tests. There are three parts to any test: HTML - The tests are started by loading an html page that builds the Jasmine environment and executes the tests Spec - describes the tests and how they should run Source - The code being tested First, I created a new JavaScript file for my first Spec. Then, I went to add it to the Jasmine test environment on the HTML page. The HTML page will need to access the new Spec file and the Source to test. This is accomplished through simple script tags. The sample HTML file, SpecRunner.html included in the download, has 2 comment lines that call out a place to put those tags.
<!-- include source files here... --> <script src=Insert path to the code you are testing javascript></script> type=text/

<!-- include spec files here... --> <script src=Insert path to the file you will put your tests in javascript></script>

type=text/

With the reference created, I moved on to editing my Spec file. The first function is describe. Describes are headings you can use to organize multiple tests into logical groupings, or suites. For example, I might have a describe for a simple objects Attribute Tests and another for Function Tests. I used Simple Test for this example. The describe is a closure so the second parameter is a function. The it goes inside this closure. it is the specific test(s) you are going to run. it is also a function with a closure. The first parameter is what will be returned to you on a successful test. This example returns 2+2=4 on a successful test. The second parameter is the function that does the work. A lot of things can happen inside an it. Primarily, a thing is expected to have a predetermined result. This is the purpose of the expect function. The expect function captures the result of the process passed into it. The expect then matches that actual result against the expected result. If the result matches the expected result, then the test passes. If not, the test fails. The matchers I have used most often are toBe and toEqual. The test can be read as I expect the result to be or I expect the result to equal. The difference between the two is type comparison. toBe performs implicit type conversion (==), and toEqual performs
3 of 4

TUTORIALS BUILDING A UNIT TEST IN JASMINE, PART 1

no type conversion (===). It helps me understand my tests by reading them in plain language. One of the reasons I like Jasmine is how easy this is. The simple test I put together for this post can be read as: I have a simple test running to check that 2 + 2 = 4, and I expect my inline function to return a 4 when run.

Next week, we will take this and start abstracting it out.

David Posin
Scrollmotion, Inc.

HIS BLOG

SHARE

JavaScript Architect at
GOOGLE+
GITHUB

appliness

TUTORIALS JAVASCRIPT

BOOKMARK / SHARE / TOC

Bubbling in Enyo Part 2.


by David Posin

TUTORIALS BUBBLING IN ENYO, PART 2

by David Posin

Wouldnt it be great if we could use the same BubbleButton in 2 hierarchies...

We looked at a simple example in Part 1. A button component sent an event up the object hierarchy until it was captured by the App kind and resolved. Wouldnt it be great if we could use the same BubbleButton kind in 2 different hierarchies and get 2 different results? Yes it would; so lets do that. Lets start by revisiting the BubbleButton:
enyo.kind({ name: BubbleButton, kind: enyo.Button, handlers: { ontap: tapped }, tapped: function() { this.setAttribute (disabled, true); this.bubble(onUpdate); return true; } });

The BubbleButton is an extended type from the base enyo.Button type. This means that all the standard methods and functionality of a button are provided automatically when a new instance is created. This includes the instance getting create, destory, and render methods. I have removed all three explicitly from the button definition for easier reading and less code. They will be inherited when the time comes. The button is still listening for a tap event which is defined in the handlers section.
handlers: { ontap: tapped },

The tapped function will run when the button receives the ontap event. The ontap is an event we get for free from the Enyo framework. The ontap event blurs the line between mobile and desktop, and is fired by both touch screen taps and mouse clicks. One change has been made since last time. The tapped function now includes this line:
this.setAttribute (disabled, true);
2 of 7

TUTORIALS BUBBLING IN ENYO, PART 2

The BubbleButton will be assigned the html disabled attribute after being pressed. The vanilla disabled attribute is used so it will only work on browsers that support that property. I cant think of a browser that doesnt support the disabled property but it is worth mentioning. The setAttribute method tells Enyo to immediately update the UI representation of this component. A separate render call is not required. With this in place, there is a way to verify which one of two ontap functions is being executed. It will be possible to confirm which hierarchy the button is affecting. The active button will turn gray and non-interactive. The tapped function will cause the onUpdate event to start bubbling up the object hierarchy. The BubbleButton is still fairly generic to this point. This supports the reuse model that is so integral to Enyo. The BubbleButton can be placed into any app with no effort, and provides a simple set of localized functionalty. The example includes two new kinds: BubbleDiv and BubbleParagraph. The BubbleDiv looks like:
enyo.kind({ name: BubbleDiv, kind: enyo.Control, tag: div, handlers: { onUpdate: updateDiv }, components: [{ tag: p, name: divParagraph, content: Blank Div }, { kind: BubbleButton, content: Press Me in this Div }], updateDiv: function () { this.$.divParagraph.content = Not A Blank Div Anymore; this.render(); return true; } });

3 of 7

TUTORIALS BUBBLING IN ENYO, PART 2

The BubbleDiv explicitly identifies its tag as a div. This tells Enyo to render the component as an html div. A div is the default tag for any component without a tag explictly set to something else. This makes setting the tag redundant but is done to provide a visual differential for us to read the 2 new kinds together. There are two components contained within this div object. The first component is a simple paragraph:
{ tag: p, name: divParagraph, content: Blank Div

Giving the component a tag attribute will set the html tag, just like the div tag in the BubbleDiv. The name attribute gives us a way to reference the paragraph in code. The name is not the rendered id. The id attribute can be set explicitly but I find that is not a good idea. Enyo ends up needing the id to do its own magic. The reference via its name is maintained in the Enyo framework so we rarely need to worry about the actual id. Finally, the content is what is put into the paragraph. The paragrapgh will render like this:
<p id=app_bubbleDiv_divParagraph>Blank Div</p>

The second component is our BubbleButton component. The button inherits the properties of the regular enyo.button which includes automatic handling of the content property. Setting content in this case is what will appear on the button.
{ } kind: BubbleButton, content: Press Me in this Div

The most important part of the BubbleDiv for our purposes is the handler function:
handlers: { onUpdate: updateDiv }, updateDiv: function () { this.$.divParagraph.content = Not A Blank Div Anymore; this.render(); return true; }

4 of 7

TUTORIALS BUBBLING IN ENYO, PART 2

The BubbleButton will bubble up the onUpdate event. Since the BubbleDiv contains a BubbleButton it can choose to capture that event. This is accomplished by adding a handler for onUpdate to our BubbleDiv. When an event is captured, the onUpdate handler tells Enyo to call the updateDiv function. The updateDiv function is going to change the contents of the paragraph inside the div. The function is going to get the paragraph by using the this.$ shorthand. The shorthand allows access to the current components contents, including other components. It is possible to retrieve a component from inside another component if you know its name. In this case, we are looking for divParagraph which is the name we gave the paragraph inside of the BubbleDiv. Using dot notation we grab the divParagraph component inside this component and change its content (this.$.divParagraph.content). Since this modifies the contents of an html property, we will need to re-render this component. The BubbleDiv is re-rendered and the onUpdate event is stopped by returning true. The BubbleParagraph is very similar to our BubbleDiv:
enyo.kind({ name: BubbleParagraph, kind: enyo.Control, handlers: { onUpdate: updateParagraph }, components: [{ tag: p, name: paragraph, content: Blank Paragraph }, { kind: BubbleButton, content: Press Me in this Paragraph }], updateParagraph: function () { this.$.paragraph.content = Not A Blank Paragraph Anymore; this.render(); return true; } });

The crucial difference between the two kinds is in the updateParagraph function. The updateParagraph looks for a different component, and changes the content to something different than the BubbleDiv. Pushing the button in the BubbleParagraph changes the content to Not a Blank Paragraph Anymore. The most important
5 of 7

TUTORIALS BUBBLING IN ENYO, PART 2

feature of both is the BubbleButton. Both kinds use the same BubbbleButton kind. Despite this simularity, the result of pushing the button is different. Use the jsFiddle below to try it out. In summary, two different kinds with two different behaviors using the same button. The power of Enyos object and bubbling system have allowed the creation of a new reusable component in a few lines of code. The BubbleButton has been written once and used twice. An Enyo kind definition is very narrative in structure which makes it easy to maintain and understand. An Enyo kind can exist as a targeted event emitter with the bubble functionality. The simple way that a small definition can unlock so much potential is one of my favorite features of the Enyo2 framework.

6 of 7

TUTORIALS BUBBLING IN ENYO, PART 2

In Part 3, the example will be expanded to allow the onUpdate event to continue past the direct parent to be handled elsewhere.

David Posin
Scrollmotion, Inc.

HIS BLOG

SHARE

JavaScript Architect at
GOOGLE+
GITHUB

appliness

TUTORIALS JAVASCRIPT

BOOKMARK / SHARE / TOC

The future of JavaScript: a CoffeeScript-like workflow


by Dr. Axel Rauschmayer

TUTORIALS THE FUTURE OF JAVASCRIPT

by Dr. Axel Rauschmayer


ECMAScript

There are good times ahead for JavaScript.

ECMAScript 6 will bring many new features to the language. However, it will be years before we can rely on it being supported in most browsers that are in use. This post examines tools that will allow us to program with ECMAScript 6 much sooner. EVOLVING A WEB PROGRAMMING JavaScript is a web programming language. You will thus always encounter a wide variety of language versions: Applications are written in many different ECMAScript versions. Even a single application is likely to be a mix of several versions, considering that it often includes libraries and external code (e.g. for analytics). Many different browser versions are in use, even quite old ones. In every browser, there is exactly one version of ECMAScript available. Users have little control over which version it is, because browsers often update themselves automatically (making new versions forced upgrades). This imposes constraints on what can be done with ECMAScript 6: First, this version cannot introduce any changes that would break existing code. Second, app developers will have to wait years until they can use it when it is supported by most browsers. It is interesting to compare that with how things work with traditional programming languages: You have much more control. End users decide when to upgrade engine and app versions. As an app developer, you can usually demand that a reasonably recent version of a language be installed and can target that version. Breaking changes to a language can be introduced by letting users install two versions in parallel (which is what Python did with version 3). WHY NOT VERSIONING? One possible solution is to simply annotate each piece of code with a language version. That would allow new versions to introduce breaking changes, because those wont affect the old code. However, there are two problems with this approach: First, its a
2 of 7

TUTORIALS THE FUTURE OF JAVASCRIPT

usability problem who wants to start each code fragment with a version number? For ECMAScript 5 strict mode, you have to do that and it hampered its adoption rate. Second, its a maintenance problem you have to maintain several language versions in parallel inside a single engine. That would make browsers even more bloated. Lastly, we still havent solved the issue of app developers not being able to use ECMAScript 6 right away. For the remainder of this post, we will focus on this issue and ignore the issues that engines are faced with. SOLUTION FOR APP DEVELOPERS: A COFFEESCRIPT-LIKE WORKFLOW If we want to use ECMAScript 6 as app developers, but still want to run our software on old browsers, we only have one option: compile ECMAScript 6 to ECMAScript 3 (possibly ECMAScript 5 in 12 years). The precedent is obvious: CoffeeScript has been doing this since December 2010. With source maps, you can even debug its code in the browser the JavaScript it has been compiled to is hidden from you. Several ECMAScript 6 features have been influenced by CoffeeScript (arrow functions, classes). Then why not use CoffeeScript and be done with it? There are several reasons: - Different syntax: when CoffeeScript was created, giving it a different syntax made sense, because it wasnt JavaScript and pretending so would have clashed with future versions of that language. However, now that CoffeeScripts most important fixes are available in ECMAScript 6, we can go native again. This point is obviously controversial people who like CoffeeScript often do so because of its different syntax, not despite it. I, however, agree with Nicholas Zakas assertion: There is a very real problem in the web development industry and that problem is a significant lack of good JavaScript developers. [...] [I] want the web as a whole to continue to grow and get better, and that only happens when we have more competent developers entering the workforce. I see compile-to-JavaScript languages as a barrier to that goal. We should be convincing more people to learn JavaScript rather than giving them more options to not write JavaScript. I often wonder what would happen if all of the teams and companies who spent time, energy, personnel, and money to develop these alternatives instead used those resources on improving JavaScript and teaching it.

3 of 7

TUTORIALS THE FUTURE OF JAVASCRIPT

- No compilation during development: Soon, youll be able to use an ECMAScript 6 capable browser during development and wont have to compile. Its a small thing, but still less complexity to worry about. - New features: ECMAScript 6 can do things that CoffeeScript cant. Two examples: modules and generators. COMPILING ECMASCRIPT 6 TO ECMASCRIPT 3 There are already several solutions for compiling ECMAScript 6 to ECMAScript 3 (or ECMAScript 5): Traceur: compiles ECMAScript 6 to ECMAScript 3, on the fly. You can thus already play with ECMAScript 6 now. Dynamic compilation is an interesting alternative to compiling before deployment. Possible problems are performance and debugging. Harmonizr: statically compiles to ECMAScript 3. It supports ECMAScript 6 features such as modules, arrow functions and classes. TypeScript: statically compiles to ECMAScript 3 and has several advanced features, some of them borrowed from ECMAScript 6 (classes, modules). Interestingly, feedback from TypeScript now helps with evolving ECMAScript. Issues encountered here let us discover potential problems with ECMAScript 6 before it exists. Note that TypeScript is not always completely compatible with ECMAScript 6 (especially w.r.t. how it handles private properties). Esprima: Ariya Hidayat has written articles on how to use his ECMAScript parser Esprima to compile ECMAScript 6 modules and classes to earlier ECMAScript versions. COMPILING LET DECLARATIONS Possibly the most difficult thing for compilers will be how to translate the blockscoped let variable declarations to the function-scoped var declarations. For example, the following code can remain largely unchanged, if tmp isnt used outside the then-block.
// ECMAScript 6 function foo(x, y) { if (x === 1) {
4 of 7

TUTORIALS THE FUTURE OF JAVASCRIPT

let tmp = x + 1; ...

This compiles to:


// ECMAScript 3 function foo(x, y) { if (x === 1) { var tmp = x + 1; ... } }

However, if tmp is used elsewhere then things are more complicated:


// ECMAScript 6 function foo(x, y) { if (x === 1) { let tmp = x + 1; ... } if (y === 1) { let tmp = y + 1; ... } }

Then you have the option to rename tmp:


// ECMAScript 3 function foo(x, y) { if (x === 1) { var tmp_1 = x + 1; ... } if (y === 1) { var tmp_2 = y + 1; ... } }

Or you can insert IIFEs:

5 of 7

TUTORIALS THE FUTURE OF JAVASCRIPT

// ECMAScript 3 function foo(x, y) { if (x === 1) (function () { var tmp = x + 1; ... }()); if (y === 1) (function () { var tmp = y + 1; ... }()); }

THE STANDARD LIBRARY ECMAScript 6 will also have several useful additions to the standard library. For example: a map data structure (with arbitrary keys, as opposed to the string-only keys of objects) and additional string methods (startsWith(), endsWith(), repeat() etc.). Most of them can be shimmed on ECMAScript 5 an earlier via a library. ECMAScript 6 compilers will probably provide this functionality in the same manner. USING NEW LANGUAGE FEATURES DIRECTLY But when do we get to use ECMAScript 6 natively? I see three options: 1. Wait until ECMAScript 6 is the dominant version, switch to it completely. That will take a while. 2. Dynamically feature-detect what a browser supports and shim less functionality. 3. Determine what ECMAScript version a browser supports before delivering JavaScript source files from the server. If it supports ECMAScript 6, deliver the original source code. If it doesnt, deliver the compiled source code. As far as I can tell, implementing (3) is currently difficult. Maybe there should be better support for it in browsers (by sending the supported ECMAScript version to the server?). CONCLUSION There are good times ahead for JavaScript. ECMAScript 6 will introduce many great features, compilation will ensure that well actually be able to program with
6 of 7

TUTORIALS THE FUTURE OF JAVASCRIPT

them. If you want to find out what ECMAScript 6 can do, take a look at the guide to posts about ECMAScript.next (ECMAScript 6s code name) on 2ality.

Dr. Axel Rauschmayer


Consultant for JavaScript

HIS BLOG

SHARE

TWITTER

GITHUB

appliness

TUTORIALS JAVASCRIPT

BOOKMARK / SHARE / TOC

My Workflow for Developing PhoneGap Applications.


by Andrew Trice

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

by Andrew Trice
GETTING STARTED

Ill try to shed some light on the workflow and tools that I use when developing PhoneGap applications.

I am asked all the time How do I get started developing PhoneGap applications?. My normal answer is to advise people to check out the PhoneGap Getting Started Guides, which provide a great starting point for every platform. However after further thought, Im not sure this is always what people are asking. Rather than how do I get started?, I think people are often looking for insight into the workflow for developing PhoneGap applications. Everything from tools to developer flow, to getting the app on devices. The Getting Started Guides are essential for setting up the initial project structure, but once you get that setup, you might be wondering what do I do next?. In this post, Ill try to shed some light on the workflow and tools that I use when developing PhoneGap applications. KNOW WHAT YOURE GOING TO BUILD BEFORE YOU BUILD IT First and foremost it is essential to have at least some kind of idea what you are going to build before you build it. If you just start hacking things together without a plan, the final result is seldomly great. Complete (pixel perfect) UI/UX mockups are fantastic, but you dont have to have a fully polished design and screen flow. Just having wireframes/sketches are a great start. Heck, even a sketch on a napkin is better than starting with nothing. The UX design/wireframes help you understand what you application should be doing from the users perspective, which in turn helps you make decisions on how you tackle a project. This can be purely from a HTML level, helping you figure out how you should position DOM elements and/or content. Or, it can help you gauge your projects technical complexity How many moving parts do you have, how much of the app is dynamic or asynchronus, or how do different visual elements need to work together? You can leverage this design/mockup to analyze the needs of your application and determine if a particular framework/development methodology is a best fit (Bootstrap, Backbone. js, Knockout.js, Sencha, jQuery Mobile, Angular.js, etc). When working with a designer, I use Adobes Creative Suite Tools for pretty much everything wireframes, UI/UX designs, chopping up assets, etc Im currently working on a project that was designed by the talented Joni from Adobe XD. Joni designed
2 of 16

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

everything in Creative Suite, and Im using Photoshop to view screen flows and extract UI assets for the actual implementation.

UI Mockups in Photoshop

3 of 16

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

Screen Flow in Photoshop Note: This app will also be free and open source as a sample/learning resource for PhoneGap, including all of the design assets Ill follow up with another post on this later, once the app is available in the app stores. If you arent a graphics person, or dont have creative suite, there are a bunch of other tools that you can use for wireframing and/or sketching (but cmon, Creative Cloud is only $50 a month). Here are several Ive used with great success, but this is not a comprehensive list at all: OmniGraffle - A drag & drop wireframing tool for OS X. This is fantastic for wireframing or documenting screen flows. In fact, the screen flow image shown in Photoshop above was originally composed in Omnigraffle, using the mockups created in Photoshop. Visio - A powerful drag & drop wireframing/design tool for Windows much like OmniGraffle, but for windows. PowerPoint or Keynote - These arent just for presentations. They can be really useful for putting together screen flow diagrams, or annotating images/content.
4 of 16

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

Often people like to sketch out ideas & wireframes on their tablets, here are a few tools that I use for that: Adobe Touch Apps Adobe Ideas can be great for digitally sketching ideas. iBrainstorm A great app for collaboratively taking notes and sketching. Im partial to this one b/c used to be on the dev team, and I wrote a good chunk of the graphics sketching logic. There are a bunch of other tablet sketching apps out there, but I havent used most of them. CODING ENVIRONMENT Coding environments are a tricky subject. There is no single solution that meets the exact wants and needs for everyone. Some people chose lightweight text editors, some people chose large-scale IDEs, some people use designer-centric tools, and many of these choices are dependant upon which operating system you use or your background as a designer or developer. Since PhoneGap applications are really just editing HTML, CSS & JavaScript, you can use whatever editor you want. In fact, I know a several people that use vim as their primary editor. LARGE-SCALE IDES Im a bigger fan of of using a complete IDE (integrated development environment) than I am of a lightweight editor, simply b/c IDEs tend to have hooks into more features/languages, etc I know people complain about startup time, but there is no startup time if you leave it open all the time. There are a few catches when talking about IDEs with PhoneGap. The first is that if you want to deploy anything locally to devices (without using PhoneGap Build), you have to delpoy using the IDE for the particular platform that you are targeting. That means Xcode for iOS, Eclipse for Android, or Visual Studio for Windows Phone, etc However if you wish, you can use your editor of choice, and just use the IDE to deploy to devices locally. You can even share source code across several IDE installations using symlinks (which I describe here). I very often use this type of a configuration to share code between Xcode, Eclipse, and WebStorm. My preference for coding PhoneGap applications is to use WebStorm by JetBrains. WebStorm has great code-hinting (even for your own custom JS and 3rd party
5 of 16

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

libraries), great refactoring, hooks into Git, CVS, or SVN repositories, and is a very mature IDE.

WebStorm IDE I tend to use this as my primary coding tool, then switch to Eclipse or Xcode when I want to locally deploy to a device for testing. When using PhoneGap Build to simplify cross-platform compilation, I just push the code to git, then recompile via PhoneGap Build. Im not a fan of Xcodes HTML/JS editing, and havent found an HTML/JS plugin for Eclipse that I really like. To target Windows devices, I use Visual Studio. LIGHTWEIGHT EDITORS Im a bigger fan of larger IDEs than lightweight editors, but Adobe Edge Code (also known as Brackets) is a great lightweight editor for quick edits. Edge Code/ Brackets is an open source HTML/JS editor that supports live editing in the browser and inline editors for CSS styles, without leaving your HTML files. If you tried Edge
6 of 16

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

Code Preview 1, but werent sold on it, you should try Edge Code Preview 2. The team has come a long way very quickly. Its fast, easy to use, and there is a plugin to tie it into PhoneGap Build. I sometimes use this for quick edits.

Adobe Edge Code Edge Code/Brackets also has a thriving open source project, and encourages you to get involved and help contribute. There are tons of other lightweight editors out there, and everyone has their favorite. As long as youre happy with the tool, and it can edit text (HTML, CSS, JS) files, you can use it to build PhoneGap applications.

7 of 16

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

DESIGNER-FRIENDLY EDITORS Im not necessarily the primary target for Dreamweaver, but it has some nice features. Dreamweaver gives you a great programming environment plus a WYSIWYG editor for HTML experiences. It also features PhoneGap Build integration directly inside the coding environment. If youre used to Dreamweaver for creating web experiences, you can continue to use it and target mobile apps as well.

Adobe Dreamweaver

DEBUGGING ENVIRONMENTS Yes, that is plural Debugging Environments. Due to the cross-platform nature and PhoneGaps leveraging of native web views for each platform, debugging PhoneGap applications can sometimes be tricky. Here are some tips that will make this significantly easier.
8 of 16

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

THE PHONEGAP EMULATOR The PhoneGap Emulator is my primary development/debugging tool for all PhoneGap apps. It is a browser-based emulator leveraging the Google Chrome browser and the Ripple Emulation Environment. The PhoneGap Emulator runs inside of Google Chrome, and provides emulation of PhoneGaps core APIs. Since it is built on top of Chrome, it enables you to leverage Chromes Developer Tools, which in my opinion are second to none for web/application development. This is a highly-productive developer environment.

PhoneGap Emulator in Google Chrome Heres why I like the PhoneGap/Ripple/Google Chrome development environment: First, this combination enables you to emulate most core PhoneGap APIs without leaving the desktop environment. It enables you to test various APIs including geolocation (with simulated locations), device events (deviceready, back, etc), sensor events (accelerometer, compass), and even lets you test with different
9 of 16

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

device aspect ratios all without having to push anything to an actual device. This saves a lot of time in development iterations. You can read about the supported Ripple emulator features here. Second, Chromes Developer Tools are awesome. Here are just a few things that you can do while developing/debugging your app, live within the emulation environment: 1. Alter DOM and CSS at runtime via the elements panel. 2. Analyze all resources consumed by your app, via the resources panel. This includes all scripts, images, html files, cookies, etc it even includes insight into any local data stored via PhoneGaps local storage database (WebSQL implementation). 3. View/query all local databases within your app. You can write your own queries to view/alter data in the WebSQL database. Thanks to Ray for sharing this, its not immediately intuitive.

Debugging Local Storage Databases in Chrome with SQL 4. Analyze network requests/utilization via the network panel. 5. Debug JavaScript with the Scripts/Sources Panel. You can set breakpoints in JS execution, inspect & alter values in JS objects in-memory, and view details and line numbers for any exceptions that occur. 6. Monitor function execution time, memory consumption, event listeners, and frame rendering time via the timeline panel.

10 of 16

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

Chrome Timeline Panel 7. Profile CPU/Memory usage via the profiles panel. 8. Use the console to monitor console.log() statements, inspect properties of objects in memory, or execute arbitrary JavaScript whenever you want. The PhoneGap Emulator enables developers to be extremely productive with development, however I cannot emphasize enough that on-device testing is critical for having a successful app. On-device testing can expose performance problems or browser rendering variances that you may not notice in the emulator environment. ON-DEVICE REMOTE DEBUGGING As I mentioned above, on-device testing is critical for successful applications. iOS and BlackBerry have an advantage over other platforms b/c the latest developer tools allow you to remotely debug content live on a device. Since the release of iOS 6, you can debug content in the iOS simulator using Safaris Developer Tools. Safaris developer tools give you many of the same debugging capabilities that I mentioned above for Chrome.

11 of 16

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

To debug an app running in the iOS simulator, just go to Safaris Develop menu, select iPhone Simulator, then select your apps index.html file.

Connect Remote Debugging Youll end up with a full remote debugging experience, just like if you were debugging inside the Safari browser, complete with JS breakpoints, DOM inspection, etc

Remote Debug iOS Simulator with Safari

12 of 16

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

The process to remotely connect to a live app running on an external iOS device is very similar. Just follow the instructions here, under the Remote Debugging section, and you will be up and running very quickly. The latest BlackBerry devices also have the same remote debugging capability (since it is all actually based on the webkit engine). You can view detailed instructions how to remotely debug PhoneGap apps on BlackBerry devices here. REMOTE DEBUGGING WITH WEINRE Not every platform supports live remote debugging, especially older versions. Weinre (pronounced winery) is a remote web inspector that allows you to inspect/ edit DOM and CSS elements on remote devices. Basically, you include some JavaScript in your app, and it communicates back to a server that will tell you whats happening inside of the app running on the mobile device. It wont give you full debugging capabilities like JS breakpoints and memory inspection, but its better than nothing. You can use Weinre by setting up your own instance, or by leveraging debug.phonegap.com.

Weinre for On-Device Debugging

13 of 16

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

WHEN ALL ELSE FAILS If youre still debugging your apps, and the solutions mentioned above dont work, you can always resort to plain-old alert() statements to pop up debug messages, or use console.log() statements to write to system logs. On Android, all console.log(...); messages will appear as printouts in the commandline tool logcat, which is bundled with the Android SDK and integrated into the Android Eclipse plugin. On BlackBerry, all console.log(...); are printed to the BlackBerrys Event Log. The Event Log can be accessed by pressing ALT + LGLG. On iOS, all console.log(...); are output to the Xcode Debug Area console. Read more about debugging PhoneGap apps here.

BUILDING PHONEGAP APPS The PhoneGap getting started guides will point you to the right direction for getting started with a particular platform. If you are just targeting iOS, you can use Xcode for building. If you are just targeting Android, you can use Eclipse, etc It is all very easy to get up and running. However, this process gets much more complicated when targeting multiple platforms at once. When I have to do this, PhoneGap Build becomes really, really handy.

14 of 16

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

PhoneGap Build allows you to either upload your code, or point to a Git repository. PhoneGap Build will then pull your code and build for 7 different platforms, without you having to do anything special or setup multiple environments. All that youll have to do is install the cloud-compiled binaries on your device. You can do this by copying/pasting a URL to the binaries, or by capturing a QR code that will directly link to the compiled application binary. One other advantage of PhoneGap build is that it lets designers/developers build mobile applications without having to install any developer tools. If you want to compile a PhoneGap app for iOS, but are on Windows just use PhoneGap build and you wont need Xcode or a Mac. Check out the PhoneGap Build FAQ for more detail about how exactly it works. PHONEGAP UI/DEVELOPMENT FRAMEWORKS Probably the most common PhoneGap question that I get asked is what MVC/ development framework should I use?. If youve been waiting for me to answer this, dont hold your breath. It is impossible to be prescriptive and say that one solution fits all use cases for every developer. When people ask me this, I like to paraphrase Brian Leroux from the PhoneGap team: Use HTML, it works really well. I think people often overlook the fact that PhoneGaps UI renderer is a system web view. Anything that is valid HTML/CSS content can be rendered as your applications user interface. This could be something incredibly simple, like text on the screen, or it could be incredibly creative or complex. The important factor is that you need to focus on a quality user experience. If youre worried about your UX, and are worried that Apple may reject your app, then read this article where I explain Apple rejections in detail. HTML/JS developers come from many different backgrounds, with varying degrees of programming expertise. Some frameworks appeal to some people, other frameworks appeal to other people. There also seem to be new UI & architectural frameworks popping up every week. It would be a disservice to all people who use PhoneGap for us to proclaim that we should only use one singe framework.

15 of 16

TUTORIALS MY WORKFLOW FOR DEVELOPING PHONEGAP APPLICATIONS

If you are interested in UI frameworks, take a look at these: Twitter Bootstrap Zurb Foundation Sencha Touch Kendo UI jQuery Mobile Enjyo.js app-UI Moobile Chocolate Chip UI Dojo Mobile If you are interested in architectural patterns, take a look at these. Backbone.js Knockout.js Angular.js Ember.js Ext.js There are lots, and lots, and lots more options out in the HTML/JS development world Im not even taking into account JavaScript generating tools and languages like CoffeeScript, TypeScript, or others Hopefully this helps get you on the right track. Enjoy!

Andrew Trice
at Adobe

HIS BLOG

SHARE

Technical Evangelist
TWITTER GITHUB

appliness

TUTORIALS JAVASCRIPT

BOOKMARK / SHARE / TOC

Android Push Notifications with PhoneGap.


by Holly Schinsky

TUTORIALS ANDROID PUSH NOTIFICATIONS WITH PHONEGAP

by Holly Schinsky

I was able to get my notifications working much faster on Android...

My last post covered push notifications with PhoneGap on Apple devices, but I also wanted to cover push notifications with PhoneGap on Android for those developing cross platform applications. I found that I was able to get my notifications working much faster on Android comparatively. GOOGLE CLOUD MESSAGING Android push notifications are available via the Google Cloud Messaging GCM service (similar to Apples Push Notification Service). Previously they were supported through C2DM (Cloud to Device Messaging framework) but that API has since been deprecated and the Google Cloud Messaging services adds enhancements above and beyond what C2DM offered. Theres a Cordova/PhoneGap plugin available to aid in working with the Google Cloud Messaging service. The message size allotment for the GCM payload is 4kb (String data only), noticeably bigger than the Apple Push Notification requirements of 256 bytes. Theres an article about the types of messages that can be sent in detail here. Also, I suggest you look over the documentation for using this service in general here when building your application, there are a lot of details I will not cover in this post. Some points I wanted to highlight from that article are: GCM makes no guarantees about delivery or the order of messages. An Android application on an Android device doesnt need to be running to receive messages. The system will wake up the Android application via Intent broadcast when the message arrives, as long as the application is set up with the proper broadcast receiver and permissions. It does not provide any built-in user interface or other handling for message data. GCM simply passes raw message data received straight to the Android application, which has full control of how to handle it. For example, the application might post a notification, display a custom user interface, or silently sync data.
2 of 12

TUTORIALS ANDROID PUSH NOTIFICATIONS WITH PHONEGAP

STEPS The steps for setting up push notifications in your Android application are: 1. Create a new Android Cordova project either via the command line tools or Eclipse (command line recommended) 2. Download the GCM Cordova Plugin 3. Follow the steps in the plugins Readme Dont forget to setup your Google Cloud Messaging Account as noted in the readme and note your project id located in the URL. For instance the number in bold below is the id you need to send in the register() function: https://code.google.com/apis/console/?pli=1#project:824841663942 Dont forget to change the following to use your GCM project id (from the step above)
window.GCM.register(your_sender_id, GCM_Event, GCM_Success, GCM_Fail );

becomes
window.GCM.register(824841663942, GCM_Event, GCM_Success, GCM_Fail );

Add code handling for the actions to take when the application receives a message while open or not (ie: display a popup alert, status bar notification etc). Note: The plugin handles registering with GCM and has methods for receiving a message, however it does not actually provide the notification code itself, this is something you need to add. Read on further for how to add native code to produce a status bar notification. If you need more information about GCM project creation, specific steps can be found here. The plugin includes a sample project already setup to register for push notifications (includes the AndroidManifest.xml changes and plugin configuration already), all you have to do is edit the CORDOVA_GCM_script.js file to use your GCM sender/project id in the register function and you can run it immediately or use this project as a reference while making the changes to your own.

3 of 12

TUTORIALS ANDROID PUSH NOTIFICATIONS WITH PHONEGAP

If you prefer to use Eclipse for your editing, you can simply import your existing Android project that you just created above (or the sample included in the plugin) and start working from there. Choose File | New | Project, then you will see the following dialog, where you will select Android Project from Existing Code as follows:

4 of 12

TUTORIALS ANDROID PUSH NOTIFICATIONS WITH PHONEGAP

RUNNING THE SAMPLE APPLICATION When you run the sample code from the plugin, it will automatically try to register your device. If registration is successful, you should see a message containing the registration token id as I circled below in the screenshot of mine running on my Galaxy Tablet:

You should also see the following trace in your console:


10-24 18:24:20.720: V/GCMReceiver:onRegistered(21989): Registration ID arrived! 10-24 18:24:20.730: V/GCMReceiver:onRegisterd(21989): {regid:APA91bFobAwM7P3 Okxy2al8RI12VcJFUS-giXWTOoWXIObtSPOE1h7FuH1VPLBPgshDI_Fp7aIYVET-ssvGUErlWYA0cKP GhoXT1daqyDsEfem9ZtgZNRhQFv7kLCIVSigYlpMluToPiSHSsFSEdtCDfKoOZqNPsfg,event: registered} 10-24 18:24:20.730: V/GCMPlugin:sendJavascript(21989): javascript:GCM_Event({ regid:APA91bFobAwM7P3Okxy2al8RI12VcJFUS-giXWTOoWXIObtSPOE1h7FuH1VPLBPgshDI_ Fp7aIYVET-ssvGUErlWYA0cKPGhoXT1daqyDsEfem9ZtgZNRhQFv7kLCIVSigYlpMluToPiSHSsFSEd tCDfKoOZqNPsfg,event:registered})

5 of 12

TUTORIALS ANDROID PUSH NOTIFICATIONS WITH PHONEGAP

Once you have obtained a registration id as above, you can write server code (see the section below on using Node.JS code to send a message to your application) or use a service like Urban Airship or PushWoosh to start sending notifications. When a message is received, you will see additional text displayed as shown in the screenshot below:

At this point though, the plugin does not contain anything more to actually show a status bar notification or otherwise notify you. The next section covers how you can add some additional code to it for showing a status bar notification when the message is received.

6 of 12

TUTORIALS ANDROID PUSH NOTIFICATIONS WITH PHONEGAP

STATUS BAR NOTIFICATION Since the plugin simply receives the message (whether running or not) but doesnt do anything with it from there, you have various choices for what you could do with it. One common thing is to show a message in the native status bar. Note that on iOS the process is different and the notification is automatically shown, but on Android you have to explicitly code for it. You could use the Cordova StatusBarNotification plugin along with this one, or if you want a faster solution, you could simply add the following native Java code into your GCMIntentService.java onMessage() function:
String message = extras.getString(message); String title = extras.getString(title); Notification notif = new Notification(android.R.drawable.btn_star_big_on, message, System.currentTimeMillis() ); notif.flags = Notification.FLAG_AUTO_CANCEL; notif.defaults |= Notification.DEFAULT_SOUND; notif.defaults |= Notification.DEFAULT_VIBRATE; Intent notificationIntent = new Intent(context, TestSampleApp.class); notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0); notif.setLatestEventInfo(context, title, message, contentIntent); String ns = Context.NOTIFICATION_SERVICE; NotificationManager mNotificationManager = (NotificationManager) context. getSystemService(ns); mNotificationManager.notify(1, notif);

Also, dont forget to add these imports at the top of the file to support the above code:
import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent;

Be sure to replace YourActivityClassName.class with the name of your stub class that extends DroidGap. For instance, in the sample project it is called MainActivity.

7 of 12

TUTORIALS ANDROID PUSH NOTIFICATIONS WITH PHONEGAP

The above code sets the notification to include a star icon, vibration and the default sound. An example of it running on my Android Galaxy Tablet is shown below (circled in red).

When you click on the notification, the app will open and look like the following, showing that a message was in fact received:

Status bar notifications will be displayed differently depending on the type of device. Some Android devices will show them at the top versus at the bottom as shown in my screenshots
8 of 12

TUTORIALS ANDROID PUSH NOTIFICATIONS WITH PHONEGAP

SENDING A MESSAGE WITH NODE-GCM Theres a Node.js library for sending notifications through Google Cloud Messaging as there was for Apples Push Notification Service as I showed in my last post. Its called node-gcm, and below is the code I used to send my device a message (keys changed ). In the Sender parameter you need to specify the API key that Google gave you when you registered for the Google Cloud Messaging service. You received two API keys, a browser and server key, either should work here, but if one does not, try the other ! You also need to specify the token returned to your application when you registered using the plugin above. This is the registration id that was printed to the screen and console when you ran the application and called the GCM register function.
var gcm = require(node-gcm); var message = new gcm.Message(); var sender = new gcm.Sender(AIzaSyCDx8v9R0fMsAsjoAffF-P3FCFWXlvwKgL); var registrationIds = []; message.addData(title,My Game); message.addData(message,Your turn!!!!); message.addData(msgcnt,1); message.collapseKey = demo; message.delayWhileIdle = true; message.timeToLive = 3; // At least one token is required - each app will register a different token registrationIds.push(APA91bFobAwN7P3Okxy2al8RI12VcJFUS-giXWTOoWXIObtSPOE1h7FuH 1VPLBPgshDI_Fp7aIYVET-ssvGUErlWYA0cKPGhoXT1daqyDsEfem9ZtgZNRhQFv7kLCIVSigYlpMlu ToPiSHSsFSEdtCDfKoOZqNPgfs); /** * Parameters: message-literal, registrationIds-array, No. of retries, callback-function */ sender.send(message, registrationIds, 4, function (result) { console.log(result); }); /** Use the following line if you want to send the message without retries sender.sendNoRetry(message, registrationIds, function (result) { console. log(result); }); **/

You need to set the name of the title and message keys explicitly to title and message as the application plugin code is looking for that in GCMIntentService.java:
9 of 12

TUTORIALS ANDROID PUSH NOTIFICATIONS WITH PHONEGAP

Bundle extras = intent.getExtras(); if (extras != null) { try { String title = extras.getString(title); String message = extras.getString(message); .... } }

COLLAPSE KEY According to the Android developer documentation, when you define a collapse key, it will only deliver the last one with a given collapse key, therefore saving the user from becoming over-notified such as in the case of sports scores for example.

10 of 12

TUTORIALS ANDROID PUSH NOTIFICATIONS WITH PHONEGAP

Also, note that these status bar notifications will be shown in the expanded list (if not dismissed yet) such as in the following:

11 of 12

TUTORIALS ANDROID PUSH NOTIFICATIONS WITH PHONEGAP

OTHER PLUGIN OPTIONS Lastly, I wanted to point out that if you are googling about Cordova push notification plugins for Android, you may also come across another one here. This one is supposed to be more specific to using notifications from PushWoosh, which I will cover in a future post with a sample. The plugin API more closely resembles the iOS Cordova PushNotification plugin, and interestingly enough still worked in receiving push notifications from my Node.js service completely outside of the PushWoosh service when I tested it (and I did not have to add the native Java code shown above to show the status bar notification) so I wanted people to be aware of it in case they wanted to try this plugin as well.

Holly Schinsky
Developer Evangelist

HER BLOG

SHARE

TWITTER

GITHUB

appliness

INTERVIEW MIKO HEVERY

BOOKMARK / SHARE / TOC

appliness

INTERVIEW DENISE JACOBS

BOOKMARK / SHARE / TOC

INTERVIEW

MIKO HEVERY

isko Hevery started coding at 8 after his father bought the first computer in their tiny village in Slovakia. From his early days of BASIC programming to making computer chips before moving on to building web applications, Misko has developed a passion for making developers productive. His path eventually lead him to create AngularJS, the current success of which seems to be the result of a bet. Is Angular destined to become HTML6? Time will tell

by Maile Valentine

photos by LucieXYZ Photography

INTERVIEW MIKO HEVERY

ABOUT YOU

APPLINESS: Hello Misko! Thank you very much for your time, we are honored to have you featured in Appliness. Can you tell us a bit about yourself? Miko Hevery: Thanks for having me! I work for Google and my passion is make developers productive. I want to help build the next awesome apps, not necessarily directly, but indirectly by elevating the software development discipline. For many years I have focused both internally in Google as well as in Open Source community in sharing my passion for writing better software through testing. About three years ago, I have become passionate about making it easy to build large scale interactive AJAX style applications on the web. I am a firm believer, that unless the easy stuff is easy, the complex stuff is impossible. Before Google, I have worked in Adobe, Sun, and even Intel. I say even Intel, since Intel builds chips not webapplications, and I am a hardware engineer by training, which has switched to software and then to webapplications.

When did you start coding? What peaked your interest in development? It all started when my dad in 1984 read in the magazine about personal computers and he had to get one. But back then we lived in a tiny village in Slovakia, and we must have been the first family to own a personal computer in the county, if not the first. I became enamored with programming, starting with BASIC as my first programming language at the age of eight, and I have not stopped coding since.

3 of 14

INTERVIEW MIKO HEVERY

MIKO HEVERY
ABOUT ANGULAR
Can you tell us a bit about Angular and how you came to develop it, its history? Every web-application is really just once complex marshaling problem. We marshal data from the DB, through the HTTP into the heap and to the DOM for the user to read, and then we do it all again in reverse order. At first this is fun, but after you build few applications, you very quickly get tired of marshaling your data through these layers, and I wanted to do something about it. Specifically, I wanted to make webapps so easy that anyone could do it.
4 of 14

INTERVIEW MIKO HEVERY

ABOUT ANGULAR

I set my eye on web-designers, and I wondered if I could bring the DB to the HTML, such that any static web-server serving your local mom and pop pizza shop could throw in some HTML sugar and have a web-site which could send email, persist form data, all without having to maintain or understand any backend technologies. The result was a service which provided a library which then allowed the web-designer to turn any static page into a dynamic one. The turning point came when I was working on internal Google project. After 6 months of building a GWT application with three engineers, we were getting frustrated with the lack of good feature velocity. I bragged that I could redo this app in Angular in two weeks, and my team called me on it. I lost the bet, because it took me three weeks, but after our codebase shrunk to one 17th the original size people paid attention. At this point Angular was not what it is today, and the application build in Angular was more or less one big hack, but it showed what is possible with declarative approach. From that moment on, my job was to turn Angular into a real framework. At first we used it for our internal Google application, but soon other teams started to notice. Specifically the Doubleclick for Advertisers team, which was just in the midst of doing a rewrite, became our toughest customer, building a large scale enterprise applications on top of it.

Three more software engineers and two more years later and we had Angular v1.0 to share with the world. What problem did AngularJS solve for developers? HTML and browsers are awesome for serving static documents. Turning static pages into dynamic ones is possible with JavaScript, but the fact that the platform was not originally designed to serve dynamic applications shows painfully every step of the way. Angular increases the abstraction level of the browser to make it more suitable for building dynamic webapplications. It does this not by creating new syntax, but by teaching the old browsers new tricks. Angular is instantly familiar to web-developers since it just HTML with features which make building dynamic pages easy. Angular provides data binding, components, dependency injection, and a testing for the application. How is it unique frameworks? from other

Most developers see a complex problem and they write a function for it, and then tell everyone to use it. I do things differently. I dont want to hide the problem behind a function, I want the problem to go away. I dont want others to run into the problem and say, I wonder if anyone has solved this and put it behind a function that I can use. I want the problem to be
5 of 14

INTERVIEW MIKO HEVERY

leveled with the ground, so that when the next developer passes through, there is nothing to snag on. I want the developer to pass by without even realizing that there used to be nasty problem hiding here, the developer should be blissfully ignorant. When you think this way, the result is not a library which has functions for common problems, the result is a browser with fever-sharp edges. When you develop in Angular, you are developing in a better browser, where things just work, and when you look at the application code it is clean, succinct, and free of functions which hide the problems. Its just you and the browser. I often say that Angular is what the web browser would have been, had it been designed for applications, but I think this Twitter quote says it better: Pretty sure that HTML6 is going under the codename @angularjs! Is it accurate to categorize AngularJS as a framework? If not, what is a more accurate description? Most people are familiar with libraries and framework terminology. Library is a collection of functions which do useful things, where the developer is fully in charge. Framework is a piece

ABOUT ANGULAR

of code which is in charge and calls your application to fill in the details of the application behavior. Frameworks typically force the implementation to follow its rules, and implement its interfaces. If I had to choose, I would say that Angular is a framework, but I think a better description is that it is a better browser. Frameworks are needed whenever the platform one is building up does not match the needs of application d e v e l o p e r. HTML has lots of frameworks and libraries, because it was not intended for building dynamic applications, rather it was designed for building static documents. When building an iOS app, developers dont start by choosing a framework, instead they just build the application. The reason for that is that the iOS platform matches the needs of the application developers. This is in stark contrast to HTML. For this reason I dont think of AngularJS as a framework but as a better browser which better matches the needs of web-application developers. You may argue that it is just another way to describe a framework, but I would like
6 of 14

INTERVIEW MIKO HEVERY

ABOUT ANGULAR

to point out one difference. If you look at an AngularJS application, there is complete lack of an angular API. There is nothing to inherit, nothing to call, and no complex life cycle for your controllers to follow. This is a stark contrast to most frameworks which force you to implement its interfaces, call its API and live by its lifecycle and its events. It really is just a better browser. What are some of the most common misconceptions about AngularJS and how it works? When most developers look at the framework, the knee jerk reaction is to dismiss it as just another templating framework. But even here, Angular is unique. Most templating frameworks consume String template and merge it with data to produce a String output which then gets .innerHTML into the DOM. This is great the first time, but subsequent updates clobber the user state, such as selection and cursor location. Angular, on the other hand, consumes DOM template, not String template, and the result is a live, continuously updating view which updates only the relevant parts of the page. The result is two way databinding which is seamlessly updates the DOM and makes the application model the single source of truth at all times. The second misconception is that Angular must be slow or unsuitable for large scale applications, because it does dirty checking. While it is true
7 of 14

INTERVIEW MIKO HEVERY

ABOUT ANGULAR

that dirty checking is how get the model change notification, it turns out that with some clever optimization it is not slow at all. Just about every well designed page is within the capability of event old legacy browsers. What should developers unlearn in order to use Angular most effectively? The number one question we get is how to get a hold of DOM in the controller and how to register listeners on it. Developers have come to accept DOM manipulation as a necessary evil, and rely on it in even the most basic of UIs. Another thing unique about Angular is that there is no main method to the application which would bootstrap the framework. Through the magic of Dependency Injection the applications assemble themselves in the right way automatically. How can Angular be used to make the browser smarter? I think the most powerful and unique thing about Angular is that it allows the application developer to extend the browser vocabulary to turn HTML int a DSL (domain specific language). This allows the developer to build a specifically tailored constructs which fit the application need. It also turns the HTML into a declarative description of how the application is put together. Given new developers coming onto the project clear map of how the

application is put together. Are there any plugins you recommend for using with Angular? Any other tools? Yeoman - is a robust and opinionated set of tools, libraries, and a workflow that can help developers quickly build beautiful, compelling web apps. testacular - Spectacular test runner for JavaScript. ngmodules - Collection of common Angular modules. AngularStrap - AngularJS bindings for Twitter Bootstrap. AngularUI - Common UI widgets. What is in store for new features in Angular? One of the biggest complaints of all AJAX-style applications is that they are not crawlable by the search engines. To solve this the site needs to provide server-side rendering of the site, so that it can be indexed by the crawler. The second issue is that AJAX applications do not render until after the Javascript has downloaded and executed. This makes the AJAX application appear slower at startup than classical application. Both of these issues can be solved by server side pre-rendering, but it requires that the AJAX application efficiently reconnects with the server render HTML. The next area is to add declarative animations to the HTML for the
8 of 14

INTERVIEW MIKO HEVERY

directives which change the DOM structure.

ABOUT ANGULAR

Finally, we would like to add lazy code loading. This will further speed up the application since it would allow only the code which is needed for rendering of the current page to be downloaded.

9 of 14

INTERVIEW MIKO HEVERY

MIKO HEVERY
ABOUT TESTING
What was your contribution to JSTestDriver? I was always unsatisfied with the way the JavaScript tests are executed. The need to switch to a browser and refresh it to execute the tests, would break my workflow. I wanted the tests to execute all the time in the background without any developer interaction on every file save. By running the tests all the time, the developer would get instant feedback whenever something would get broken. JSTestDrive was the first iteration of that idea, and it was implement by Jeremie Lenfant-Engelmann and Cory
10 of 14

INTERVIEW MIKO HEVERY

ABOUT TESTING

Smith. JSTestDriver is not a new way to write the tests as any test framework can be used for writing the tests. It is not a new assertion since any assertion framework can be used. It is a new way of getting the JavaScript code to the browser and executing it. With the popularity of node, the ideas behind JSTestDriver have been re-implemented into an even slicker package in Testacular by Vojta Jina. This reimplementation takes all of the learnings behind the JSTD and corrects many of the its shortcomings. Testacular allows execution of all 1,600 AngularJS tests in about 3 seconds. This means that we can run all angular tests from our IDE on every save. This fundamentally changes the way one develops code in JavaScript. Can you tell us about this tool? How does it help JavaScript developers? Testacular is responsible for breaking out of the browser sandbox. The reason why existing test runners are cumbersome, is that browsers by design are sandboxed from the host OS. This makes it difficult to get the new code into the browser and the results out of the browser window and into the IDE for the developer. Testacular solves this by running an HTTP server which provides a way to capture browsers. Then any number of browsers, even on remote machines or mobile devices can connect to the server and become slaves. Testacular

sets up web-socket connection to the browser to allow the tests to break out of the browser sandbox. Testacular then watches the file system and pushes the changed files to the browsers for instance execution. The result is super fast, seamless, and enjoyable testing experience. What types of testing should developers plan for their code? Any project needs a lot of unit tests to prove that the behavior of the individual classes is correct. These unit tests can than with the help of Testacular be executed on every file save for instant feedback. But angular goes further, it provides standard mocks for all external Angular services such as XHR and browser location, so that Angular applications can be tested with minimal effort. The dependency injection system can then be used to assemble the application with key services mocked out. However unit-tests do not prove that the individual classes and bindings are correctly hooked up. For this reason Angular also comes with Scenario runner which understands the inner workings of Angular to provide scenarios which do not need to do application pooling to verify that the server has responded. At what point in the development cycle should they plan for each type of testing?

11 of 14

INTERVIEW MIKO HEVERY

ABOUT TESTING

Testing must be baked into the development process from the very first line of code written, otherwise you end up with code which does not lend itself for testing. This results in hard to understand tests, which are very brittle, propagating the myth that testing does not catch any bugs. What are some key points to remember to write testable code? - Use dependency injection, rather than creating your own dependencies or looking them up in global variables. Always interact with your direct dependencies, rather than breaking the Law of Demeter. - Avoid work in constructor, since the constructors can not be mocked out in tests. - Singletons which enforce their own uniqueness reply on global variables, and global variables are an antipattern. For deeper discussion refer to Guide to Writing Testable Code. What are some of the more common mistakes developers make when writing testable code? I think you want to ask, what are the most common mistakes when writing code, and that is that it is not testable. They either dont write tests, or write them after the fact. The beauty of writing the tests before is that they make you think about the API first, and then the implementation. Also no one writes a convoluted test, when the

code to be tested is yet to be written. One writes convoluted tests only as a necessity of existing code. Most developers write code first, which means that their API is incidental to the implementation. This is what makes the test convoluted, and forces you to do things like excessive mocking and monkey patching. Do you have any other favorite debugging tools? Not really, since tests usually prevent the need to do complex debugging.

12 of 14

INTERVIEW MIKO HEVERY

MIKO HEVERY
ABOUT STUFF
Can you tell us about any other open source projects you have contributed to? In the past I was working on Testability Explorer, which was an attempt to help diagnose testability problems in the code. It was meant as a feedback tool, which would suggest dependencies. Are there any projects you have on the side or would like to focus on more in the future? I believe in doing one thing and doing it well. Having too many things to focus on will most likely result in poor performance on each of them. Better to have one project for which you get
13 of 14

INTERVIEW MIKO HEVERY

recognition than ten, which no one has ever heard of. What are some of the advancements in browser technology youve been most excited about? Object.observe Web-components and shadow DOM What are some of your favorite HTML5 or web standard additions?

I dont think that I have anyone in particular, but I am a big fan of anything which will allow the web to become more ubiquitous. What do you like to do in your spare time? Do you have spare time? I used to have spare time, it was nice. Now I have kids, and any free time goes to them, and I love spending time with them and learning from them.

ABOUT STUFF

appliness

TUTORIALS JAVASCRIPT

BOOKMARK / SHARE / TOC

Building Huuuuuge Apps with AngularJS


by Brian Ford

TUTORIALS BUILDING HUUUUUUGE APPS WITH ANGULARJS

by Brian Ford
GETTING STARTED

AngularJS is one of the most suitable JS frameworks for writing large apps.

The AngularJS documentation is great for getting started and for looking up specific API calls. However, it doesnt really tell you how to organize and manage your app as it grows to tens or hundreds of thousands of lines of code. Ive collected here some of my observations and best practices for how to manage your sprawling application. First well take a look at organization, then move on to some tips on improving performance, and conclude with a brief summary on tools, servers, and build processes. While this post will focus on big apps in particular, theres a great video on YouTube from the December 2012 AngularJS meetup on best practices thats also worth checking out. DONT WRITE A HUGE APP The best advice about huge apps is not to make them. Write small, focused, modular parts, and progressively combine them into bigger things to make your app. (This advice brought to you by node.js hacker and all around cool dude @substack) ORGANIZATION Probably the biggest question with large apps is where to put all of that code. On your toolbelt of organizational tools, youve got files, directories, modules, services, and controllers. For a quick overview of good AngularJS project structure, check out the Angular Seed on Github. However Id like to go a bit more in-depth and offer some additional advice on project structure. Lets start with directories and work our way down the list. DIRECTORIES This is the typical folder layout that I recommend:
root-app-folder --- index.html --- scripts --- controllers --- main.js --- ... --- directives
2 of 10

TUTORIALS BUILDING HUUUUUUGE APPS WITH ANGULARJS

-----

--- myDirective.js --- ... --- filters --- myFilter.js --- ... --- services --- myService.js --- ... --- vendor --- angular.js --- angular.min.js --- es5-shim.min.js --- json3.min.js --- app.js styles --- ... views --- main.html --- ...

As you add more files, it might make sense to create subdirectories to further organize controllers and services. For instance, I often find myself making a models directory inside of services. My rule of thumb is to only further sort files into directories if there is some rational hierarchy by which you can organize the files. FILES Each file should have one thing in it, where a thing is a controller, directive, filter, or service. This makes for small, focused files. It also helps create a litmus test for how APIs are doing. If you find yourself flipping back and forth through files too frequently, this is an indication that your APIs are too complex. You should rethink, refactor, and simplify. I would make an exception for closely related directives. For example, if you have an <pane> directive that requires <panel> to be a parent, those should be in the same file. MODULES Define and configure all modules in app.js:
angular.module(yourAppName, [yourAppDep]); angular.module(yourAppDep);

3 of 10

TUTORIALS BUILDING HUUUUUUGE APPS WITH ANGULARJS

Define controllers, services, etc. on modules like this:


angular.module(yourAppDep).controller(MyCtrl, function () { // ... });

Although we (the AngularJS team) have discussed being able to lazy-load at the module granularity, its not yet on the roadmap for the next version of Angular. There was a good discussion on Google+ about using multiple top-level AngularJS apps to produce a lazy-loading-like effect. I havent tried it or seen it done, but if you desperately need to reduce payload size, thats certainly one way to do it. The only remaining question is how to subdivide controllers, directives, services, and filters into modules. The Angular Seed puts filters, services, and directives into separate modules, but that seems a bit silly to me. Depending on the app, Id be more inclined to organize modules by page/route. From a performance perspective, it doesnt really matter how you organize your modules, so choose whatever method best suits your project. DEPENDENCIES In general, services, controllers, directives, etc. should have as few dependencies as possible. This is good software development practice in general, but its worth mentioning. This also will help in testing. APIs should be layered. Controllers especially should not be synthesizing different levels of abstraction. DIRECTIVES Use an app-specific prefix for directives. This is useful for avoiding collisions with 3rd party components. On the subject of 3rd party components, theres a growing community site called ngmodules that looks promising. For example, if your app is called The Best Todo List App Ever, you might prefix your directives with btla.
angular.module(yourAppDep).directive(btlaControlPanel, function () { // ... });

4 of 10

TUTORIALS BUILDING HUUUUUUGE APPS WITH ANGULARJS

You might worry about directive names becoming too long, but I havent seen it become problematic. Youll never really see a performance hit from long directive names, thanks to gzip compression. SERVICES
angular.module(yourAppDep).service(MyCtrl, function () { // ... });

MODELS AngularJS is unique among JavaScript frameworks in that it gives you complete control over your model layer. I think this is one of the great strengths of Angular, because at the core of your application is your data, and data varies wildly from app to app. My biggest recommendation is to consider what data you will be using, and how you will store it. If youre using a NoSQL datastore like CouchDB or MongoDB, you might be content working with plain-old JavaScript Objects (POJO) and functional helpers. If youre using a relational database like MySQL, you might want psuedo-classes with methods for mutating, serializing, and deserializing the data. If your server provides a RESTful interface, $resource might be a good place to start. These are just suggestions; any of these approaches might be useful outside of the situations I described. With so many options, this is sometimes a challenging decision to make. But thinking hard about your data will pay off. In general, youll find many great utilities for dealing with models in Underscore.js, the utility library that also powers Backbone.js. CONTROLLERS By convention, controller names should start with a capital letter and end with Ctrl.
angular.module(yourAppDep).controller(MyCtrl, function () { // ... });

Remember that controllers can be reused. This seems obvious, but Ive caught
5 of 10

TUTORIALS BUILDING HUUUUUUGE APPS WITH ANGULARJS

myself reimplementing features in different controllers. For example, consider a user control panel that allows a user to change application settings and a dialog box prompting a user to change a setting. Both could share a common controller. PERFORMANCE AngularJS apps are generally very, very fast. Most apps really dont need any sort of special optimization, so unless youre experiencing poor performance, your time is better spent improving your app in other ways. For these exceptional cases Angular provides some excellent ways to address performance issues. First though, its important to identify the cause of performance degradation. For that, I highly recommend the AngularJS Batarang Chrome extension or Chromes built-in CPU profiling. OPTIMIZING THE DIGEST CYCLE AngularJS uses dirty checking in its digest cycle. For the uninitiated, you can read more about the digest cycle in the official docs and in this StackOverflow answer. Sometimes, you want to be able to avoid a digest cycle. One common situation in real-time WebSocketed apps is that you dont always want to digest when you receive a message. Consider a real-time game where messages are sent from the server 30 or more times per second.
app.factory(socket, function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // this could fire many times a second var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });

One great way to deal with this is to throttle the requests so a digest only happens a few times a second. Underscore.js provides such a function, but the
6 of 10

TUTORIALS BUILDING HUUUUUUGE APPS WITH ANGULARJS

implementation is pretty tiny, so Ive reproduced it inside the socket service below:
app.factory(socket, function ($rootScope) { // // // // Underscore.js 1.4.3 http://underscorejs.org (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. Underscore may be freely distributed under the MIT license.

// _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500));

// limit to once every 500ms

7 of 10

TUTORIALS BUILDING HUUUUUUGE APPS WITH ANGULARJS

} // ... }; });

Other times, you know an incoming change will only affect certain scopes, and might want to just dirty check those. For those cases, you can call $scope.$digest instead of $scope.$apply. $digest will only run the digest cycle on the scope its called on, and all of that scopes children. Finally, to keep digest cycles short, watch expressions in $scope.$watch should be as fast as possible. Wherever possible, avoid deep comparisons. Remember, you only need to compare things that affect the view. FILTERS Filters are called at least twice during every digest cycle. For that reason, its best if they are lightweight. In cases where data is loaded and displayed, but not modified, moving the transformations done in filters to run on the data when its fetched might be better. This is actually relatively simple, since AngularJS exposes filters to be used programmatically through $filter. For instance, you load a list of names in lower-case, but need title-case, so you have a filter that does the transformation:
{{someModel.name | titlecase}}

Its pretty easy to move this to your controller and change the name to title-case when its loaded.
angular.module(myApp).controller(MyCtrl, function ($scope, $http, $filter) { $http.get(/someModel) .success(function (data) { $scope.someModel = data; // run the same titlecase filter inside the controller after loading the data $scope.someModel.name = $filter(titlecase)($scope.someModel.name); });

8 of 10

TUTORIALS BUILDING HUUUUUUGE APPS WITH ANGULARJS

});

For cases that you cant transform data upon retrieval, memoization is a great way to speed up your expensive filters without much work. Addy Osmani has a pretty great article on memoization in JavaScript thats worth a read. As for implementation, Underscore.js provides an excellent memoization function that you can use. This technique should not be used blindly, however. Memoization only helps when youre calling a filter frequently with the same, unchanged models. For rapidly changing models that have many different values throughout your applications runtime, youre better off not memoizing filters that act on that data. TESTING Testing is immensely important for large projects. Tests allow you to refactor with confidence, which is essential in keeping code clean on a large project. Large apps should have both unit and end-to-end (E2E) tests. Unit tests are great in helping you pinpoint problems, and E2E tests ensure that the whole app works as expected. Each controller, service, filter, and directive should have a set of unit tests. Each feature of your app should have an E2E test. This is another topic that deserves more attention. Fortunately, the AngularJS documentation has more to say on both unit and E2E tests. My colleage Vojta Jina also spoke recently about testing directives. The video is on YouTube, and definitely worth a watch. TOOLS Ive been doing a lot of work on Yeoman to try to consolidate best practices and good project structure, and make what little boilerplate AngularJS has automagically generated. I highly recommend checking it out. The AngularJS Batarang is another of my projects, and is great for both debugging and finding performance bottlenecks. SERVER As youre aware, you can use any server you want with AngularJS. It is strictly a client-side library. My recommendation and prefered setup is to use Node.js alongside nginx. I use nginx to server static files, and Node to create a RESTful API and/or socketed app. Node.js hits a sweet spot between ease of use and speed.
9 of 10

TUTORIALS BUILDING HUUUUUUGE APPS WITH ANGULARJS

For instance, its relatively easy to spawn worker processes or create a webserver that can use all of your fancy servers cores. As for cloud providers, Ive used both Nodejitsu and Linode to great success. Nodejitsu is great if youre sticking strictly to node. It makes deploying your app easy, and you dont have to worry about your server environment. You can spawn additional node processes as needed to scale and handle bigger loads. If you need more control over your server environment, Linode gives you root to a fleet of VMs. Linode also provides a nice API for managing VMs. And there are plenty of other great cloud server providers that I havent had a chance to look at yet myself. Configuring and scaling a backend is a subject worthy of its own article, and theres no shortage of great advice elsewhere for that. BUILD PROCESS Admittedly, this is one thing Angular needs to be better at, and one of my huge aims for 2013 is to help on this front. Ive released ngmin, a tool that I hope will ultimately solve the problem of minimizing AngularJS apps for production. For now, I think your best bet is concatenating your JavaScript files with app.js first, then using ngmin to annotate DI functions, and finally minifying with Closure Compiler with the flag --compilation_level SIMPLE_OPTIMIZATIONS. You can see an example of this at work in the build process for angular.js. I dont recommend using RequireJS with AngularJS. Although its certainly possible, I havent seen any instance where RequireJS was beneficial in practice. CONCLUSION AngularJS is one of the most suitable JS frameworks for writing large apps. Outof-the-box, its very fast and greatly helps structure your app. But hopefully this advice is useful as you push the boundaries for whats possible with AngularJS.

Brian Ford
Web Developer

HIS BLOG

SHARE

TWITTER

GITHUB

appliness

TUTORIALS JAVASCRIPT

BOOKMARK / SHARE / TOC

Responsive Form Validation with AngularJS and HTML5


by Glenn Gervais

TUTORIALS RESPONSIVE FORM VALIDATION WITH ANGULARJS AND HTML5

by Glenn Gervais
GETTING STARTED

A modern approach to form submission and validation.

This AngularJS example demonstrates how HTML5 and AngularJS can work together to provide a modern approach to form submission and validation without lengthy JavaScript validation algorithms, cumbersome CSS, or page refreshes. Note that there are multiple ways to present and submit a form using HTML5 and AngularJS. Your implementation should depend on the needs of your application. The method I use here does not perform an actual submit. Instead, when the Submit button is clicked it calls a function that updates a visitorInfo object. Any action can be performed when the visitorInfo object is updated by modifying the update function in VisitorFormController in app.js. The example provides immediate feedback based on the data entered into the input fields. Every input field has been flagged as required and you can watch the debugging info to see the status change dynamically as each input field is populated.

2 of 4

TUTORIALS RESPONSIVE FORM VALIDATION WITH ANGULARJS AND HTML5

Lets take a closer look at the email section to see how this is done:
<span class=label>Email:</span> <input type=email name=email placeholder=Email required= /> <span class=valid>?</span>

The first line is simply the label that is show before the input field. The label class lets me apply some styling to keep it on the same line as the input field, make it bold, etc. No magic there. The input field has several attributes. Name gives us a means of referring to that specific field. Type defaults to text but weve given it the HTML5 type of email. Doing so implements validation rules, such as requiring an & and a domain type (like .COM). It also causes responsive mobile devices to present different UI. For example, assigning a type of email will cause .COM to appear on keyboards of many mobile devices. The ngModel directive links the input field to a scope property, in this case visitorInfo. email. visitorInfo is an object that holds all of the form properties. Notice that each input field model includes visitorInfo before the property name. You can watch visitorInfo populate in the debugging info as you fill in the form. Placeholder is a new input attribute that allows you to define a short data entry hint that will appear inside the input field. The hint disappears when the user starts entering text but will reappear if the text is deleted. Placeholder text does not get submitted as form data. Finally, there is the required attribute that defines the field as one that must be filled in for the form to be considered valid. The span below the input field contains a checkmark that is not visible when the page first loads. The AngularJS ngShow directive has an evaluation in it that will only allow the span to be visible when the field passes email field passes validation rules. Negative feedback is provided courtesy of CSS and AngularJS. Enter a value in the First Name field and then delete it. The field background will change to red. If you look in style.css youll see the following section:
input.ng-invalid.ng-dirty { background-color:red;
3 of 4

TUTORIALS RESPONSIVE FORM VALIDATION WITH ANGULARJS AND HTML5

ng-invalid and ng-dirty automatically get assigned as classes based on the input field state. If the field contents are invalid then the input field will be dynamically assigned the ng-invalid class. We can use that class to style the field in certain circumstances as I did above. Pretty slick! See the AngularJS API for more information on these class assignments. Finally, check out the Submit and Restore buttons. The Submit buttons job is to update the visitorInfo object. The restore button restores all of the field data to the last submitted value. Both buttons react to the state of the form. The submit button will enable and turn green when the entire form has been filled out with valid information. The restore button enables when the form data differs from the stored visitorInfo object data. This functionality is done using a combination of AngularJSs ngClick and ngDisabled directives:
<button ng-click=reset() ng-disabled=isUnchanged(visitorInfo)>RESTORE</button> <button class=submitbtn ng-click=update(visitorInfo) ng-disabled=valForm.$invalid || isUnchanged(visitorInfo)>SUBMIT</button>

ngDisabled contains an evaluation. If the evaluation is true then ngDisabled will also be set to true, making the buttons un-clickable. If they evaluate to false then the buttons will become enabled. Once they are enable, they can be clicked and the clicks will be handled by the functions that are referenced in the ngClick directives. All in all it was very easy. The code itself is MUCH shorter than this post, which is a testament to the simplicity of AngularJS and HTML5 (or it could be just an indication that Im too wordy.) In either case, Im using that line as an opportunity to wrap this post up. As always, check out the code on Plunkr. Fork it, edit it, experiment with it. Its the best way to learn.

Glenn Gervais

HIS BLOG

SHARE

Web Developer at Lexia Learning

TWITTER

GITHUB

appliness

TUTORIALS CSS

BOOKMARK / SHARE / TOC

Using Form Elements and CSS3 to Replace JavaScript


by Louis Lazaris

TUTORIALS USING FORM ELEMENTS AND CSS3 TO REPLACE JAVASCRIPT

by Louis Lazaris
GETTING STARTED

A CSS-only solution is much cleaner and easier to maintain.

Since the advent of CSS3 and the continuing improvement in browser support for new features, more developers are coming up with unique ways to add functionality to web pages without the use of JavaScript. In the last couple of years, a number of developer techniques have sprung up using form elements to replace functionality normally done with JavaScript and, commonly, with a library like jQuery. In this article, I run through some of these techniques and discuss the concepts involved. This should help you get a good overall understanding of how these tricks work, and may give you insight into creating something with pure CSS for one of your future web projects. WHY USE THESE TECHNIQUES? There are a few reasons why these techniques might be beneficial to your code. First of all, any extra JavaScript makes our websites slower because youd be adding more code and in some cases potentially an extra external resource for the page to load. Additionally, a CSS-only solution is much cleaner and easier to maintain. With good commenting, it should be fairly easy to track down how certain functionality is operating, should you ever need to make any necessary corrections or improvements. INITIAL WARNING! The fact is, the techniques mentioned in this article may not be good options because of the semantic problems and accessibility challenges that arise when using form elements in a way not intended. So although this article has definite experimental and educational benefits for those learning CSS, take into consideration any drawbacks that might occur before using these techniques extensively in any project. Of course, if youre able to ensure you can use these without accessibility problems, then by all means do so. But please be forewarned that they could be problematic.

2 of 7

TUTORIALS USING FORM ELEMENTS AND CSS3 TO REPLACE JAVASCRIPT

TAB SWITCHER WITH RADIO BUTTONS Many websites feature a tab switcher. In brief, this is a single unit, or widget, sometimes appearing in the sidebar of a website, that has two or more content areas that the user can choose from. Only one of these content areas is visible at one time, and the options are displayed in the form of tabs at the top of the widget. Most older tutorials and demos use list items, div elements, and jQuery to create this functionality. But in the past couple of years, a number of scripts and tutorials have begun to use radio buttons and some new CSS3 pseudo-classes to assist with the functionality of the tabs. Lets run through how this might be done. Our markup can be divided into multiple sections. Each section might look something like the following markup:
<section class=tab> <input type=radio id=tab-one name=tab-set checked> <label for=tab-one>Tab #1</label> <div class=tab-content> <p>First tab content goes here.</p> </div><!-- tab-content --> </section><!-- .tab (1) -->

This might be repeated three or four times. Then, we could have a wrapper with a class of tab-switcher holding all these sections together. The key parts of the markup are the input elements with type radio and their associated label elements. Here is the example in JS Bin. Select CSS to see that code. Throughout this article, vendor CSS3 prefixes are omitted for brevity. If you want to see this code in action, you can check out this JS Bin demo. Now lets consider the concepts involved in creating this tab switcher. Notice the demo is not using any JavaScript. HIDDEN RADIO BUTTONS Although this example is using radio buttons, we dont actually see any radio buttons on the page. This is because the radio buttons are set to display: none in our CSS. But if the radio buttons arent visible on the page, how do they function? Well, notice the markup also includes a label element thats associated with each radio button using IDs and for attributes. Although the radio buttons are not visible
3 of 7

TUTORIALS USING FORM ELEMENTS AND CSS3 TO REPLACE JAVASCRIPT

or clickable, the associated label elements are. And if you are familiar with label elements, you know that browsers allow the labels to be clicked to select their associated form elements. Thus, all we have to do is style our labels to look like tabs (I used rounded corners and a few other styles) and then target them using the :checked pseudo-class along with the general sibling selector (the tilde character, ~). The general sibling selector lets us target both the content section of the selected tab, as well as the label element. Using :checked in combination with the sibling selector lets us target only the parts of the tab switcher that are currently selected, or active. With some absolute positioning along with z-index, we then can make the chosen section visible. In the demo, I also added some CSS3 transitions to prevent the switching from occurring too quickly. CONCEPTS TO REMEMBER To summarize this technique, here are the concepts to keep in mind: - The radio buttons are not visible on the page. - Any label element can be associated with any form element, allowing the form element to be selected via the label without the form element being visible. - The :checked pseudo-class in combination with the general sibling selector lets us target elements associated with the selected form element.

ACCORDION SLIDER WITH CHECKBOXES Once again, we create a commonly-used web page widget while avoiding any JavaScript. This time, we create a vertical accordion slider. For our markup, similar to the tab switcher, we divide each accordion section using HTML5 section elements. We have a wrapper with a class of accordion-wrap enclosing all five sections. Each section looks something like the following markup:
<section class=accordion-item> <input type=checkbox id=accordion-one name=accordion-group checked> <label for=accordion-one>Accordion Section #1</label> <div class=accordion-content>
4 of 7

TUTORIALS USING FORM ELEMENTS AND CSS3 TO REPLACE JAVASCRIPT

<p>content here... </p> </div><!-- .accordion-content --> </section><!-- .accordion-item -->

The actual example has five of these, but Im showing you just one for brevity. Again, the key parts of the code are the checkbox input element and its associated label element. Our CSS is similar to the previous example, and once again we utilize the :checked pseudo-class along with the general sibling selector. Here is the example in JS Bin. Select CSS to see that code. USING MAX-HEIGHT This example uses checkboxes, which, unlike radio buttons, allow multiple choices to be selected. This means the different items in the accordion can all appear expanded at the same time. The tabs example used a combination of opacity and z-index to show the selected item. But this time, were using the max-height property. Any unchecked item starts out with a max-height value of 0, along with overflow: hidden, so its not visible. When an item is checked, we set the max-height to any large number that exceeds the height value of the largest item. We use max-height and not the height property, because although height can be animated via CSS3, you cannot animate from 0 to auto. So we have to choose an arbitrary max-height value, to ensure the height of the element doesnt extend far past the actual content it holds. (Credit to Lea Verou for this technique.) CONCEPTS TO REMEMBER Here are the main points to remember in this example: - Checkboxes allow multiple elements to be selected, thus mimicking what we might do with JavaScript. - Again, we use labels to trigger the selection, but keep the checkboxes hidden. - We show the content of each accordion item by animating from max-height: 0 to a large max-height value that exceeds the tallest item. - We use a different transition-duration value for the checked state compared to the unchecked state, which is one of the flexibilities of CSS3 transitions.

5 of 7

TUTORIALS USING FORM ELEMENTS AND CSS3 TO REPLACE JAVASCRIPT

REVEALING A TEXT FIELD WITH FOCUS This final technique is simply a form button that, when clicked, animates to reveal a text input element. Lets look at the markup first, which is quite simple:
<input type=text class=txt id=textfield> <label for=textfield>Click to Type</label>

In this example, were using nothing but a single text field with an associated label element, as in the following JS Bin example. Select CSS to see the related code. USING :FOCUS In this example, were using the :focus pseudo-class to make the form field visible. The label element is styled to look like a button. Its positioned to appear on top of the text field, so the text field is not immediately visible. We then use our super-handy sibling selector to animate the left property on the label element. This reveals the text field by moving the label element out of the way. Take a look at this code in action at this JS Bin demo. CONCEPTS TO REMEMBER To summarize what we did in this last example: - The :focus pseudo-class is used to detect if the user has clicked the label element, thus adding focus to the text field. - The label and the form element are positioned absolutely and stacked using z-index. - A CSS transition animates the left property to move the label out of the way when the user is ready to type. - The general sibling selector is once again used to target an element adjacent to the selected form field. BUGS, PROBLEMS, AND WARNINGS As already mentioned, these techniques should be considered carefully before being used. First of all, older versions of WebKit had a bug that didnt allow the :checked pseudo-class to work in conjunction with a sibling selector. Fortunately,

6 of 7

TUTORIALS USING FORM ELEMENTS AND CSS3 TO REPLACE JAVASCRIPT

not many people are using older versions of WebKit so this is less of a problem today. The other problem occurs in WebKit on iOS5 or below, which doesnt allow a checkboxs state to change by touching a label element. A workaround for this is to add an empty inline onclick handler to all label elements, as I did in the demos for this post. Additionally, iOS has slow reaction to label clicks that trigger input state changes. A more significant problem, however, is the fact that the markup for these elements could cause problems with assistive technology devices like screen readers. This accessibility issue should be taken into consideration before implementing a method like these. There has been discussion about the possibility of adding this type of behavior natively to elements with pure CSS, to prevent these bugs and accessibility problems, but that would be much further down the road and would not be implemented in all browsers for a very long time. WHERE TO GO FROM HERE To deal with some of the cross-browser problems, you can attempt to use a selector polyfill like Selectivizr to fill in any gaps, but you might end up with buggy or unpredictable results, and, unless you provide an animation polyfill, transitions are missing. As mentioned in the introduction, if you take care to avoid any accessibility problems, these techniques can be useful. By avoiding JavaScript, your pages load faster, the functionality is less likely to have any lag, and with a few simple comments in your HTML or CSS your code is easier to maintain.

Louis Lazaris
Freelance web developers

HIS BLOG

SHARE

TWITTER

GITHUB

appliness

TUTORIALS CSS

BOOKMARK / SHARE / TOC

Conditional loading of resources with mediaqueries.


by Christian Heilmann

TUTORIALS CONDITIONAL LOADING OF RESOURCES WITH MEDIAQUERIES

by Christian Heilmann
VIDEO TUTORIAL

This could be used to conditionally load high resolution images, couldnt it?

Here is a quick idea about making mediaqueries not only apply styles according to certain criteria being met, but also loading the resources needed on demand. You can check a quick and dirty screencast with the idea or just read on.

Mediaqueries are very, very useful things. They allow us to react to the screen size and orientation and even resolution of the device our apps and sites are shown in. That is in and of itself nothing new in the past we just used JavaScript to read attributes like window.innerWidth and reacted accordingly but with mediaqueries we can do all of this in plain CSS and can add several conditions inside a single style sheet. In addition to the @media selectors in a style sheet we can also add a media attribute to elements and make them dependent on the query. So for example if we want to
2 of 7

TUTORIALS CONDITIONAL LOADING OF RESOURCES WITH MEDIAQUERIES

apply a certain style sheet only when the screen size is larger than 600 pixels we can do this in HTML:
<link rel=stylesheet media=screen and (min-width: 601px) href=large.css>

Handy isnt it? And as we applied the mediaquery we only request this file when and if it is needed which means we even save on an HTTP request and dont suffer the latency issues connected with loading a file over the wire (or over a 3G or EDGE connection). Especially with movies and source elements this can save us a lot of time and traffic. Sadly, though, that is not the case. LOAD ALL THE THINGS EVEN WHEN THEY DONT APPLY Lets take this HTML document:
<html lang=en-US> <head> <meta charset=UTF-8> <style type=text/css> body { font-family: Helvetica, Arial, sans-serif; } p { font-size: 12px; } </style> <link rel=stylesheet media=screen and (min-width: 600px) href=small.css> <link rel=stylesheet media=screen and (min-width: 4000px) href=big.css> <title>CSS files with media queries</title> </head> <body> <p>Testing media attributes</p> </body> </html>

If your screen is less than 600 pixels wide the paragraph should be 12px in size, over 600 pixels it is 20px (as defined in small.css) and on a screen more than 4000 pixels wide (not likely, right?) it should be 200px (as defined in big.css). That works. So we really do not need to load big.css, right? Sadly enough though all the browsers I tested in do. This seems wasteful but is based on how browsers worked in the past and I assume done to make rendering happen as early as possible. Try it out with your devtools of choice open.
3 of 7

TUTORIALS CONDITIONAL LOADING OF RESOURCES WITH MEDIAQUERIES

As Ilya Grigorik points out in Debunking Responsive CSS Performance Myths this behaviour is by design. Make sure to read the comments on this post. However, stay with me as I think we should have a handle on loading all kind of resources on demand, which will be shown later. I am quite sure that CSS preprocessors like SASS and LESS can help with that, but I was wondering how we could extend this idea. How can you not only apply styles to elements that match a certain query, but how can you load them only when and if they are applied? The answer as always is JavaScript.

4 of 7

TUTORIALS CONDITIONAL LOADING OF RESOURCES WITH MEDIAQUERIES

MATCHMEDIA TO THE RESCUE Mediaqueries are not only applicable to CSS, they are also available in JavaScript. You can even have events firing when they are applied which gives you a much more granular control. If you want a good overview of the JavaScript equivalent of @media or the media attribute, this article introducing matchmedia is a good start. Using matchmedia you can execute blocks of JavaScript only when a certain mediaquery condition is met. This means you could just write out the CSS when and if the query is true:
if (window.matchMedia(screen and (min-width: 600px))){ document.write(<link rel=stylesheet href=small.css>); }

Of course, that would make you a terrible person, as document.write() is known to kill cute kittens from a distance of 20 feet. So lets be more clever about this. Instead of applying the CSS with a link element with a href which causes the undesired loading we dig into the toolbox of HTML5 and use data attributes instead. Anything we want dependent on the query, gets a data- prefix:
<link rel=stylesheet class=mediaquerydependent data-media=screen and (min-width: 600px) data-href=green.css> <link rel=stylesheet class=mediaquerydependent data-media=screen and (min-width: 4000px) data-href=blue.css>

We also add a class of mediaquerydependent to give us a hook for JavaScript to do its magic. As I wanted to go further with this and not only load CSS but anything that points to a resource, we can do the same for an image, for example:
<img data-src=http://placekitten.com/500/500 data-alt=kitten class=mediaquerydependent data-media=screen and (min-width: 600px)>

All that is missing then is a small JavaScript to loop through all the elements we want to change, evaluate their mediaqueries and change the data- prefixed attributes back to real ones. This is that script:

5 of 7

TUTORIALS CONDITIONAL LOADING OF RESOURCES WITH MEDIAQUERIES

(function(){ var queries = document. querySelectorAll(.mediaquerydependent), all = queries.length, cur = null, attr = null; while (all--) { cur = queries[all]; if (cur.dataset.media && window.matchMedia(cur.dataset.media).matches) { for (attr in cur.dataset) { if (attr !== media) { cur.setAttribute(attr, cur.dataset[attr]); } } } } }());

Here is what it does: - We use querySelectorAll to get all the elements that need the mediaquery check and loop over them (using a reverse while loop). - We test if the element has a data-media property and if the query defined in it is true - We then loop through all data-prefixed attributes and add a non-prefixed attribute with its value (omitting the media one) In other words, if the condition of a minimum width of 600 pixels is met our image example will become:
<img data-src=http://placekitten.com/500/500 data-alt=kitten class=mediaquerydependent data-media=screen and (min-width: 600px)> src=http://placekitten.com/500/500 alt=kitten>

This will make the browser load the image and apply the alternative text. BUT, WHAT IF JAVASCRIPT IS NOT AVAILABLE? When JavaScript is not available you have no problem either. As you are already in a fairyland, just ask a wandering magician on his unicorn to help you out.
6 of 7

TUTORIALS CONDITIONAL LOADING OF RESOURCES WITH MEDIAQUERIES

Seriously though, you can of course provide presets that are available should the script fail. Just add the href of a fallback which will always be loaded and replaced only when needed.
<link rel=stylesheet class=mediaquerydependent href=standard.css data-media=screen and (min-width: 600px) data-href=green.css>

This will load standard.css in any case and replace it with green.css when the screen is more than 600 pixels wide. Right now, this script only runs on first load of the page, but you could easily run it on window resize, too. As said, there are even events that get fired with matchmedia but pending testing according to the original article this is still broken in iOS, so I wanted to keep it safe. After all mediaqueries are there to give the user what they can consume on a certain device the use case of resizing a window to see changes is more of a developer thing. This could be used to conditionally load high resolution images, couldnt it? You can grab the code on GitHub and see it in action here.

Christian Heilmann
Evangelist at Mozilla

HIS BLOG

SHARE

TWITTER

GITHUB

appliness

TUTORIALS DESIGN

BOOKMARK / SHARE / TOC

Icons and Icon Fonts.


by Bear Travis

TUTORIALS ICONS AND ICON FONTS

by Bear Travis
GETTING STARTED

They are stylable, scale well, and can help reduce the clutter of individual files.

The explosion of devices and screen sizes has had an interesting effect on how designers and developers use icons on the web. Used well, icons can pack a lot of information into a small amount of visual real estate. They can help UIs communicate efficiently. For example, consider

The conversation bubble icon is not only smaller than the word Comments, it is also easier to pick out in a sea of text. One of the primary challenges facing icon designers is that their icons must display crisply when sized for different screens. When resized, especially to small areas, icons can become fuzzy or illegible. For the pixel aficionado, the only possible solution may be to hand tweak each icon for each display size. Even for a simple case (phone, tablet, and desktop screen sizes at low and high pixel densities), you may wind up with 6+ different versions of an icon. When you combine these variations with the need to style icons for different use cases (hovered, selected, disabled, etc), the number of icon renderings can quickly spiral out of control.

A 2424 icon becomes blurry when resized to a 3232 or 1616 size. Bookmark icon courtesy of PJ Onori from The Noun Project.

2 of 6

TUTORIALS ICONS AND ICON FONTS

Resizing vs pixel-aligning at 3232

The bookmark icon, used as part of a styled button Traditionally, there have been two ways to cut down on the number of icon files. The first, using SVG icons, replaces the resolution-dependent versions of an icon with a single vector. The second, combining multiple icons into a single sprite sheet, cuts down the number of files to manage during development and load during runtime. More recently, web fonts have become a convenient way of packaging vector icons into a single file. At their most basic, fonts just contain a bunch of glyphs, or vector shapes. For example, the Edge Web Font Strumpf contains the shape to represent a capital C. Instead of storing glyphs for characters, icon fonts store glyphs for you guessed it icons. Since font glyphs are vector based, they will scale more cleanly than their rasterized counterparts. Although icons from an icon font must be monochromatic (unlike their SVG counterparts), they can be styled using CSS, just like any other text on a web page. Instead of rasterizing an icon at different sizes, using different colors, opacities and filters, you can simply style them. CHARACTER FONTS Under the hood, there are three main mechanisms icon fonts use to replace markup with font glyphs. The first, and simplest, just maps standard latin characters to the icon glyphs. Instead of replacing the character C with , replace it with . You can use an icon font like this the same way you would use any other web font.
<style> @font-face { font-family: IconFont; src: url(icon-font.ttf); font-weight: normal; font-style: normal; } </style> <span style=font-family: IconFont>C</span>

3 of 6

TUTORIALS ICONS AND ICON FONTS

Note that the above web font incantation has been simplified from the full version. The weather icon font Meteocons uses this type of font encoding, substituting, say, a sunshine icon for the letter B. PRIVATE USE FONTS While these fonts display correctly, they can cause a disconnect between a pages markup and visual representation. After all, the letter B doesnt really map to our idea of sunshine. This disconnect can cause problems for developers trying to understand the code, search engines attempting to parse it, and screen readers assisting the visually impaired. The second method of icon font encoding gets around this problem by using characters that have no semantic meaning. The Unicode standard defines some characters for private use. These characters have no standardized meaning, and font developers can assign custom glyphs to them. When developers, screen readers, or search engines encounter one these characters, they should either ignore it, or interpret it as having a custom meaning within the markup. The markup using this method would look something like:
<style> @font-face { font-family: IconFont; src: url(icon-font.ttf); font-weight: normal; font-style: normal; } </style> <span style=font-family: IconFont>&#xE02D;</span>

There are two small annoyances to this method (think of them as opportunities for improvement). The first is that these characters need to be escaped as numbers, since you cant type them on your keyboard. The second is that each icon does have a meaning we are unable to convey through the markup. If you saw &#xE02D; in some HTML, Im guessing your first reaction wouldnt be Oh, that must be a comment icon. Unicode does provide some icon entities that can help machines parse markup, and the best of these icon fonts tend to map to them when possible. Most also provide human-friendly classnames that utilize pseudo-elements and the content property under the hood. For example, the markup might look like
<style> .icon-comment:before { font-family: IconFont; content: \e02d;

4 of 6

TUTORIALS ICONS AND ICON FONTS

} </style> <span class=icon-comment></span>

Examples of these types of icon fonts include Iconic and Font Awesome. LIGATURE FONTS There is an alternative solution to the problem of creating more human-friendly markup using ligatures, part of the new CSS3 Font Specification. Ligatures enable a font to substitute a single font glyph for multiple markup characters. Used in the traditional sense, ligatures combine adjacent characters into more visually pleasant forms.

Traditional ligature example from Wikipedia However, ligatures also make it possible to replace, say, comment, with the glyph . You have a literal description of the icon as part of the markup, which makes it easier to understand for developers, screen readers and search engines.
<style> @font-face { font-family: IconFont; src: url(icon-font.ttf); font-weight: normal; font-style: normal; } </style> <span style=font-family: IconFont>comment</span>

A couple icon fonts are already experimenting with this method, including SymbolSet and Ligature Symbols. It is important to note that because they are a new feature, ligatures are not yet fully supported across browsers. Icon fonts offer an interesting solution to the problem of icon management. They do have certain strengths and weaknesses to consider when looking at them for a
5 of 6

TUTORIALS ICONS AND ICON FONTS

project. They are stylable, scale well, and can help reduce the clutter of individual files. On the other hand, people are used to working with individual image assets because the workflow can be simple and fast. Right now, the biggest challenge may simply be that icons are more frequently distributed as individual assets rather than packaged as a font. As more and more icon fonts become available, however, I think well see them playing an increasing role in web development. If youre interested in learning more, check out one of the previously listed icon fonts, or create your own over at Icomoon.

Bear Travis

HIS BLOG

SHARE

Computer Scientist at Adobe

TWITTER

GITHUB

appliness

TUTORIALS JAVASCRIPT

BOOKMARK / SHARE / TOC

Making the Transition from Development to Design.


by P.J. Onori

TUTORIALS MAKING THE TRANSITION FROM DEVELOPMENT TO DESIGN

by P.J. Onori

If there is one thing to be taken away from this, it is to refrain from mentally separating design and development.

Just how does a person with development background move over to design? Here are some tips as someone who has gone through the process. A couple months ago, a person emailed me asking for tips for transitioning to design from a development background. As someone who had loosely gone through the same path (from programming to design to programming then back to design), I wanted to share any advice I could possibly give. After writing the letter, I thought it may be useful to a few other people out there. So if you are a developer looking to get into design, this is written specifically for you. To preface, this article is not why developers can be good designers. This article does a great job of articulating those ideas. So instead of duplicating good work, I spent time on some ways a developer can get into design. Before I get into the meat of this response, I highly recommend you start your transition in the software design world (e.g., web apps, mobile apps, traditional software, etc.). If that is not the case, I highly recommend you reconsider, at least in the short term. I hold the belief that software design is going to be changing a lot in the next 5 years, and those changes are going to greatly benefit people with development and design skills. I think the future designer is going to look and act a lot more like a design technologist. So dont look at your current position as a disadvantage, view it as a great starting point towards a complementary vocation. I tried to put together a list of tips that would have been helpful to know when I first got started. The design technologist role was still taking shape when I entered the professional sector and a lot of my own progression was from muddling around in the dark. To be honest, I dont think I would change that even if I had the opportunity to do so. So, while I believe these tips could be helpful, there is something to be said about just getting yourself lost with the faith that you will find your way out and learn something in the process. If there is one thing to take away from this email, it is to refrain from mentally separating design and development. When you are creating wireframes, you are implying code that needs to be written. When you are coding, you are actualizing user experiences. To mentally separate each process is the first step towards viewing the creation of software as an assembly-line process. We have a lot of horrendous software due to that line of thinking.

2 of 7

TUTORIALS MAKING THE TRANSITION FROM DEVELOPMENT TO DESIGN

MY LIST OF TIPS Remember, these are tips based on my personal philosophy and things that have shaped my approach. A lot of the thoughts below are opinions that a lot of other designers may disagree with. Thats what makes this topic so interesting. TIP #1: DONT STOP BUILDING THINGS It will not be long before anyone designing software will require an understanding of how to make software. I have been saying this for nearly half a decade and it is finally starting to play out. Developers interested in design do not realize their development background is their greatest asset. Designers will be desperately working to have the skills you already have. It is important to keep your development skills honed. If your goal is to shift your emphasis towards design, your day-to-day development tasks may change but they can still be used. The most obvious area where they can be used productively is prototyping. As interaction design becomes increasingly complex, prototypes will become a greater necessity. Your coding background will allow you to make more sophisticated, accurate and (hopefully) insightful prototypes. Ultimately, the real goal is to see no difference between your development and design skills. The skills gained from each focus are connected, interdependent and equally important towards making good software.

TIP #2: LEARN DESIGN IN ORDER OF DEPENDENCY Trying to tackle the entire universe of design at once will set you up for failure. I highly suggest easing into the process. A great way to do this is to start at what is most vital for software (its function) to what makes it delightful to use (its form). A worthwhile read on this subject can be found here. I decided to modify the authors hierarchy a bit for our case (if youve looked at the diagram from the link provided, the list below starts at the bottom and moves up):

3 of 7

TUTORIALS MAKING THE TRANSITION FROM DEVELOPMENT TO DESIGN

These steps gradate from the rational to the emotional. Learning design by progressing through these steps is optimal for two reasons. The first reason is that each tier is dependent on its predecessorfor instance, learning visual design without a strong understanding of interaction design will lead to poor output. The second reason is that this transition gradually moves you from pure logical, quantitative thinking to more qualitative, aesthetic thinking. The first two steps (design for reliability and design for performance) will probably be areas youre familiar with. However, it is important to understand how much design can impact the reliability and performance of software. Designing for organization is all about information architecture and content hierarchy. Designing for order and structure relates to traditional interface design (which is traditionally represented with wireframes). Designing for interaction, determines the details of how a human being actually uses software (translating a static interface into a rich interactive experience). Designing for aesthetics is obviously visual/motion design. There are ample material for each of these areas which will be easy enough to findthis article is not about detailing every step, its about explaining the progression of learning. There is another step which does not exist on the pyramid, and it is arguably the most important. The last step is to learn to use all the skills concurrently. The end goal is to not treat these facets of design as separate steps, but as variables in a complex equation that is accounted for throughout the entire process. While the hierarchy of design needs will continue in the order illustrated, the aggregate of all skills are used to solve each need. TIP #3: DESIGN EVERYTHING YOU DO During my first internship out of college, Stella Lai gave me this tip and it has been the best professional advice I ever received. Try to practice this tip as literally as possible. The obvious areas are how you dress and how your house/apartment/room is organized. I would suggest not stopping there. Your emails should be written/ composed clearly and beautifully. Your conversations with individuals should be designed through how you listen, how you maintain eye contact, how you respond (both spoken and unspoken). Everything you do should have a reason, no matter how small. Design requires constant practice, this is a great way to keep growing. TIP #4: CARE ABOUT YOUR AUDIENCE

4 of 7

TUTORIALS MAKING THE TRANSITION FROM DEVELOPMENT TO DESIGN

The work you care about will likely turn out better than the work you dont care about. So what happens in the case when you simply cannot get yourself to care? I advise you to put your focus on the people your work will affect as much if not more than the subject of your work itself. If you care about your audience, youll automatically care more about the subject. The opposite is not always the case. The more we put others (the audience) in front of ourselves, the better the results tend to be. TIP #5: TALK ABOUT DESIGN AND LISTEN EVEN MORE Reading is great, but I have learned far more through discussions with experienced, knowledgable and trustworthy people. When you find yourself in such a situation, ask questions and listen. I want to emphasize the importance of truly listening. In the short term, it is important to absorb as much good information as you can while you are in the learning process to challenge your preconceptions and push your thinking. In the long term, it is important because listening will be a vital skill in your practice. The best designers I know are amazing listeners. You will be doing it a lot (with your colleagues, your audience, your clients, etc.), so you should be good at it. TIP #6: LEARN TO WRITE, THEN LEARN TO SPEAK Early in your practice it will be important to absorb ideas to help you form your own philosophies and approaches. However, at some point (preferably earlier than it is comfortable for you), it will be important to start formulating those points of view to an audience. Thoughts kept in your head have the luxury of being biased, irrational or simply flawed. Communicating those thoughts to an audience and opening them up to scrutiny forces us to improve our thinking. Writing well is also essential to practicing design. Ive done some of my best learning through writing on my blog. I would suggest blogging as the first step towards sharing your ideas. In the long term, I suggest trying to speak in front of an audience at least once. Some people love it, others hate it. I have spoken only a half-dozen times or so and I find the process as rewarding as I do terrifying. The skills necessary for successful speaking (e.g., compelling storytelling, brevity, connecting with the audience, etc.) will help you in your daily practice, especially client-facing interactions. Sometimes, communicating the thinking behind your work is as important as the work itself. TIP #7: FOCUS ON DEFINING AND SOLVING PROBLEMS

5 of 7

TUTORIALS MAKING THE TRANSITION FROM DEVELOPMENT TO DESIGN

A lot of the work you see at design showcase websites are great examples of well executed decorations that lack substance. The people that can perform this type of work are countless and the skills highly commoditized. Avoid pixel-pushing at all

costs your job is to solve problems. View your work through that lens at all times. Always know what problems you are trying to solve while in the process of designing (e.g., people are having a hard time knowing where to go next in a flow, or, the current visual design does not reflect the mood of our brand). Good designers solve problems, great ones ensure they are solving the right ones. Accurately defining the problem goes a long way towards solving it. TIP #8: LISTEN TO YOUR GUT, BUT TRUST YOUR BRAIN Trends come and go, but elegant, rational and utilitarian products never go out of style. Its not bad to follow your instincts, but always follow up to understand why you did it in the first place. Because it felt right is a fine way to start a conversation, but not a good way to end one. TIP #9: BE YOUR BIGGEST CRITIC You will never be perfect, but that shouldnt stop you from trying. There are always areas to grow. Your work and your practice always can (and should) be improved. When in doubt lean towards being too hard on yourself rather than too easy. TIP #10: LEARN FROM THE TIME-TESTEDAND EMULATE IT
6 of 7

TUTORIALS MAKING THE TRANSITION FROM DEVELOPMENT TO DESIGN

Few things prove a designs success better than how long it remains relevant. Look to the timeless to guide your approach. This need not be limited to software, the thinking behind designing a great chair often parallels the thinking behind designing great software. Understand how others before you have solved similar problems and try to determine why it took the shape it did. Value precedence; it carries considerable weight. Blindly echoing design trends is a great way to have a dated portfolio in a couple years. Focusing on digital influences to follow, the operating system is one of the most time-tested and finely tuned pieces of software in existence. Explore the nuances, understand the patterns and know them like the back of your hand. When do you use a drop down as opposed to radio boxes? Why? There are smart reasons behind most of these details and they are worthwhile to know. TIP #11: IDEATE ROMANTICALLY, CREATE PRAGMATICALLY Our ideas should be bigger than reality, but our execution should be married to it. This allows us to see the grand future of a product while ensuring that it can exist to have any future at all. Both are important, but they can be detrimental if out of balance or practiced at the wrong times. The design world is in a phase of rapid change. Designers who understand and can work with code are becoming the prototype. Your transition is not going to happen overnight and a lot of your thinking will need to bend. However, I think you will be surprised by how much of your thinking will not. A lot of your shift is about understanding that you have already been creatively solving problems as a developer, and that a lot of that thinking is universal.

P.J. Onori
Design Technologist

HIS BLOG

SHARE

TWITTER

GITHUB

appliness

THOUGHT DESIGN

BOOKMARK / SHARE / TOC

Design is not Veneer.


by Aral Balkan

THOUGHT DESIGN IS NOT VENEER

by Aral Balkan
GETTING STARTED

Let me tell you what design is not, it is not a silver sixpence

This is a response to the article How to make your site look halfdecent in half an hour by Anna PowellSmith on 24 ways. I apologised for the way I reacted to the article on Twitter in a previous note. I also mentioned in my apology that I would detail my reasons for finding the article harmful in a future note. This is that note. And I write it in hopes that it will constitute constructive discourse. The title of the article How To Make Your Site Look HalfDecent in Half an Hour is itself enough to set the blood of any designer boiling as it perpetuates an already prevalent and harmful myth: that you can simply sprinkle design on top of an otherwise completed site like some sort of magic ingredient. In fact, the articles summary makes just that very case: Anna Powell-Smith stirs the silver sixpence of design into the Christmas pudding of web development Impress your friends with your quick design fixes. What is a silver sixpence, you ask? Good question. Heres the lowdown, according to the Royal Mint: In the past, everyone in the household would give the Christmas pudding mixture a stir and make a wish, and the cook would include a silver sixpence in the mix. Tradition had it that whoever found the sixpence would have good luck in the year ahead. Now, let me tell you what design is not: it is not a silver sixpence. And its not something you add to your site in half an hour. There are no quick design fixes. Design is not veneer. Design is not synonymous with aesthetics, although aesthetics are a component of design. In the words of Steve Jobs, Design is not just what it looks like and feels like. Design is how it works. In response to my initial tweets, several people stated that I was simply not the target audience for the article. I feel that this argument misses a critical point: the article in question is most harmful to its stated target audience programmers intimidated by visual design as it can lull them into a false sense of security (if you use these shortcuts you can make your personal programming projects look professional, quickly). The intended target audience is the one likely to be tempted most by silver bullet recipes
2 of 8

THOUGHT DESIGN IS NOT VENEER

without realising that they are being given fish, instead of being taught how to fish. So its true that I am not the intended target audience for the article, however, unlike the intended target audience, I am in a position to see the article for what it is: a wellintentioned attempt at providing pragmatic advice that nonetheless ends up perpetuating harmful myths. The article, in summary, serves up design as a series of ingredients that you can simply add to your projects without thinking about why youre adding them or the people who will be using your product. Want to add design to your site? Drop in a grid framework, add a few sweet fonts, embellish using colours, textures, icons, and a background image, and voil, you have a beautiful website. In the articles defence, Anna does state that you will get better results by working with a professional designer, and by studying design more deeply. However, the rest of the article builds upon the assumption that programmers and designers are separate species and that design for the programmer is, at best, a distraction that she should get out of the way as quickly as possible using a set of hacks so that she can focus on writing code.

I am a programmer. I am not a designer.


This statement, meant to empathise with a target audience of developers, is exactly the myth that we need to stop perpetuating. If you are a programmer, the work that you do contributes directly to the experience that the people using your

3 of 8

THOUGHT DESIGN IS NOT VENEER

product will have. Whether you know it or not, you are a designer. Whether you know it or not, the work you do affects the design of the site or application you are building. If you are aware of this fact, you can make a conscious effort to affect the design in line with the needs of your users. If you are not aware of it, you will still be impacting the design of the product, however you will be doing so without realising it and without thinking about the people who will ultimately be using your product.

The way a thing looks is not veneer layered on top of its functionality.

None of us are born designers. It is not a talent. It has very little to do with being able to draw well or make things look pretty (we are talking about design here, not illustration). The way something looks is not veneer layered on top of its functionality. The two are inextricably linked. The way a thing looks creates inherent expectations about how it is meant to be used. This is called an affordance. If your site or app has intuitive affordances that is, if it satisfies with its behaviour the expectations that it creates with its appearance it will go a long way towards providing a usable experience. But even this level of basic functionality what we call usable takes lots of thought, effort, iteration, and testing to achieve. It also requires vision. Good design rarely happens without intent sustained, focused intent what we call vision. If you dont see yourself as a designer, youve already lost. For it is the designer who thinks about the user, tries to understand the user, and creates things that empower, amuse, and delight the user. And responsibility for design falls within the remit of every member of a team regardless of the specialised role that they may be tasked with on their current project or within their current institution. Only such teams, supported by an organisational structure that is designled from the topdown, can hope to create beautifully designed products.

In attempting to find shortcuts to design, it sidesteps design altogether; replacing it with a shallow simulacrum

Design is everyones responsibility. You are a designer whether you are aware of it or not. If youre not aware of it, chances are that you are not a particularly good designer. Because good design doesnt just happen. And there is no five minute guide or quick fix that can help you. Sure, you can learn how to put lipstick on a
4 of 8

THOUGHT DESIGN IS NOT VENEER

pig, but itll still be a pig. Not that I have anything against pigs but you get the idea. THE RIGHT MOTIVATIONS The problem with Annas article is not that it recommends bad tools or materials to use but that it suggests using said tools and materials for entirely the wrong reasons. Bootstrap may very well be a great tool for prototyping, for example, but it no more democratises the whole process of web design than iMovie democratises the process of making feature films because it comes with premade templates. In other words, simply adding a grid framework to your site guarantees a usable experience about as much as using iMovie guarantees a Hollywood blockbuster. Similarly, web fonts are not one of the quickest ways to make your site look distinctive, modern, and less Bootstrappy. They are your voice in the land of the written word and there is much more to good typography than your choice of fonts. Typography is concerned with the art of laying out type, not just choosing fonts. Again, there is nothing wrong with providing a list of type foundries, its always good to have links to useful resources. But adding some sweet fonts to your site is not going to make it read any better unless youre also considering the measure (line length), line height, and rhythm of your treatment. And were not even talking about taking into consideration the differences in browser engines that render certain typefaces unreadable on certain platforms. At the very least, you should be asking why? Why this font? What is the feeling Im trying to convey? Is this text meant to be serious, fun, exciting, solemn, scary? Whats the voice Im trying to achieve? And for whom? Who is my audience? Whom am I designing for? Design is as much about asking the right questions as it is about answering them. It is about worrying about the right thing: solving your users problems not your own problems. And thats the great shortcoming of this article: it doesnt consider the motivations or reasons for using the tools and materials that it suggests. It doesnt consider the users problems but focuses on alleviating your own problems
5 of 8

THOUGHT DESIGN IS NOT VENEER

as a developer. In attempting to find shortcuts to design, it sidesteps design altogether; replacing it with a shallow simulacrum a simple mimicry devoid of vision, purpose, and meaning. This is perhaps best demonstrated in the section that shows you how to add an icon to a signin button: Finally, well add a truck icon to the main action button, as follows. Why a truck? Why not? Why not, indeed? Does it matter that a truck icon makes no sense whatsover on a signin button? It does not if all you are concerned with is adding meaningless decoration to your site. As an element without purpose, it simply adds to the noise in your interface. At best, it adds to the burden of the users cognitive load and, at worst, it might confuse her about the function of the button by muddying its intent. Design is not about spraying your site with a little visual je ne sais quoi like a drunkard pissing in an alleyway. PURPOSE IN DESIGN Having read through Annas article several times now, and each time with an eye to find someanysaving grace that I could use to temper my response, I can safely say that you can start on the journey to improve your sites by doing exactly the opposite of what is suggested in the article. Do not simply add a grid system, web fonts, textures, icons, fancy CSS3, a background image, and colour to your site without thinking long and hard about why youre adding each one of those things and how they will influence the experience of your users. Your design will be better off for not having those elements rather than having them thoughtlessly dumped in like so much junk in a landfill. Every element you add to your design is a potential bit of extra cognitive load. And every element you add will influence and be influenced by every other element in your site. Every change you make will have cascade effects on the rest of the experience. Every element you add is thus another bit of potential confusion, another speck of potential noise. Design is as much about knowing what not to add to your product in the first place as it is about knowing what to remove. That is not to say that we never add things. Of course, we do. But never without thought. Never without a process whereby everything we add goes through a trial by fire to earn its right to exist. Design is much more about saying no than it is about saying

6 of 8

THOUGHT DESIGN IS NOT VENEER

yes. Even when its painful. Especially when its painful. As Antoine de SaintExupry says in The Little Prince: Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. At the very least, do not add anything to your design without good reason. And the only good reason is if it adds more value to the user experience than it removes. And so you must constantly be thinking of the user. Every element you add to a design must have a purpose. The purpose may be purely emotive. This is fine. We are, after all, emotional, irrational, unpredictable creatures. But it must have purpose. And that purpose must be a valuable one. Remember, every element you add either contributes to your product being more useful and easier to understand or makes it less useful and more confusing. You should no more be adding visual elements willy nilly to your sites than you should be adding code snippets and components without at least understanding their motivations, purpose, and effects. SO WHATS A DEVELOPER TO DO? Instead of adding elements to your site just because you can, devote that time to learning about design. No one is born a good designer. Its true that you need empathy but I strongly believe that unless you are, by nature, a psychopath you can cultivate empathy even if you are not, by nurture, empathetic. There are many design devices and games that can help you focus on the needs of the user. So, learn design. Instead of learning Bootstrap to use as a magic bullet, for example, read a book on typography or take a typography class. When youre done, you wont need web fonts to create a pleasing and readable typographical treatment. And, if you decide to use a web font or two, you will use them for the right reasons: because you have made a conscious decision to control the voice of your content. The same goes for the use of textures, colours, icons, background images, fancy CSS effects, etc. Without purpose, they are hollow, meaningless ornaments at best and confusing noise at worst. There are no shortcuts to good design. There are no silver bullets, no magic buttons, no silver sixpences. Every design problem is unique. Design is a process, not a product. And you cannot take part in the process by ignoring the irrational,
7 of 8

THOUGHT DESIGN IS NOT VENEER

emotional, unpredictable beings who will be using your products. However much you may want to. However scary it may be to think of them. Quite on the contrary, you must base your process around them. Around understanding and fulfilling their needs. Because their needs are all that matter. Indirectly, their needs are your needs and your businesss needs. Because we are living in the age of user experience, where features are commodities and user experience is the differentiating factor. Yes, its scary. Yes, its complicated. Yes, it can get messy. Unlike in code, there are maybes lots of them. We live in a world of gradients. But it doesnt mean that we get to ignore the scary, complicated, and messy bits or sidestep thinking about them by using a bunch of meaningless, shallow, and ultimately harmful shortcuts and quick fixes. Not if we want to create meaningful and authentic experiences for the people who use our products. Because design is not veneer. P.S. To further understand why I care so deeply about design, and why I feel you should too, please read This Is All There Is and watch the talk I gave last month called A Happy Grain of Sand.

Aral Balkan
Experience Designer

HIS BLOG

SHARE

TWITTER

GITHUB

appliness

NEWS BY BRIAN RINALDI

BOOKMARK / SHARE / TOC

Five things you can do to make HTML5 perform better by Christian Heilmann

Instant Form Validation by James Edwards

Basic Canvas Animation Using JavaScript by Sandeep Panda

What is SVG?

by Johnny Simpson

Blending features in Canvas by Rik Cabanier

Backbone. Tasks by Alex Young

jQuery Mobile 1.3.0 by Aurelio de Rosa PhoneGap Build API for Node.js by Michael Brooks Source Maps by Sayanee Basu

CSS Clip Property by Hugo Giraudel

appliness

MORE NEWS ON HTTP://REMOTESYNTHESIS.COM/

appliness

EOF FOLLOW US

BOOKMARK / SHARE / TOC

Now what?
N
SUBSCRIBE TO OUR MONTHLY NEWSLETTER

FOLLOW US ON TWITTER

JOIN US ON FACEBOOK

visit appliness.com

Das könnte Ihnen auch gefallen