130

Appliness #10 – January 2012

Embed Size (px)

Citation preview

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 1/130

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 2/130

appliness JANUARY 2013 TABLE OF CONTENTS BOOKMARK / SHARE / TO

Best Practices whenworking with JavaScript

templatesby Andrew Burgess

Hello AngularJSby

Glenn Gervais

GoogleMaps

CustomMarkersby Ray

Camden

Geo 

pushednotifications

by Holly

Schinsky

Developing aPhoneGap Application

by ChristopheCoenraets

Gruntbuild tool

byFrederic

Hemberger

PhoneGap &Force.com

by PiotrWalczyszyn

Interviewof

DENISE

JACOBS

Arraysin JS

by Dr.AxelRauschmayer

CSS Nextby

Divya Manian

appliness

CSS Things that don’toccupy space

byLouis Lazaris

CSSCalcby 

DavidWalsh

Bubblingin Enyo 2

byDavidPosin

About webstandards byMihai Corlan

NEWSby 

Brian Rinaldi

HistoryMgtby

RAY 

CAMDEN

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 3/130

appliness JANUARY 2013 TABLE OF CONTENTS BOOKMARK / SHARE / TO

Best Practices whenworking with JavaScript

templatesby Andrew Burgess

Hello AngularJSby

Glenn Gervais

GoogleMaps

CustomMarkers

by RayCamden

Geo 

pushednotifications

by HollySchinsky

Developing aPhoneGap Application

by ChristopheCoenraets

Gruntbuild tool

byFrederic

Hemberger

PhoneGap &Force.com

by Piotr

Walczyszyn

Interviewof

DENISE

JACOBS

Arrays

in JSby Dr.Axel

Rauschmayer

CSS Nextby

Divya ManianCSS Things that don’t

occupy spaceby

Louis Lazaris

CSSCalcby 

DavidWalsh

Bubblingin Enyo 2

by

DavidPosin

About webstandards by NEWS

HistoryMgt

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 4/130

appliness TUTORIALS JAVASCRIPT BOOKMARK / SHARE / TO

Best PracticesWhen WorkingWith JavaScriptTemplates.

by Andrew Burgess

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 5/130

UTORIALS BEST PRACTICES WHEN WORKING WITH JAVASCRIPT TEMPLATES

by AndrewBurgess

2 of 8 

Maybe you don’t need them for simple web apps, but it doesn’t take too muchcomplexity before embracing JavaScript templates becomes a good decision. Like anyother tool or technique, there are a few best practices that you should keep in mind,when using templates. We’ll take a look at a handful of these practices in this tutorial.

First things first: unless you’re John Resig, you most likely want to choose a well-testedlibrary to offer your template functionality. While the options are nearly endless, thereare two really good options, depending on the complexity of your project.

If the project is relatively simple, you can use Underscore.js. For the most part, this libraryoffers functional programming utilities, but it does have a _.template method thatcouldn’t make things easier. By default, it uses the ERB-esque <%= %> delimiters, butthat can easily be modified. The beauty of this solution is that any project that requirestemplates will likely have Underscore loaded already, simply due to its sheer general

usefulness. To learn more about Underscore, check out Siddharth’s comprehensivetutorial right here on Nettuts+.

If you need something with a bit more zest, might I recommend Handlebars? With manyuseful block expressions (such as #each for looping and #if for conditionals) and theability to register your own helper functions, Handlebars will give you everything youneed to create even the most complex of templates.

Of course, there are other template libraries out there; feel free to check them out! I

only recommend these two because I enjoy and use them myself. They also tend to bethe most popular offerings in the community.

There will be times, when the data that you are inserting into a template won’t quitebe formatted in the way you prefer. In these situations, you’ll need to create customfunctions to format it. If you’re using something like Handlebars, you can easily registera helper function; but other solutions, like Underscore, don’t offer that functionality.

UNDERSCORE FOR SIMPLE, HANDLEBARS FOR COMPLEX

CREATE TEMPLATE HELPER FUNCTIONS

“If you need somethingwith a bit more zest, might

recommend Handlebars?”

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 6/130

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 7/130

4 of 8 

The first alternative is to store them all within a JavaScript file. Of course, thismeans that your templates will be stored as strings instead of the more readableindented HTML, but stick with me for a second! First, for templates that are longerthan a single line (most templates), you don’t have to use an unwieldy, wrapping

string. Instead, try something like this:

Templates = {};Templates.contactEntry = [  “<h1> {{fullName}} </h1>”,  “<ul>”,  “<li> Email: {{email}} </li>”,  “<li> Phone: {{tel}} </li>”,  “</ul>”].join(“\n”);

Storing a template in an array like this makes it much easier to handle. Using syntaxlike this, you can easily store all your templates in their own JavaScript file, andhave that file loaded onto the page before you need the templates. And of course,you don’t have to keep them all within a single Template object, but it keepsthings organized. That Templates object could even be a property on your globalapplication object (as in, MyApp.Templates).

But wait, there’s more (to coin a phrase). You can convert all of your templates to

their respective template functions in a single loop:

for (var tmpl in Templates) {  if (Templates.hasOwnProperty(tmpl) {  Templates[t] = _.template(Templates[t]); // Underscore example  }}

If you’re using AMD in your application, this method will still work; just put thatin a templates module that returns that Templates object. However, many AMD

solutions have a text plugin that lets you load plain text files; instead of the normalmodule object, you’ll get a string in return. If you’re using the RequireJS library,you’ll have to include the text.js plugin in the same directory as the require.js file. Then, you can do something along the lines of:

require([“text!templates/document.html”], function (documentTemplate) {});

That documentTemplate parameter will be a string containing whatever contents

UTORIALS BEST PRACTICES WHEN WORKING WITH JAVASCRIPT TEMPLATES

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 8/130

5 of 8 

is in that templates/document.html file. When doing it this way, you won’t be ableto put multiple templates into one file, unless you want to manipulate that string.

If you think about it for a second, there’s some extra work done by the browserevery time you create a template. Usually, that template starts out as a string thatyou pass to a template-creating function. That function returns another function,which you can pass the data to and receive HTML from. The extra work is the“creating-the-template-function” part; there’s no reason why this can’t be donebefore the JavaScript is sent to the client. Preferably, you could put add this workto your build process, along with minifying your CSS and concatenating your JS.

Unfortunately, pre-compiling JavaScript templates isn’t quite as simple as minifying

or concatenating… at least, not just yet, probably due to the many ways to createtemplates. If you’re using Grunt or Yeoman, you can look up plugins (like this one)on the Grunt website. If you’re using the Asset Pipeline in a Rails app, you can takeadvantage of Sprockets to pre-compile your template functions.

PRECOMPILE YOUR TEMPLATES

UTORIALS BEST PRACTICES WHEN WORKING WITH JAVASCRIPT TEMPLATES

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 9/130

6 of 8 

Not too long ago, while researching for another project, I came across an interestingidea regarding JavaScript templates in the excellent book Recipes with Backbone.It’s since become a best practice in the community: no evaluation in templates.

Of course, interpolating variables is, strictly speaking, evaluation, but what I’mmore referring to here is logic code. You can put whatever JavaScript you’d likeinside of the delimiting tags, but it can easily get out of hand. We all know that it’sconsidered a best practice to keep your HTML, CSS, and JavaScript separate; thismakes it easier to keep track of the code and spot errors, when necessary. Thesame is true for templates: they should be a place for interpolating values only.Any logic or data transformation should be performed outside the template.

Of course, how far you go with this idea is up to you. You might decide that looping

inside your templates is okay; you might have a template like this:

<h1> My List </h1><ul id=”myList”>  <% list.forEach(function (item) { %>  <li> <%= item.name %> </li>  <% }); %></ul>

Or, you might instead choose to loop outside your templates by creating a wrappertemplate, and then looping over items, rendering a sub-templates, and insertingthem into the wrapper template.

 You might end up with two templates like this:

The wrapper template:

<h1> My List </h1><ul id=”myList”>

</ul>

The sub-template:

<li> <%= name %> </li>

Of course, this separated method makes for a bit more code, but you’ll find itworth the effort in the long run.

NO EVALUATION IN TEMPLATES

UTORIALS BEST PRACTICES WHEN WORKING WITH JAVASCRIPT TEMPLATES

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 10/130

7 of 8 

Along these lines, it’s a good practice follow the lead of the framework or libraryyou’re using. For example, I’ve found that, when using Backbone with Underscoretemplates, it is easier to use outside loops and sub-templates: Underscore’sminimal template functionality doesn’t offer any looping syntax, and Backbone’srender method is a great place to do that looping and inserting the sub-templates.

However, when using Meteor, which builds in Handlebars templates, it’s mucheasier to loop inside the templates with an #each block; (and use sub-templates,too, if you want).

This won’t always be applicable, but, in some cases, it can be really helpful to makeyour templates update automatically, when the data they are displaying changes. Ilike this idea a lot, because it allows even the UI of your application to be completely

data-driven: when a model attribute updates, the UI updates with it. This is thebasic principle behind tools, like Knockout.

While you could probably roll this functionality on your own without too muchtrouble, all the popular frameworks have it built in. For example, in Backbone, atemplate’s initialize function might include some custom event listeners, likeso:

this.model.on(‘change’, this.render, this);

This way, whenever a model attribute changes, the template’s render function willbe called and the template re-rendered. Alternatively, you can use a plugin, likebackbone.stickit, which will manage the bindings for you. If you’re working withMeteor and using one of its reactive data sources, you’ll get this binding for free– no extra work necessary. I’m not familiar enough with any other framework toknow exactly how they do it, but any framework worth using should have a similarfeature.

If you aren’t careful, very quickly, your templates can get out of hand and becomeunwieldy. This is why it’s always a good idea to limit your templates to a reasonablesize. If you make them too large, they’ll be more difficult to update, and won’t allowfor a good separation of the code. On the other hand, if they’re too small, they’llcost too much for what they bring, and will subsequently slow down your app.

BIND DATA TO THE TEMPLATES

SIMPLIFY YOUR TEMPLATES

UTORIALS BEST PRACTICES WHEN WORKING WITH JAVASCRIPT TEMPLATES

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 11/130

This is why it’s important to find a happy medium. Approach your templates in thesame way that you write your JavaScript or CSS code: make it modular. Yes, eachUI “chunk” or widget should have it’s own template, but don’t forget about sub-templates. They’re useful, when smaller units of a widget have complex layouts or

states, as well as when they have multiple events, but remember that they can bea double-edged sword. Don’t use them unless you have a good reason to.

Finally, remember that JavaScript templates is just one more tool in your box; and,sometimes, it simply isn’t the right one for the job. Don’t use templates where youdon’t need them. Use your head: there may be other situations, when a templateis not the best tool.

DON’T USE ‘EM IF YOU DON’T NEED ‘EM

Andrew BurgessCanadian Web Developer

HIS BLOG

TWITTER

SHARE

GITHUB

More tutorials on:

UTORIALS BEST PRACTICES WHEN WORKING WITH JAVASCRIPT TEMPLATES

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 12/130

appliness TUTORIALS JAVASCRIPT BOOKMARK / SHARE / TO

Arrays in JavaScript

by Dr. AxelRauschmayer

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 13/130

UTORIALS ARRAYS IN JAVASCRIPT

by Dr AxelRauschmayer

2 of 9 

Remember that objects in JavaScript are maps from strings to values. Arrays are objects,only a few property keys are special:

Array indices: If a key is a string holding a non-negative integer below a certainmaximum then it is treated as an array index.

“length”: The value of this property is a non-negative integer holding the length of

an array. That length is defined as the numerically largest array index, converted tointeger, plus one.

This is somewhat shocking, especially when you are coming from another language:array indices in JavaScript are actually strings. Naturally, engines perform optimizationsunder the hood so that, internally, that is not true. But it is how the spec defines themand how the programmer sees them. For example:

> var arr = [‘a’, ‘b’, ‘c’];

> arr[‘0’]‘a’> arr[0]‘a’

Because 0 is not an identifier, the dot notation (arr.0) is a syntax error. Hence, youhave to resort to square brackets. The square brackets operator converts its operandto string, which is why arr[0] works, above. Array indices are (roughly) limited to32 bit. Similarly to the square brackets operator, the in operator also converts its firstoperand to string. Which is why it can be used with numbers to check whether or not

there is an array element at a given index:

> 2 in [ ‘a’, ‘b’, ‘c’ ]true> 3 in [ ‘a’, ‘b’, ‘c’ ]false

The following sections go into more detail about how arrays work.

OVERVIEW

“They are much more likeobjects than you migh

think.”

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 14/130

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 15/130

UTORIALS ARRAYS IN JAVASCRIPT

4 of 9 

There are three ways of invoking the Array constructor:

new Array(): creates a new empty array. The empty array literal [] is a more

concise way of doing the same thing.

new Array(len): creates an array with len holes. On some JavaScript engines,this operation lets you pre-allocate arrays, giving you performance benefits forsmall arrays (not for large ones). In most cases, performance doesn’t matterand you can avoid the redundancy introduced by a preallocation. If it fits theproblem, an array literal initializing all elements at once is preferable.

new Array(elem1, elem2, ...): creates an array whose elements are elem1, elem2

etc. This variant of the constructor is never a good choice, because if you use itfor a single element that is a number, the variant #2 is invoked. To avoid this bug,use the array literal [ elem1, elem2, ...] which does everything this constructorvariant does.

If you call Array as a function (without new) then the effect is the same as callingit as a constructor.

(As an aside, because there are not many use cases for this: JavaScript therefore doesnot have a built-in function for reliably creating arrays from elements. ECMAScript6 will have Array.of() which rectifies this situation.)

The ECMAScript specification has a very narrow definition for what property keysare considered array indices. A string s is an array index if and only if:

s, parsed as an unsigned 32 bit integer and converted to string is equal to s.

s, converted to integer, is smaller than 232−1 (the maximum length).

Thus, if compared numerically, an array index s must be within the range

0 ≤ s < 232−1

ToUint32, the conversion to an unsigned 32 bit integer, is a spec-internal operation.

ARRAYS WITH HOLES

ARRAY INDICES

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 16/130

UTORIALS ARRAYS IN JAVASCRIPT

5 of 9 

 You can implement it in JavaScript as follows:

  function ToUint32(x) {  return x >>> 0;  }

ToUint32 is very tolerant. However, condition (1), above, means that while manystrings can be converted to an unsigned 32 bit integer, only a few of them are validarray indices. Examples:

  > ToUint32(‘0’)  0  > ToUint32(‘00’)  0  > ToUint32(‘03’)

  3  > ToUint32(‘abc’)  0  > ToUint32(Math.pow(2,32)+3)  3

Only the first example fulfills condition (1) and is a valid array index. All non-arrayindices are treated like normal properties:

  > var arr = [‘a’, ‘b’, ‘c’];

  > arr[‘0’]  ‘a’  > arr[‘00’]  undefined

The property length of arrays is always an integer value l in the range

0 ≤ l ≤ 232−1 (32 bit)

1. Tracking indices 

As new elements are added, the length increases automatically:

  > var arr = [];  > arr.length  0  > arr[0] = ‘a’;

LENGTH

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 17/130

UTORIALS ARRAYS IN JAVASCRIPT

6 of 9 

  > arr.length  1

2. Decreasing the length

if an existing length l is replaced with a newer value l’ that is smaller, then all arrayelements are removed whose indices i are in the range

l’ ≤ i < l

For example:

  > var arr = [ ‘a’, ‘b’, ‘c’ ];  > arr.length

  3  > 2 in arr  true  > arr.length = 2;  2  > 2 in arr  false

3. Increasing the length

Setting the length to values larger than the current length creates holes:

  > var arr = [‘a’];  > arr.length = 3;  > arr  [ ‘a’, , ,]

4. Legal values for length

 You can assign any value to length, but converting it to a number via ToUint32 andconverting it to number must yield the same result. Examples:

  > ToUint32(‘0’) //*  0  > ToUint32(‘000’) //*  0  > ToUint32(‘-1’)  4294967295  > ToUint32(Math.pow(2,32)-1) //*

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 18/130

UTORIALS ARRAYS IN JAVASCRIPT

7 of 9 

  4294967295  > ToUint32(Math.pow(2,32))  0  > ToUint32(‘abc’)  0

Hence, all values marked with an asterisk are legal lengths, the remaining valuesaren’t:

  > Number(‘0’)  0  > Number(‘000’)  0  > Number(‘-1’)  -1  > Number(Math.pow(2,32)-1)

  4294967295  > Number(Math.pow(2,32))  4294967296  > Number(‘abc’)  NaN

 You can easily test this:

  > [].length = -1  RangeError: Invalid array length

  > [].length = Math.pow(2,32)  RangeError: Invalid array length  > [].length = ‘abc’  RangeError: Invalid array length

Instances of Array are like normal objects, except for one difference: If you define 

a property, two cases are handled differently:

Array indices: increase length, if necessary.

“length”: throw an error for illegal values, possibly remove elements if the newvalue is smaller than the previous one.

All other property keys are handled the same as for normal objects. Note thatproperty definition is also used by the assignment operator (it calls the internal

ARRAY INSTANCES

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 19/130

UTORIALS ARRAYS IN JAVASCRIPT

8 of 9

[[Put]] method which in turn calls [[DefineOwnProperty]] – if there isn’t a settervisible in the prototype chain).The above means that it is impossible to create a subtype of Array using standardECMAScript 5. “Subtyping JavaScript built-ins” has details.

What happens if you use an array index that is not within the allowed range? Thenit is treated like a normal property key. If you use such an index to add to an array,your addition is not considered an array element. For example, let’s use an indexthat is too big.

  > var arr = [‘a’, ‘b’];  > arr[Math.pow(2,32)-1] = ‘c’;  > arr  [ ‘a’, ‘b’ ]  > arr.length  2  > arr[Math.pow(2,32)-1]

BEYOND THE LIMITS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 20/130

UTORIALS ARRAYS IN JAVASCRIPT

  ‘c’

 You do get an error if you try to grow the length beyond the allowed maximum:

  > var arr = new Array(Math.pow(2,32)-1) // max length

  > arr.push(‘x’)  RangeError: Invalid array length

Recommendations when working with arrays:

- Pretend array indices are numbers. That’s what usually happens under the

hood and the general direction in which ECMAScript is moving.

- Avoid the Array constructor.

- Use array literals whenever you can.

- Don’t be clever with regard to arrays. If you follow standard patterns, enginesusually figure out what you are trying to do and optimize accordingly. The article“Performance Tips for JavaScript in V8” (by Chris Wilson) contains several

interesting array-related suggestions.

RECOMMENDATIONS

Dr. Axel Rauschmayer

Consultant & Trainer for JS

HIS BLOG

TWITTER

SHARE

GITHUB

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 21/130

appliness TUTORIALS JAVASCRIPT BOOKMARK / SHARE / TO

Hello AngularJS

by GlennGervais

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 22/130

UTORIALS HELLO ANGULARJS

by GlennGervais

2 of 6 

Being a Flex developer who really loves his work, it still pisses me off that Adobeessentially buried Flash alive last year. That being said, when you make a living codingyou have to keep up with the times. Enter AngularJS, Google’s js solution for buildingyour own application framework. Extensible, dynamic, and pretty damned slick.

‘Hello Whatever’ is usually the first step in the learning experience, however theAngularJS team has a good example of this on their site. I’ll take it a quarter-step

further in the hopes of providing something a little more unique.

I created a simple AngularJS app that will add two numbers together as they arechanged. This demonstrates AngularJS’s binding between the form and the model.The AngularJS ‘Hello World’ example is actually included in the form of ‘Your opinionof angular’:

HTML CODE

<!doctype html><!-- Simple introductory level example of angular.js by Glenn Gervais --><!-- Referenced by http://rabidgadfly.com/2012/11/hello-angularjs/ -->

<!-- Define this as an AngularJS app --><html ng-app> <head>

  <!-- Don’t forget to load angularjs! -->  <script src=”http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js”>

  </script> 

<!-- Our application/controller definition -->  <script src=”app.js”></script>  </head> <body>

  <!-- Tell the app to use the Ctrl scope defined in our app.js -->  <div ng-controller=”Ctrl”> 

HELLO WORLD

“Extensible, dynamic, andpretty damned slick.”

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 23/130

  <!-- Note the ng-model assignment. It’s bound to the scope variable definedin app.js. -->  Your opinion of AngularJS: <input name=”angular-description”ng-model=”angularDescription” ng-placeholder=”Your opinion of Angular here” >  <hr>  <!-- Note that we are outputting the value of angularDescription here. It’s

  bound to the scope variable so it updates automatically -->  <p>AngularJS <span style=”color:red;”>{{angularDescription}}</span>!</p> 

<!-- Simple adding machine -->  <p>Enter numbers in the input boxes:</p>  <input name=”top-number” ng-model=”topNumber” ng-placeholder=”EnterNumber” />  +  <input name=”bot-number” ng-model=”botNumber” ng-placeholder=”EnterNumber” />  =

  <!-- Not elegant but multiplying the values by one in the braces belowmakes them evaluate as numbers instead of strings. Without it we would end up  with concatenation instead of addition -->  <span style=”color:red;”>{{topNumber*1 + botNumber*1}}</span>  </div>

  </body></html>

  <div data-role=”header” data-position=”fixed”>

  <h1>Welcome</h1>  </div><!-- /header -->

  <div data-role=”content”><div id=”formLogin”>

<script type=”text/javascript”>

JAVASCRIPT CODE

/* (Very) simple controller that sets scope variables we* will bind to.*/function Ctrl($scope) {  $scope.angularDescription = “Rocks”;  $scope.topNumber = 0;  $scope.botNumber = 0;}

3 of 6 

UTORIALS HELLO ANGULARJS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 24/130

THE RESULT

Much of the magic is done with the ng-model directive which binds the view to themodel using scope variables.

In my first section I created an extremely simple app that added 2 values together.In this post I take that app a few steps further by creating a simple calculator.

This app demonstrates how to call scoped functions using button clicks, and howscoped variables can work together in an application.

RUNNING SAMPLE (you can also access the code of the HTML, CSS and JS files):

ANGULARJS SIMPLE CALCULATOR

4 of 6 

UTORIALS HELLO ANGULARJS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 25/130

Admittedly, the ‘simple’ calculator ended up being a little trickier than I thought atfirst. There are several ‘gotchas’ that tripped me up along the way. Some examples:

- There are special rules for the first number entered while the display outputreads “0”. First, you don’t want to concatenate onto the 0. Second, if you entera first number and then click the “add” button, no calculation should take place.This is especially important when subtracting where we would end up with -5if “5 -” was entered. This is the reason the newNumber boolean variable isnecessary.

- When the “equals” button is clicked the first time it should add all of the numberthat have been inputted together. The second and subsequent times it is clicked(before any new values are entered) it should repeat the last calculation. Forexample, if “8 + 2 =” is entered, 10 will be the answer. If the equals button isimmediately clicked again, it should add 2 to the result and output 12. It should

5 of 6 

UTORIALS HELLO ANGULARJS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 26/130

continue adding 2 until a new value is inputted. This is the main reason for thependingOperation and lastOperation variables.- The “add” and “subtract” buttons should only perform functionality when avalue is pending. For example, “8 + 2 +++++++” should still result in a value of10. This is unlike equals where the last action should be repeated (8 + 2 =====

equals 18).- The add button should subtract, and vice versa, when a previous subtractoperation is active. In other words entering “8 + 2 -” should result in 10 beingdisplayed in the output as soon as the subtract button is clicked.

So, the simple calculator ended up being more of a challenge than I expected.That being said, I built the app to learn about AngularJS and demonstrate itsfunctionality, not to reconcile my checking account.

I’ll continue my series of articles about AngularJS in the next issue of Appliness.Waiting for this, you can read my blog: http://rabidgadfly.com/

Glenn GervaisWeb Developer at LexiaLearning

HIS BLOG

TWITTER

SHARE

GITHUB

UTORIALS HELLO ANGULARJS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 27/130

appliness TUTORIALS JAVASCRIPT BOOKMARK / SHARE / TO

Google Maps demoCustom Markers

by RaymondCamden

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 28/130

UTORIALS GOOGLE MAPS CUSTOM MARKERS

by RaymondCamden

2 of 5 

This isn’t anything special, but a reader today asked if I could modify some code I didfor an earlier blog post: Simple introduction to Google Maps - Part 2 - Markers. Thiswas a blog post I had done as part of a series introducing folks to using the GoogleMaps SDK. While partially focused on ColdFusion (and replacing <cfmap>), it wasapplicable to anyone who wanted to try out the SDK on their web site.

The final demo in that blog post (available here) showed how to add dynamic markers

to a map and provided a simple UI to select and focus on each marker.

My reader had two main questions. First, he wanted to know how to customize themarker. Second, he wanted to build in a basic filtering system based on a type ofcontent. He was building a map of medical related locations and he wanted to be ableto filter by pharmacies or hospitals. I whipped up a demo of both of these conceptsand I thought folks might like to see the code.

GETTING STARTED

“This is really anincredibly trivial thing

to do.”

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 29/130

Let’s begin by talking about custom markers. This is really an incredibly trivial thingto do. While you have a few different options for customizing the marker, thesimplest way to do so is to point to a URL. So given this code to create a marker:

var marker = new google.maps.Marker({

  map: map,position: results[0].geometry.location,  title: “92nd Street Pharmacy”});

 You can tell Google to use a custom image like so:

var marker = new google.maps.Marker({  map: map,

position: results[0].geometry.location,  title: “92nd Street Pharmacy”,  icon:”icons/drugstore.png”});

In this case, I’m pointing to a file called drugstore.png that exists on my server. Ifyou google for “google map icons”, you’ll find a great selection of icons out there,many free to use. I found a great set here: http://mapicons.nicolasmollet.com/ In fact, he even had a medical category. I grabbed that zip, downloaded it, andexpanded it.

To make use of these icons, I took some static code he rewrote and created a moregeneric version of it. In my code, I had an array of locations. Each location includeda title and an address. I then added a “type” property that mapped to the typesof things he was looking to filter. This then allowed me to build a utility that couldmap the medical type to an image file. I also could have allowed for completelycustom icons. For example, maybe making use of a hospital’s logo. But for now, I

went with a simple type to icon solution. Here’s how I set up the sample data andthe icon “mapping” code. Obviously I made some guesses here and went with asilly choice for the default.

var data = [{address:’1340 West Towne Square Road Mequon WI 53092’,title:’Center forDiagnostic Imaging-Mequon’,type:’lab’},{address:’2445 North Mayfair Road Wauwatosa WI 53226’,title:’Center forDiagnostic Imaging-Wauwatosa’,type:’lab’},{address:’9200 W. Wisconsin Ave. Milwaukee WI 53227’,title:’Clinical Cancer

3 of 5 

UTORIALS GOOGLE MAPS CUSTOM MARKERS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 30/130

Center Pharmacy’,type:’pharmacy’},{address:’W180 N8085 Town Hall Road Menomonee Falls WI 53051’,title:’Community Memorial Hospital’,type:’hospital’}];

//A utility function that translates a given type to an icon

function getIcon(type) {  switch(type) {  case “pharmacy”: return “icons/drugstore.png”;  case “hospital”: return “icons/hospital-building.png”;  case “lab”: return “icons/barber.png”;  default: return “icons/footprint.png”;  }}

Here’s how it looks now:

4 of 5 

UTORIALS GOOGLE MAPS CUSTOM MARKERS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 31/130

Filtering was easy too. I used jQuery to bind to changes to the checkboxes on top.I then did a show/hide on both the left hand list of locations and the markers aswell. (Google had a simple API to show/hide markers.)

function doFilter() {

  if(!locIndex) {  locIndex = {};  //I reverse index markers to figure out the position of loc to marker index  for(var x=0, len=markers.length; x<len; x++) {  locIndex[markers[x].locid] = x;  }  }

  //what’s checked?  var checked = $(“input[type=checkbox]:checked”);  var selTypes = [];

  for(var i=0, len=checked.length; i<len; i++) {  selTypes.push($(checked[i]).val());  }  for(var i=0, len=data.length; i<len; i++) {  var sideDom = “p.loc[data-locid=”+(i+1)+”]”;

  //Only hide if length != 0  if(checked.length !=0 && selTypes.indexOf(data[i].type) < 0) {  $(sideDom).hide();  markers[locIndex[i+1]].setVisible(false);  } else {  $(sideDom).show();  markers[locIndex[i+1]].setVisible(true);  }  }}

$(document).on(“click”, “input[type=checkbox]”, doFilter);

And that’s it. A good modification to this would be to use the Google API that‘centers’ around markers. I’m not sure if that is smart enough to handle hiddenmarkers, but it could be useful as you filter to adjust the map. (Then again that maybe disorienting to users.)

Raymond CamdenDeveloper EvangelistAdobe

HIS BLOG

TWITTER

SHARE

GITHUB

UTORIALS GOOGLE MAPS CUSTOM MARKERS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 32/130

appliness TUTORIALS PHONEGAP BOOKMARK / SHARE / TO

Developing aPhoneGap Application.

by ChristopheCoenraets

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 33/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

by ChristopheCoenraets

2 of 22 

In this tutorial, you create a fully functional employee directory application withPhoneGap. You will learn:

• How to use different local data storage strategies.• How to use several PhoneGap APIs such as Geolocation, Contacts, and Camera.• How to handle specific mobile problems such as touch events, scrolling, styling,

page transitions, etc.

• How to build an application using a single page architecture and HTML templates.• How to build (compile and package) an application for 6 platforms using PhoneGapBuild.

To complete this tutorial, all you need is a code editor, a modern browser, and aconnection to the Internet. A working knowledge of HTML and JavaScript is assumed,but you don’t need to be a JavaScript guru.

“A single-page applicationarchitecture is particularly

well-suited for mobile apps.”

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 34/130

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 35/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

4 of 22 

4. Click the Ready to build button.

NOTE: The iOS button will immediately turn red because the iOS build requires that youupload your Apple Developer certificate and an application provisioning profile. You canfind more information here if you haven’t already signed up for the Apple Developer

Program. If you don’t have an iOS device, or if you are not ready to upload yourdeveloper certificate, you can skip step 5 and keep running the application in the browseror a non iOS device.

5. To upload your Apple developer certificate and your application provisioningprofile:a. Click the red iOS button.b.Select “add a key” in the “No key selected” dropdown.c. Provide a title for your developer certificate/provisioning profile combination

(for example: EmployeeDirectory), select your developer certificate andprovisioning profile, enter your developer certificate password, and click“submit key”.

d.Go back to the list of apps. Click the iOS button for your application again.Select your newly added key in the iOS dropdown. The iOS build will startautomatically.

6. When the build process completes, use a QR Code reader app to install theEmployee Directory application on your device.

To fine tune your build preferences:

1. In the phonegap-workshop directory, create a file namedconfig.xml file definedas follows (make the necessary adjustments for id, author, etc.):

<?xml version=”1.0” encoding=”UTF-8”?><widget xmlns = “http://www.w3.org/ns/widgets”  xmlns:gap = “http://phonegap.com/ns/1.0”

  id = “org.coenraets.employeedirectory”  versionCode = “10”  version = “1.1.0”> 

<name>Employee Directory</name> 

<description>  A simple employee directory application  </description> 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 36/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

5 of 22 

  <author href=”http://coenraets.org” email=”[email protected]”>  Christophe Coenraets  </author> 

<feature name=”http://api.phonegap.com/1.0/camera”/>  <feature name=”http://api.phonegap.com/1.0/contacts”/>

  <feature name=”http://api.phonegap.com/1.0/file”/>  <feature name=”http://api.phonegap.com/1.0/geolocation”/>  <feature name=”http://api.phonegap.com/1.0/media”/>  <feature name=”http://api.phonegap.com/1.0/network”/>  <feature name=”http://api.phonegap.com/1.0/notification”/> </widget>

2. If you used the GitHub approach, sync with GitHub and click the Update Codebutton in PhoneGap Build.

If you used the zip file approach, zip up your phonegap-workshop directory andupload the new version to PhoneGap Build

NOTE: There are many other parameters you can specify in config.xml to configure thebuild process. See the documentation for config.xml here.

A default webview alert gives away the fact that your application is not native. Inthis section, we set up the basic infrastructure to display native alerts when theapplication is running on a device, and fall back to default browser alerts whenrunning in the browser.

1. In index.html, add the following script tag (as the first script tag at the bottomof the body):

<script src=”phonegap.js”></script>

This instructs PhoneGap Build to inject a platform specific version of phonegap.jsat build time. In other words, phonegaps.js doesn’t need to be (and shouldn’t be)present in your project folder.

2. In main.js, define a function named showAlert() inside the app object. If navigator.notification is available, use its alert() function. Otherwise, use the default browseralert() function.

PART 3: USING NATIVE NOTIFICATION

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 37/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

6 of 22 

showAlert: function (message, title) {  if (navigator.notification) {  navigator.notification.alert(message, null, title, ‘OK’);  } else {  alert(title ? (title + “: “ + message) : message);

  }},

Test the notification logic by displaying a message when the application storehas been initialized: Pass an anonymous callback function as an argument to theconstructor of the persistence store (the store will call this function after it hassuccessfully initialized). In the anonymous function, invoke the showAlert() function.

initialize: function() {

  var self = this;  this.store = new MemoryStore(function() {  self.showAlert(‘Store Initialized’, ‘Info’);  });  $(‘.search-key’).on(‘keyup’, $.proxy(this.findByName, this));}

Test the application: When you run the application in the browser, you should seea standard browser alert. When you run the application on your device, you shouldsee a native alert.

A single page application is a web application that lives within a single HTMLpage. The “views” of the application are injected into- and removed from theDOM as needed as the user navigates through the app. A single page applicationarchitecture is particularly well suited for mobile apps:

• The absence of continual page refreshes provides a more fluid / closer to native

experience.• The UI is entirely created at the client-side with no dependency on a server to

create the UI, making it an ideal architecture for applications that work offline.

PART 4: SETTING UP A SINGLE PAGE APPLICATION

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 38/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

7 of 22 

In this section, we set up the basic infrastructure to turn Employee Directory intoa single page application.

1. In index.html: remove the HTML markup inside the body tag (with the exceptionof the script tags).

2. In main.js, define a function named renderHomeView() inside the app object.Implement the function to programmatically add the Home View markup to thebody element.

renderHomeView: function() {  var html =  “<div class=’header’><h1>Home</h1></div>” +  “<div class=’search-view’>” +  “<input class=’search-key’/>” +  “<ul class=’employee-list’></ul>” +

  “</div>”  $(‘body’).html(html);  $(‘.search-key’).on(‘keyup’, $.proxy(this.findByName, this));},

Modify the initialize() function of the app object. In the anonymous callback functionof the store constructor, call the renderHomeView() function to programmaticallydisplay the Home View.

initialize: function() {  var self = this;  this.store = new MemoryStore(function() {  self.renderHomeView();  });}

Writing HTML fragments in JavaScript and programmatically inserting them into theDOM is tedious. It makes your application harder to write and harder to maintain.HTML templates address this issue by decoupling the UI definition (HTML markup)from your code. There are a number of great HTML template solutions: Mustache.

 js, Handlebar.js, and Underscore.js to name a few.

In this section, we create two templates to streamline the code of the EmployeeDirectory application. We use Handlebar.js but the smae result can be achievedusing the other HTML template solutions.

PART 5: USING HANDLEBAR TEMPLATES

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 39/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

8 of 22 

Modify index.html as follows:

1. Add a script tag to include the handlebar.js library:

<script src=”lib/handlebars.js”></script>

2. Create an HTML template to render the Home View. Add this script tag as thefirst child of the body tag:

<script id=”home-tpl” type=”text/x-handlebars-template”>  <div class=’header’><h1>Home</h1></div>  <div class=’search-bar’><input class=’search-key’ type=”text”/></div>  <ul class=’employee-list’></ul></script>

3. Create an HTML template to render the employee list items. Add this script tagimmediately after the previous one:

<script id=”employee-li-tpl” type=”text/x-handlebars-template”>  {{#.}}  <li><a href=”#employees/{{this.id}}”>{{this.firstName}} {{this.lastName}}<br/>{{this.title}}</a></li>  {{/.}}</script>

Modify main.js as follows:

1. In the initialize() function of the app object, add the code to compile the twotemplates defined above:

this.homeTpl = Handlebars.compile($(“#home-tpl”).html());this.employeeLiTpl = Handlebars.compile($(“#employee-li-tpl”).html());

2. Modify renderHomeView() to use the homeTpl template instead of the inlineHTML:

renderHomeView: function() {  $(‘body’).html(this.homeTpl());  $(‘.search-key’).on(‘keyup’, $.proxy(this.findByName, this));},

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 40/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

9 of 22 

3. Modify findByName() to use the employeeLiTpl template instead of the inlineHTML:

findByName: function() {  var self = this;  this.store.findByName($(‘.search-key’).val(), function(employees) {  $(‘.employee-list’).html(self.employeeLiTpl(employees));  });},

4. Test the application.

It’s time to provide our application with some structure. If we keep adding all the

core functions of the application to the app object, it will very quickly grow out ofcontrol. In this section we create a HomeView object that encapsulates the logic tocreate and render the Home view.

STEP 1: CREATE THE HOMEVIEW CLASS

1. Create a file called HomeView.js in the js directory, and define a HomeView classimplemented as follows:

var HomeView = function(store) { 

}

2. Add the two templates as static members of HomeView.

var HomeView = function(store) { 

} HomeView.template = Handlebars.compile($(“#home-tpl”).html());HomeView.liTemplate = Handlebars.compile($(“#employee-li-tpl”).html());

3. Define an initialize() function inside the HomeView class. Define a div wrapperfor the view. The div wrapper is used to attach the view-related events. Invokethe initialize() function inside the HomeView constructor function.

PART 6: CREATING A VIEW CLASS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 41/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

10 of 22 

var HomeView = function(store) { 

this.initialize = function() {  // Define a div wrapper for the view. The div wrapper is used to attach

events.  this.el = $(‘<div/>’);

  this.el.on(‘keyup’, ‘.search-key’, this.findByName);  }; 

this.initialize(); }HomeView.template = Handlebars.compile($(“#home-tpl”).html());HomeView.liTemplate = Handlebars.compile($(“#employee-li-tpl”).html());

4. Move the renderHomeView() function from the app object to the HomeView

class. To keep the view reusable, attach the html to the div wrapper (this.el)instead of the document body. Because the function is now encapsulated in theHomeView class, you can also rename it from renderHomeView() to just render().

this.render = function() {  this.el.html(HomeView.template());  return this;};

5. Move the findByName() function from the app object to the HomeView class.

this.findByName = function() {  store.findByName($(‘.search-key’).val(), function(employees) {  $(‘.employee-list’).html(HomeView.liTemplate(employees));  });};

STEP 2: USING THE HOMEVIEW CLASS

1. In index.html, add a script tag to include HomeView.js (just before the script tagfor main.js):

<script src=”js/HomeView.js”></script>

2. Remove the renderHomeView() function from the app object.3. Remove the findByName() function from the app object.

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 42/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

11 of 22 

4. Modify the initialize function() to display the Home View using the HomeViewclass:

initialize: function() {  var self = this;  this.store = new MemoryStore(function() {  $(‘body’).html(new HomeView(self.store).render().el);  });}

STEP 1: STYLE THE APPLICATION

1. Add the Source Sans Pro font definition to the head of index.html

<script src=”css/source-sans-pro.js”></script>

Source Sans Pro is part of the free Adobe Edge Web Fonts.

2. Add styles.css to the head of index.html

<link href=”css/styles.css” rel=”stylesheet”>

3. In index.html, modify the home-tpl template: change the search-key input typefrom text to search.4. Test the application. Specifically, test the list behavior when the list is bigger

than the browser window (or the screen)

STEP 2: NATIVE SCROLLING APPROACH

1. Modify the home-tpl template in index.html. Add a div wrapper with a scrollclass around the ul element with a scroll:

<script id=”home-tpl” type=”text/x-handlebars-template”>  <div class=’header’><h1>Home</h1></div>  <div class=’search-bar’><input class=’search-key’ type=”search”/></div>  <div class=”scroll”><ul class=’employee-list’></ul></div></script>

PART 7: ADDING STYLES AND TOUCH-BASED SCROLLING

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 43/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

12 of 22 

2. Add the following class definition to css/styles.css:

.scroll {  overflow: auto;  -webkit-overflow-scrolling: touch;  position: absolute;  top: 84px;  bottom: 0px;  left: 0px;  right: 0px;}

NOTE: If the platforms you target support touch-based scrolling of fixed regions, thisapproach is all you need (you can skip step 3 below). If not, you’ll need to implement a

programmatic approach, typically with the help of a library such as iScroll.

STEP 3: ISCROLL APPROACH

1. Add a script tag to include the iscroll.js library:

<script src=”lib/iscroll.js”></script>

2. In HomeView.js, modify the findByName() function: Instantiate an iScroll objectto scroll the list of employees returned. If the iScroll object already exists (),simply refresh it to adapt it to the new size of the list.

this.findByName = function() {  store.findByName($(‘.search-key’).val(), function(employees) {  $(‘.employee-list’).html(HomeView.liTemplate(employees));  if (self.iscroll) {  console.log(‘Refresh iScroll’);  self.iscroll.refresh();  } else {  console.log(‘New iScroll’);

  self.iscroll = new iScroll($(‘.scroll’, self.el)[0], {hScrollbar:false, vScrollbar: false });  }  });};

NOTE: More information on iScroll is available here.

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 44/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

13 of 22 

1. In styles.css, add a tappable-active class definition for tapped or clicked list itemlinks. The class simply highlights the item with a blue background:

li>a.tappable-active {

  color: #fff;  background-color: #4286f5;}

2. In main.js, define a registerEvents() function inside the app object. Add a thetappable_active class to the selected (tapped or clicked) list item:

registerEvents: function() {  var self = this;  // Check of browser supports touch events...

  if (document.documentElement.hasOwnProperty(‘ontouchstart’)) {  // ... if yes: register touch event listener to change the “selected”state of the item  $(‘body’).on(‘touchstart’, ‘a’, function(event) {  $(event.target).addClass(‘tappable-active’);  });  $(‘body’).on(‘touchend’, ‘a’, function(event) {  $(event.target).removeClass(‘tappable-active’);  });  } else {  // ... if not: register mouse events instead

  $(‘body’).on(‘mousedown’, ‘a’, function(event) {  $(event.target).addClass(‘tappable-active’);  });  $(‘body’).on(‘mouseup’, ‘a’, function(event) {  $(event.target).removeClass(‘tappable-active’);  });  }},

3. Invoke the registerEvents() function from within the app object’s initialize()

function.4. Test the application.

PART 8: HIGHLIGHTING TAPPED OR CLICKED UI ELEMENTS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 45/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

14 of 22 

In this section, we add an employee details view. Since the application now hasmore than one view, we also add a simple view routing mechanism that uses thehash tag to determine whether to display the home view or the details view for a

specific employee.

STEP 1: CREATE THE EMPLOYEE TEMPLATE

Open index.html and add a template to render a detailed employee view:

<script id=”employee-tpl” type=”text/x-handlebars-template”>  <div class=’header’><a href=’#’ class=”button header-button header-button-left”>Back</a><h1>Details</h1></div>  <div class=’details’>

  <img class=’employee-image’ src=’img/{{firstName}}_{{lastName}}.jpg’ />  <h1>{{firstName}} {{lastName}}</h1>  <h2>{{title}}</h2>  <span class=”location”></span>  <ul>  <li><a href=”tel:{{officePhone}}”>Call Office<br/>{{officePhone}}</a></li>  <li><a href=”tel:{{cellPhone}}”>Call Cell<br/>{{cellPhone}}</a></li>  <li><a href=”sms:{{cellPhone}}”>SMS<br/>{{cellPhone}}</a></li>

  </ul>  </div></script>

STEP 2: CREATE THE EMPLOYEEVIEW CLASS

1. Create a file called EmployeeView.js in the js directory, and define an EmployeeViewclass implemented as follows:

var EmployeeView = function() {

 

}

PART 9: VIEW ROUTING

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 46/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

15 of 22 

2. Add the template as a static member of EmployeeView.

var EmployeeView = function() { 

}

 EmployeeView.template = Handlebars.compile($(“#employee-tpl”).html());

3. Define an initialize() function inside the HomeView class. Define a div wrapperfor the view. The div wrapper is used to attach the view related events. Invokethe initialize() function inside the HomeView constructor function.

var EmployeeView = function(employee) { 

this.initialize = function() {  this.el = $(‘<div/>’);  }; 

this.initialize(); } EmployeeView.template = Handlebars.compile($(“#employee-tpl”).html());

4. Define a render() function implemented as follows:

this.render = function() {  this.el.html(EmployeeView.template(employee));  return this;};

5. In index.html, add a script tag to include EmployeeView.js (just before the scripttag for main.js):

<script src=”js/EmployeeView.js”></script>

STEP 3: IMPLEMENT VIEW ROUTING

1. In the app’s initialize() function, define a regular expression that matches employeedetails urls.

this.detailsURL = /^#employees\/(\d{1,})/;

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 47/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

16 of 22 

2. In the app’s registerEvents() function, add an event listener to listen to URL hashtag changes:

$(window).on(‘hashchange’, $.proxy(this.route, this));

3. In the app object, define a route() function to route requests to the appropriateview:a. If there is no hash tag in the URL: display the HomeViewb.If there is a has tag matching the pattern for an employee details URL: display

an EmployeeView for the specified employee.

route: function() {  var hash = window.location.hash;  if (!hash) {  $(‘body’).html(new HomeView(this.store).render().el);

  return;  }  var match = hash.match(app.detailsURL);  if (match) {  this.store.findById(Number(match[1]), function(employee) {  $(‘body’).html(new EmployeeView(employee).render().el);  });  }}

4. Modify the initialize() function to call the route() function:

initialize: function() {  var self = this;  this.detailsURL = /^#employees\/(\d{1,})/;  this.registerEvents();  this.store = new MemoryStore(function() {  self.route();  });}

5. Test the application.

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 48/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

17 of 22 

In this section, we add the ability to tag an employee with his/her location information.In this sample application, we display the raw information (longitude/latitude) inthe employee view. In a real-life application, we would typically save the location in

the database as part of the employee information and show it on a map.

NOTE: The code below works when running the application as a PhoneGap app on yourdevice. It should also work in Chrome on the desktop when the page is served with thehttp:// protocol, and in Firefox, regardless of the protocol (http:// or file://).

1. In index.html, add the following list item to the employee-tpl template:

<li><a href=”#” class=”add-location-btn”>Add Location</a></li>

2. In the initialize() function of EmployeeView, register an event listener for the clickevent of the Add Location list item:

this.el.on(‘click’, ‘.add-location-btn’, this.addLocation);

3. In EmployeeView, define the addLocation event handler as follows:

this.addLocation = function(event) {

  event.preventDefault();  console.log(‘addLocation’);  navigator.geolocation.getCurrentPosition(  function(position) {  $(‘.location’, this.el).html(position.coords.latitude + ‘,’ +position.coords.longitude);  },  function() {  alert(‘Error getting location’);  });  return false;

};

4. Test the Application.

PART 10: USING THE LOCATION API

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 49/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

18 of 22 

In this section, we use the PhoneGap Contacts API to provide the user with theability to add an employee to the device’s contact list.

NOTE: The code below only works when running the application on your device as aPhoneGap app. In other words, you can’t test it in a browser on the desktop.

1. In index.html, add the following list item to the employee template:

<li><a href=”#” class=”add-contact-btn”>Add to Contacts</a></li>

2. In the initialize() function of EmployeeView, register an event listener for the clickevent of the Add to Contacts list item:

this.el.on(‘click’, ‘.add-contact-btn’, this.addToContacts);

3. In EmployeeView, define the addToContacts event handler as follows:

this.addToContacts = function(event) {  event.preventDefault();  console.log(‘addToContacts’);  if (!navigator.contacts) {  app.showAlert(“Contacts API not supported”, “Error”);

  return;  }  var contact = navigator.contacts.create();  contact.name = {givenName: employee.firstName, familyName: employee.lastName};  var phoneNumbers = [];  phoneNumbers[0] = new ContactField(‘work’, employee.officePhone, false);  phoneNumbers[1] = new ContactField(‘mobile’, employee.cellPhone, true); //preferred number  contact.phoneNumbers = phoneNumbers;  contact.save();  return false;};

4. Test the Application.

PART 11: USING THE CONTACTS API

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 50/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

19 of 22 

In this section, we use the PhoneGap Camera API to provide the user with theability to take a picture of an employee, and use that picture as the employee’spicture in the application. We do not persist that picture in this sample application.

NOTE: The code below only works when running the application on your device as aPhoneGap app. In other words, you can’t test it in a browser on the desktop.

1. In index.html, add the following list item to the employee template:

<li><a href=”#” class=”change-pic-btn”>Change Picture</a></li>

2. In the initialize() function of EmployeeView, register an event listener for the click

event of the Change Picture list item:

this.el.on(‘click’, ‘.change-pic-btn’, this.changePicture);

3. In EmployeeView, define the changePicture event handler as follows:

this.changePicture = function(event) {  event.preventDefault();  if (!navigator.camera) {  app.showAlert(“Camera API not supported”, “Error”);

  return;  }  var options = { quality: 50,  destinationType: Camera.DestinationType.DATA_URL,  sourceType: 1, // 0:Photo Library, 1=Camera,2=Saved Photo Album  encodingType: 0 // 0=JPG 1=PNG  }; 

navigator.camera.getPicture(

  function(imageData) {  $(‘.employee-image’, this.el).attr(‘src’, “data:image/jpeg;base64,”+ imageData);  },  function() {  app.showAlert(‘Error taking picture’, ‘Error’);  },  options); 

return false;};

PART 12: USING THE CAMERA API

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 51/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

20 of 22 

4. Test the Application.

1. Add the following classes to styles.css:

.page {  position: absolute;  width: 100%;  height: 100%;  -webkit-transform:translate3d(0,0,0);} .stage-center {

  top: 0;  left: 0;} .stage-left {  left: -100%;} .stage-right {  left: 100%;}

 .transition {  -moz-transition-duration: .375s;  -webkit-transition-duration: .375s;  -o-transition-duration: .375s;}

PART 13: SLIDING PAGES WITH CSS TRANSITIONS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 52/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

21 of 22 

2. Inside the app object, define a slidePage() function implemented as follows:

slidePage: function(page) { 

var currentPageDest,  self = this; 

// If there is no current page (app just started) -> No transition:Position new page in the view port  if (!this.currentPage) {  $(page.el).attr(‘class’, ‘page stage-center’);  $(‘body’).append(page.el);  this.currentPage = page;  return;  }

 // Cleaning up: remove old pages that were moved out of the viewport

  $(‘.stage-right, .stage-left’).not(‘.homePage’).remove(); 

if (page === app.homePage) {  // Always apply a Back transition (slide from left) when we go back tothe search page  $(page.el).attr(‘class’, ‘page stage-left’);  currentPageDest = “stage-right”;  } else {  // Forward transition (slide from right)

  $(page.el).attr(‘class’, ‘page stage-right’);  currentPageDest = “stage-left”;  }

 $(‘body’).append(page.el);

 // Wait until the new page has been added to the DOM...

  setTimeout(function() {  // Slide out the current page: If new page slides from the right ->slide current page to the left, and vice versa

  $(self.currentPage.el).attr(‘class’, ‘page transition ‘ +currentPageDest);  // Slide in the new page  $(page.el).attr(‘class’, ‘page stage-center transition’);  self.currentPage = page;  }); },

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 53/130

UTORIALS DEVELOPING A PHONEGAP APPLICATION

3. Modify the route() function as follows:

route: function() {  var self = this;  var hash = window.location.hash;  if (!hash) {

  if (this.homePage) {  this.slidePage(this.homePage);  } else {  this.homePage = new HomeView(this.store).render();  this.slidePage(this.homePage);  }  return;  }  var match = hash.match(this.detailsURL);  if (match) {

  this.store.findById(Number(match[1]), function(employee) {  self.slidePage(new EmployeeView(employee).render());  });  }},

Christophe CoenraetsTechnical Evangelist

HIS BLOG

TWITTER

SHARE

GITHUB

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 54/130

appliness TUTORIALS PHONEGAP BOOKMARK / SHARE / TO

Geo-based Push

Notifications with PhoneGapand Pushwoosh.

by HollySchinsky

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 55/130

UTORIALS GEO-BASED PUSH NOTIFICATIONS WITH PHONEGAP AND PUSHWOOSH

by HollySchinsky

2 of 6 

Recently I blogged about sending push notifications via the Pushwoosh service andspecifically with PhoneGap applications. Whileworking with the service I noticed it had somethingbuilt in for setting up geozones for your pushnotifications (aka: geofencing). If you’re notfamiliar with this term, it’s basically the ability tosend push notifications to a device when it’s in a

certain location or zone. There’s a really greatarticle about it here. This is something I’ve seenmany real application uses for myself in myconnections with people so I was particularlyinterested in trying out their service with it andsharing it.

If you haven’t looked at the previous post regarding the Pushwoosh service and push notificationsI suggest you do that first before continuing…

The way the Pushwoosh service implements geo-based notifications is by comparingthe devices’ current locationto the geographic zonesthat were defined for thatapplication either throughtheir web interface or their

APIs to see if there’s amatch. An example of theinterface to define them ontheir website is shown tothe right:

GETTING STARTED

OVERVIEW

“Geofencing allows you to sendpush notifications to a device

when it enters a location”

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 56/130

UTORIALS GEO-BASED PUSH NOTIFICATIONS WITH PHONEGAP AND PUSHWOOSH

3 of 6 

Notice the Find location link that brings up a map to help you find latitude/longitudemore quickly and set it in your form as shown in the screenshot:

When a match is found, the notification text (and any additional settings includingan HTML page or URL to open when the notification is clicked for advancednotifications) are then displayed.

Currently their sample PhoneGap applications  show this implemented with acombination of the PhoneGap Geolocation API and the Pushwoosh APIs. So thePhoneGap Geolocation API is used to track the user’s location via the followingfunctions, which may vary depending on exactly how you want your application totrack, but you get the idea:

navigator.geolocation.getCurrentPosition(geolocationSuccess, geolocationError);navigator.geolocation.watchPosition(geolocationSuccess, geolocationError, {maximumAge: 3000, enableHighAccuracy: true });

and when the device location changes, the following Pushwoosh PushNotificationAPIs are used to send the location (found in the PushNotification.js file under eachof the Android-PhoneGap and iPhone-PhoneGap projects):

USE WITH PHONEGAP

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 57/130

UTORIALS GEO-BASED PUSH NOTIFICATIONS WITH PHONEGAP AND PUSHWOOSH

4 of 6 

//Android Only----PushNotification.prototype.unregisterDevice = function(success, fail) {  cordova.exec(success, fail, “PushNotification”, “unregisterDevice”, []);}; PushNotification.prototype.startGeoPushes = function(success, fail) {

  cordova.exec(success, fail, “PushNotification”, “startGeoPushes”, []);}; PushNotification.prototype.stopGeoPushes = function(success, fail) {  cordova.exec(success, fail, “PushNotification”, “stopGeoPushes”, []);}; //Android End---- // Call this to send geo location for the devicePushNotification.prototype.sendLocation = function(config, success, fail) {

  cordova.exec(success, fail, “PushNotification”, “sendLocation”, config ?[config] : []);}; PushNotification.prototype.onDeviceReady = function() {  cordova.exec(null, null, “PushNotification”, “onDeviceReady”, []);}; // Call this to get a detailed status of remoteNotificationsPushNotification.prototype.getRemoteNotificationStatus = function(callback) {

  cordova.exec(callback, callback, “PushNotification”,“getRemoteNotificationStatus”, []);}; // Call this to set the application icon badgePushNotification.prototype.setApplicationIconBadgeNumber = function(badge,callback) {  cordova.exec(callback, callback, “PushNotification”,“setApplicationIconBadgeNumber”, [{badge: badge}]);};

 // Call this to clear all notifications from the notification centerPushNotification.prototype.cancelAllLocalNotifications = function(callback) {  cordova.exec(callback, callback, “PushNotification”,“cancelAllLocalNotifications”, []);};

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 58/130

UTORIALS GEO-BASED PUSH NOTIFICATIONS WITH PHONEGAP AND PUSHWOOSH

5 of 6 

An example of how this might look in your applications’ JavaScript is below:

deviceready: function() {  navigator.geolocation.getCurrentPosition(geolocationSuccess,geolocationError);  navigator.geolocation.watchPosition(geolocationSuccess, geolocationError, {

maximumAge: 3000, enableHighAccuracy: true }); 

function geolocationSuccess(position) {  pushNotification.sendLocation({lat:position.coords.latitude,lon:position.coords.longitude},  function(status) {  console.warn(‘sendLocation success’);  },  function(status) {  console.warn(‘sendLocation failed’);

  });  function geolocationError(error) {  alert(‘code: ‘ + error.code + ‘\n’ +  ‘message: ‘ + error.message + ‘\n’);  }};

Download the complete sample for Android and iOS with PhoneGap here for moredetails.

Additionally there are obviously some differences in the native code between iOSand Android and how things are handled, but I won’t go into detail about thathere. One thing you should be aware of though is that on Android you need to callthe following to start and stop receiving geo-based push notifications:

pushNotification.startGeoPushes();pushNotification.stopGeoPushes();

Refer to the sample Android-PhoneGap project for more details…

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 59/130

UTORIALS GEO-BASED PUSH NOTIFICATIONS WITH PHONEGAP AND PUSHWOOSH

As some may be thinking, on iOS the location updates will stop as soon as theapplication goes to the background. However, there is a flag you can set on yourapplication to allow it to continue to receive location updates so you will still receiveyour notifications. The flag is set in the application .plist file to set the background

mode (UIBackgroundModes is the official name of the key). Note that this .plistis different from the Cordova.plist, and is typically named as YourAppName -Info.plist.

Keeping the application in the background and performing continuous location pingingwill use up the battery more quickly. On iOS there is a native low-power significant changelocation API available that could be used instead (as opposed to the standard location APIthat the PhoneGap geolocation APIs use). I found a PhoneGap Geofencing plugin availablethat appears to do this but I haven’t tried it yet myself. Feel free to give it a try and post back.

Note that the geozones are only available on memberships above the free level. View theplans here.

• Check out the Pushwoosh documentation for more information.• Intro to geofencing on iOS article• Easy PhoneGap Push Notifications with Pushwoosh

IOS HANDLING

ADDITIONAL NOTES AND LINKS

Holly SchinksyDeveloper Evangelist

HER BLOG

TWITTER

SHARE

GITHUB

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 60/130

appliness  VIDEO TUTORIALS JAVASCRIPT BOOKMARK / SHARE / TO

VIDEO TUTORIALS

PhoneGap & Force.com

by PiotrWalczyszyn

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 61/130

I’m proud to present a series of seven video tutorials that teach how to build PhoneGapapplications connected to Force.com (Salesforce). It is over an hour of content thatgoes step-by-step from project set up to packaging of applications ready for multipleplatforms. Before you start watching the tutorials you may also want to check out arecording of a session I did at Dreamforce 2012; it covers similar topic but from a high

level perspective. One thing I wanted to mention here is that the GapForce app thatI presented during my session is already available to download from App Store andGoogle Play. Also its source code is available on GitHub here, in case you wanted to

Piotr WalczyszynDeveloper Evangelistat Adobe

HIS BLOG

TWITTER

SHARE

GITHUB

DEO TUTORIALS PHONEGAP AND FORCE.COM

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 62/130

appliness INTERVIEW DENISE JACOBS BOOKMARK / SHARE / TO

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 63/130

appliness INTERVIEW DENISE JACOBS BOOKMARK / SHARE / TO

INTERVIEWDENISE JACOBS

by Maile Valentinephotos by Derek Kearney

D enise is a true Renaissance Woman who has successful-ly created a niche role for herself by bringing creativity

and inspiration to the world of technology geeks. She canteach you all about soap-making or get into the inner workings ofCSS and web standards all while inspiring others in the process.Catch a glimpse of this Creativity Evangelist who writes booksand articles, teaches others and speaks around the world.

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 64/130

TERVIEW DENISE JACOBS

3 of 27 

 APPLINESS: Hello Denise! It is a big

honor to have you in our next issueof Appliness. Can you start by tellingus a little about yourself?

Denise Jacobs: As for my company, Iam an independent consultant, I workmainly by myself, sometimes I willpull people to work on projects. Atthis point though, I have been mainly

working by myself on projects suchconsulting people on web design orweb development. I just finished doinga big CSS optimization project tryingto help a company that had 7500 linesof crazy CSS and figure out a way theycould make it scalable, modular andeasier to maintain and build upon. I also build websites and do CSS3trainings, I was doing that for acompany whose main client was Intuit.

I was teaching developers at Intuit how

to use CSS and CSS3. I also speak atconferences, write articles and booksand things like that. So, it’s kind of astandard range of what most consultantsin the industry do. That’s what I do forwork.

That said, in actuality, I’m a bit of a creativeperson in a technical person’s clothing.

I’m seeing now that, intrinsically, I havealways been a creative person, but thetechnical stuff was my “way in the door”.It was my way into somehow giving mycreative outlet validity because I seemyself, especially now, much more asa creative person, whereas before Iused to identify myself as a technicalperson. Working in the web and techindustry are what I have used to get toseeing myself as a creative, but it’s notnecessarily “the thing” for me anymore

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 65/130

TERVIEW DENISE JACOBS

at this point in my life. Ten years ago,however, it totally was. Beyond that, I really think of myself as ateacher, that’s the essence of who I am.I love to teach people ways to do what

they do better. One of the reasons I likedteaching CSS3, is because people getinto a bind with CSS and there are a lotof old, outdated methods of achievingthings that you can achieve easily inCSS3. I like to help people figure outhow to do things in a way that’s easier,better and more enjoyable.

How did you get into teaching?

I used to teach soapmaking classes wayback in 1998. I started that businesswhen people kept asking me what wasin soap and so I said “Oh, it’s reallyeasy, come over to my house and I’llshow you how to make it.” I did thata couple of times and I thought that Icould teach 20 people at a time insteadof 5 and still have a good time andactually make a profit [laughs]. So that’s how I discovered I really lovedteaching. And I thought “if I can teachthis, then I can teach other things.”At the same time I was doing that, I

was working in the web/tech industrydoing project management and I hatedit. So, I thought if I could teach webconcepts and how to make websites,that would be phenomenal. I ended upgetting a job teaching Web Design andDevelopment at the Seattle CommunityCollege, and I taught there for almost5 years.

So for me the speaking, writing,trainings all boil down to teaching andtrying to help people access informationthey wouldn’t have had before that willpotentially better their lives.

The role of “Creativity Evangelist”sounds very intriguing and cool. Isthat a term you coined? How did youcome to be in that role?

 Yes, I made it up! One of my favoritestories about my life, ever, happenedduring the process of writing the CSSDetective Guide. At the beginning of

writing the book, I freaked out. I gotthe book contract, I spent the first dayI was supposed to spend writing intears. I kept thinking “Why am I writinga book? Should I be writing a book? Idon’t know if I can write a book!”

I finally pulled myself together, andthen spent the next 9 months writingmy book and managing my anxieties.Incidentally, the initial idea for the InnerCritic article came from that period oftime - even though it wasn’t until 2 yearslater that I wrote it. When I finished thebook and everything was done and atthe publisher to get printed, I finally hadthe time to design the website I was

planning to build for the book. I hadsketched it out several weeks earlier.As I was building the comp for it inPhotoshop, I realized I was having sucha good time designing it that I didn’twant to go to sleep. I was up until 5 inthe morning finalizing the design andhaving such an awesome time doing it-- it was all coming together. I went to

sleep because I had to, not because I4 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 66/130

TERVIEW DENISE JACOBS

really wanted to. When I finally wokeup a little bit later, I had this hugerealization. For so long in my life, I hadbeen wanting to be a creative person.Over the years, I’d dabbled in all kindsof projects: soapmaking, papermaking,

making stationery sets, edible gardendesign, etc. to prove it to myself orto practice being creative. That day, Ifinally got it: I AM creative! I had justfinished writing a book where I wrotethe content, designed websites for it,built the websites, broke them andrebuilt them. Then I wrote about thatprocess and did most of it through

storytelling format. I thought, “if thatdoesn’t make me creative, I don’t knowwhat does!” With this epiphany, I felt this amazingsense of power and a huge rush ofenergy. And at that moment, everythingbecame clear: I figured out what it isI wanted to do - to help people feellike this: empowered and powerful. Iwant to help people feel like they arecreative and to be the creative personthey’ve always wanted to be. I wantmy life to be about helping peopleget in touch with their creativity andexpressing it and putting it out in theworld and transforming the world by

having people get in touch with theircreativity. Take it how you will, but it’salmost spiritual thing where I wantpeople to be able have that feelingthat they can do anything.

I realized I wanted to “preach thegospel” of creativity. And so basically,from that point on, I thought, “I’m like

an evangelist: a Creativity Evangelist”.

I loved the sound of it and looked it upand nobody owned the domain, and

nobody else was calling themselvesa Creativity Evangelist so I was like“awww yeah! It’s all mine!” I feel quite fortunate -- a lot of peoplesearch a long time for their life’s work.Even though it may go in differentpermutations, forms and whatnot,I feel that at this moment, it’s clear

that this is what I’m most passionateabout. Even during the time when Iwas teaching the soapmaking classesway back from 1998-2003 and thenteaching web design and developmentat Seattle Central from 2000-2005, I hadbeen helping people be creative. Backthen, I sometimes thought of myself a“creativity midwife” -- as I felt I helped

5 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 67/130

TERVIEW DENISE JACOBS

people give birth to their ideas. Throughmy eclectic craft classes, I was alreadyproviding an excuse or permission forpeople to explore their creativity. A lotof my students were folks who wereworking at Microsoft when Microsoft

was really starting to boom in the late1990s and early 2000s, because that’swhere their jobs were and they couldmake lots of money. But it seems like alot of them were stifled creatives. Theywould come to my class and would justlet their hair down and start gettingconversant with their playful creativesides. I developed new courses to keep

giving people that opportunity.

 What does the role of CreativityEvangelist entail?

Currently, my message is almost asubversive rework  / unwork  type ofmanifesto because the way peoplework is very much at odds with beinghighly creatively productive. We areasked to come up with this idea, dothis new thing in this amount of time-- everything we do actually calls uponus to be creative in some way shapeor form. Yet, so many of us don’t reallyhave the tools or the space to be able todo it. So instead of giving people craft

classes to attend, now it’s the contentthat I speak about at conferences,write about, and will soon teach whereI’m trying to encourage people toapproach work differently so they cancreate more. I’m hoping to get people to that sparkwhere they are encouraged and are

doing the work they are really brilliant

at. I believe that everyone has got thispiece of brilliance they can tap into. SirKen Robinson wrote a book called TheElement  that speaks to this conceptfairly well, although I think he couldhave gone into more detail (which why

I’m planning to write more books, so Ican share my ideas as well). But, he talksabout that in a lot of ways and I thinkthat is really important and critical andthat’s one of the skills that is neededright now.

The tech industry is such a hotbed ofinnovation and wonderful ideas, but

it’s also a place where a lot of crazywork practices are still being donewhich are completely at odds withwith what people need to succeed inmoving forward in the industry. Withthe economy the way it is, and theway work is, (and especially in the techindustry), I feel like this is a really goodplace to start helping -- changing theway people approach work. Back inOctober, I had a tour of the Googleoffice in Zurich. It was amazing: all ofthe different rooms had things likefireman poles, vintage Swiss cable carsset up in ways that people could usethem as mini meeting rooms, and allkinds of wonderful things to spark your

creativity and imagination. They did agreat job of setting up an environmentthat stimulates and promotes creativityand playful thinking. There are somebusinesses that do that, but there areso many more businesses that will geton to you for being there 2 minutesafter 9 o’clock and other practicesthat essentially stifle creativity and

innovation.6 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 68/130

TERVIEW DENISE JACOBS

 Part of my vision moving forward isto be able to start affecting changeon both a larger, corporate scale butalso on an individual scale so peoplestart realizing they can ask for different

things. Then people can look at theirwork days differently and start askingfor different things from their managers.From a top down perspective, I’dinfluence and teach more managersand corporate VPs and show them thatthis is the way to go if you want yourcompany to be forward-thinking andmoving - you really have to have this

top-down approach that gives peoplethe environment in which they cancreate well because this is going to bean economic advantage.

How important is storytelling in agood web design? How should onego about telling a good story throughtheir site?

I contributed a chapter to The SmashingBook  about how storytelling in webdesign actually comes from severaldifferent aspects. With the web, there isa visual layer you can work with, but youalso have interactivity. The differencebetween a flat book story and a website

is that you can move through a websitein different ways - much like in a gamebook (or a create your own adventurebook) but even better. You also havethe content itself, the actual words orimagery. So you’ve got this kind ofmulti-tiered way in which you actuallyneed to create the story you want totell.

I think part of what is most importantin storytelling in web design is whathappens beforehand: figuring out whatstory you want to tell first. They say youcan’t design a website, or pretty muchdo anything, without knowing the

content ahead of time, so storytellingis a good framework in which to getanswers about the business, the visionand a brand in general. Or, after doingit, that helps clarify the process so thatyou can take the information and putit into a story and that actually writingthe story may help clarify what some ofthe business questions are.

 When you ask people clarify their brand,they may say “Our brand is...uh... wedo stuff!” So, that’s great, you do stuff.Let’s say this is a story and tell me whatthe story is. What kind of story do youwant it to be or what’s the outcomeof the story? What’s the happily everafter? You can reverse engineer it tohelp put things in context, or visualizeit in a certain way to come up with theinformation. So, once they have thatthen you can have all of those piecesand get the visual imagery to do thevisual storytelling part of it. To figure outwhat the interactivity, the UX, aspectsare going to be, and then obviously

also the content. So it’s a nice holisticprocess. To me, it’s an easier processthan sitting around and writing a bunchof lists. It’s easier to visualize richimagery, like that of a great fairytale asopposed to sitting around a conferencetable with a white board.

7 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 69/130

TERVIEW DENISE JACOBS

DENISE JACOBS

ABOUT RESPONSIVE DESIGN

In responsive web design, do youthink, then, that coming up with thestory is the first thing that you do?

I think it’s important because it seemsthat people see web design as a sortof panacea -- a solution for everything.As with any new technology or fresh

approach to solving a problem,

sometimes it begs more questions thanit answers; such as making companies,businesses or whoever is the decisionmaker, think about what they wantto know about their audience. Withresponsive design, you have to ask:who are you being responsive to andwhy?

 8 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 70/130

TERVIEW DENISE JACOBS

With a CSS optimization project I did thisyear, one of the reasons the customerwanted to do it is because they wantedto retrofit it to be responsive. So I hadto take a step back for a bit to see, firstof all, they don’t have a grid at all. Their

site visually looks like it’s built on a grid,but when you look at the stylesheet,there is no actual CSS grid. The widthsof some of their main elements variedbetween 432 pixels here and 435 pixelsthere and so on... all for the elementsthat looked the same visually. So firstof all you need to address this. Thenyou say, okay, so what are we changing

it to? If we’re changing it to a differentorientation and device, find out howmany people in your audience are usingwhich device and which orientation.Then, which information are thosepeople looking for on those devices? If you look at any of Luke Wrobleski’sstuff on Mobile First, it’s great forresponsive design, because a lot oftimes people don’t want the wholewebsite on mobile devices. Andbecause they’ve got a very limitedtimeframe, they are probably not goingto be sitting there scrolling across theentire website on their phone or tablet.They often have different things they

are looking for and different tasks theyare trying to accomplish than when ona desktop computer or laptop. It maymean they want different content.

Frequently, it seems like people justwant to start somewhere: go aheadand make the site responsive andthen figure out the business questions

and the strategy later. However, I like

a “measure twice cut once” type ofapproach. I would rather think aboutthe strategy and get that clear beforeI have people change code that isprobably going to have to change againbecause you later figured out x or y or z.

So, yeah, while story is a good place tostart for thinking through the end goal,but I also think for going responsive,being very user-centric and audience-centric is key. Why are you doing thisand who are you doing it for? You haveto know your audience to know whatstory you’re telling. 

I was talking to Carl Smith, who is incharge of a company called NGenWorks  about stories and projects.One of the things they do when theymeet with clients is find out what storythey want to tell about the project atthe end of the project - which I thinkis brilliant. For example, you want tosay you solved x, y and z problem forthe client. So, from knowing what theywant the outcome to be, they createa story based on that outcome whichgives them the outline on how they aregoing to begin structuring the project.

I think that this approach is importantwhen people want to publish websites

as well. What story do we want to tellthe end user? What’s the story that wewant to have? What’s the story thatwe want the end users to tell otherpeople? Because they are going to bepromoting our company if we tell themthe right story and they will tell thestory to someone else. Also, taking ita step further, what story does the user

want to be told? In other words, what9 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 71/130

TERVIEW DENISE JACOBS

is going to fulfill their needs and whatare they looking for and how can wefit into that or make them understand

that what we have is something thatthey need? It’s kind of circuitous, but itstill works as a method to help get yourstory or stories for your website (andcompany) straight. It’s an interesting way to startapproaching projects, becauseeverybody loves stories, everybody

knows how to tell stories, how to put

stories into context and how to makesense out of a story. Stories stick withpeople way more than just hard data

does. So, when you have a compellingstory, you engage people’s sense ofimagination, you engage their creativity-- you engage them period. You makethem more invested in the informationand then if people are able to add theirlittle bits to the story as well, then theybecome more invested in the storyoverall. And I think it’s really just an

interesting approach in dealing with10 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 72/130

TERVIEW DENISE JACOBS

projects and getting things done aswell, because it provides a structure sothat products can conceivably get builtbetter, faster and more effectively -- andalso so that people behind the productare more invested in it. That means

that quality of the output is higherwhen people are more invested in it.Interestingly, I hadn’t really thought ofit on that level before just talking aboutit now, but it’s a solid line of reasoning.

So when you get to the point whereyou figure out the story you aregoing to tell and the audience you

are telling it to, and if you are one ofthe enlightened ones who figure outthe end story, how do you then, as adeveloper, go about making that sitescalable, modular and responsive?

First, to back up a little bit, one of thethings I’ve been doing with storytellingin general is changing my presentationstyle to be more of a storytelling onerather than just free information giving.Even changing straight anecdotalwhich, of course, is storytelling, butthen telling the whole of the contentin the context of the story rather than just with anecdotes. I’ve gotten goodfeedback about this, number 1.

 Number 2, for making a site scalableand modular it is good to review andanalyze major scalable and modular CSSarchitectures that are out there rightnow. For example, OOCSS, SMACSS,CSS for Grownups and Drive for CSS.There are more, but that’s a good start. 

The key to that is having a really good

naming convention to help makethings scalable and modular. Anotherimportant factor is to modularize thingsto figure out what the patterns are andfigure out how to distill things into theirsimplest form and how you can take

those distilled modules and build uponthem.

 With technology moving as quicklyas it is and customer demandsbeing what they are, they have toldtheir story and they want to gettheir site up quickly...how do yougo about keeping up with the new

technologies to use and still keep thesite responsive?

I find other people who are smarterthan me [laughs]. I have to say that oneof the things that has been a blessingand a curse with the whole responsiveexplosion is that it has really pusheddevelopment into a new place and it’sspurred innovation in the respect thatthere are all of these new tools. Honestly,I can’t keep up with it. I wrote an articlefor .net magazine  last year in Augustabout the top 20 tools for responsivedesign. They asked me to update it butI wasn’t able to at the time. So PeterGasston updated the article and added

30 more tools. I’m sure that all of theresearch that Peter has done to addto the stuff I did last year is already --well, maybe not obsolete, but there areprobably another good 20-30 recently-released tools to add to that that are just as relevant and wonderful.

At this point, I feel like I can’t keep up

with everything, it’s almost impossible11 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 73/130

TERVIEW DENISE JACOBS

-- especially because so much ofmy focus is now on creativity andchanging the work life and style andwork approach, and also because theresponsive stuff is changing so fast.So I follow people on Twitter who

are deeply immersed in everythingresponsive like Brad Frost, Tim Kadlec and, of course, Ethan Marcotte to findout what they are working on and try tomake assessments based on what theyare tweeting, writing, and speakingabout.

I also try to keep track of people I

admire in the industry and what theirinterests are so that I can figure out whoto follow for what things and who I cansend people to. If I can’t be a resourcefor something, then I’ll send them onto someone who can be, because Ilike giving people the good resourcesfor information they’re looking for. I’mreally happy just to find people who doare all responsive all the time so I canpoint folks onto them.

 When you plan for responsive webdesign, what kind of questions doyou ask your audience? E.g., will theyview it on the web, cellular devices,tablets, orientations? Once you getthose answers, how do you plan forthe different devices out there?

I think you can’t plan for all of thedifferent devices. But you have toknow baselines for groups. I think ofdevices in groups. Bryan and StephanieRieger of yiibu.com have done a lot ofamazing work in this area. I follow them

to find out what’s the best thinking for

that and what the best approaches arefor managing different devices. Myimpressions are from the informationyou get from analytics and whatnot.Also,Peter-Paul Koch is a good resourcefor knowing about different devices and

mobile, etc. So, I find out from otherpeople what the acceptable ranges areand I make recommendations based onthose ranges. Using information aboutthe devices and sizes, etc., I take thatinformation and put that together withthe client’s analytics of what their usersare doing, what their users are on, whatare the most popular pages, etc. I’ll take

the two together and make acceptableranges are and we figure out what thebreaking points are for the differentorientations on the different devices.

 When you mention ‘range’, what isthat a range of?

I’m thinking about it more of terms ofdisplay sizes and what the differentelements are going to be. Whichelements are going to be displayed andwhere on the page - are they going tobe higher up, etc. For example, EthanMarcotte’s Boston Globe work  wasvery helpful on how to deal with thedifferent content on the different sizeson the different devices, so I would goand look at something on my computer,then look at it on the iPad and changethe orientation, then look at it on aphone and change the orientation andwould be able to make judgementsabout what kind of choices they made.So they thought this, this and this wasimportant so I can see how that was

important and make similar sorts of12 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 74/130

TERVIEW DENISE JACOBS

choices for my clients. At this point, there is so much, I think“what are the really smart people wholive and breathe this stuff all day longdoing?” It may not be a very imaginative

thing to do, but it works. When I look attheir solutions, it helps me put some ofmy own questions into a context to beable to come up with more questions,but it gives me a basis to start from. My strength is gathering informationand putting it together in a way that’seasy for people to learn and assemble.

I also like making connections betweenthings to make them easier tounderstand and turn into new concepts.Other people come up with things likehow to make responsive design  andI think that’s great - I may never havecome up with something like that or Imay have, but I’m glad they did thatand whatever they are doing, I willleverage that.

 You mentioned at some point thatthere were new alternatives to usingfloats for layouts. I wanted to askyou about this?

There’s a great article called Give Floatsthe Flick on SitePoint and I base a lot onthat. This article really outlines how youcan work with things other than floats.Iplayed a little bit with some of thetechniques mentioned in it. But one ofthe things I loved about the article wasnot the solutions themselves as muchas the idea that there is another wayto do something that’s different from

this very established way that we’ve

grown used to doing. I tried one ofthe suggestions:  display:inline-block. There were some issues withcontrolling the margins, but I reallyliked it alot. There is also display:table  which can work as well. Even

more importantly, the idea that there’ssomething other than floats is enoughof a spur to nudge people to startlooking for what other ways we can doit. It’s not just that we have display:inline-block anddisplay: table - what other way is there to do this aswell as floats or even better? So I thinkit’s a great thing.

I also liked Louis Lazaris’ article in theAppliness issue #9 about using floats,because I’ve been talking to people aboutthe new clearfix Nicholas Gallagherdeveloped that’s in HTML5 Boilerplate.I’ve been putting in my presentationsabout changing the clearfix that youuse because a lot of people say they just use overflow:hidden. Louis’sarticle has a really great explanation ofwhy overflow:hidden  isn’t alwaysthe best answer. What I really I love about all of this is thefact that there are new things comingout that challenge old, establishedmethods that came out when tablelesslayouts started back in the early 2000s.When we look back at those days, ateverything people were wrestling andstruggling with, it’s amazing to see howmuch we’ve progressed...but also howmuch we haven’t.

13 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 75/130

TERVIEW DENISE JACOBS

How much did the creation andadoption of web standards affect

your career?

The beginning days of tableless designis when I started teaching web design.When I started teaching in 2000,table-based layouts were the way toteach. Then, around the end of 2001/beginning of 2002 - around the time theCSS became more popular - is when the

web standards and using CSS for layoutdesigns started to become popular and

became a sea change in the industry. Iwas really excited about that and I wasteaching that to my students. For me, the creation and adoptionof web standards in a lot of waystremendously shaped my careerbecause I was so excited about thisprospect of doing things differently -

DENISE JACOBS

ABOUT OPEN STANDARDS

14 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 76/130

TERVIEW DENISE JACOBS

namely the separation of presentationand content - because I was teachingHTML. I literally memorized all theHTML tags and their attributes andthat’s what I taught my students. I knewall of the attributes for FONT, all of

the attributes for TABLE and BODY...everything - I knew that stuff backwardsand forwards. So then it was really niceto be able to teach the alternative wayof CSS.

For a while I, up until I stopped teachingin early 2005, I was still teachingattributes and their values because I

felt like once you understood those,then CSS was easier to understand -you understood exactly which HTMLattributes the CSS properties werereplacing. That makes it easier to knowwhat to take away and what to putin when we know why it’s not there.Nowadays, most good teachers don’teven teach that stuff, they just teachCSS. For me, it was a really big part ofhow I shaped myself and how I thoughtabout myself in the industry becauseI was one of these people who was a“Standardista” - I was very stringentand behind supporting web standards.It was a really big part of my professionaltrajectory.

 What improvements to web designand development did you see as aresult? Think of how crazy responsive designwould be if we were still using tables.It would just be horrific -- I don’t eventhink it responsive design could have

been conceived of with tables.

 In regards to the improvements to webdesigns, I mostly see standards as a wayto spur innovations, a way to encouragepeople to see things differently and goabout things differently and using these

tools that they have been given andusing them in different ways, that’s thebest thing about it. What comes out ofit are all of the amazing things such asmobile development. The industry haschanged so much since I started doingHTML in 1996.

 What roadblocks did it create?

I mainly see this open field of innovation.The only thing I see as a roadblock ishow quickly the standards are adaptednow. But we still have all of this browser/vendor stuff we have to deal with. Forexample, with the adoption of CSS3and HTML5 properties, it’s probablya good thing they are slowed by thebrowser vendors trying to deal withthem. They are incorporating themas quickly as possible. We have onenotable exception of a browser thatdoesn’t seem to be incorporating themas quickly as possible -- I won’t namenames or anything. Browsers can’t adoptthe specifications immediately and thenthere’s a lot of interpretation -- have youever read the CSS specifications andknow how hard they are to read? Theyare written for and by standards geeks,not for general consumption. Theyare also open to wide interpretation.So whoever is working on developingSafari, Chrome, Firefox, etc. has tointerpret the meanings and figure out

how to turn that meaning into code15 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 77/130

TERVIEW DENISE JACOBS

that creates a certain outcome andbehavior that’s understandable.

I also feel, to some degree, the industryis sometimes so rabid about trying topush the standards forward that we’re

not being compassionate about howmuch time it takes to interpret thingsand translate them into somethingthat’s actionable. With some browsers,updates are automatic while othersdon’t update very often so then youare kind of stuck. I don’t know what the answer is

in regards to the browser wars ordifferences between them. I thinkdifferences are good, but sometimes itseems like it’d be easier if there wasone, but we can’t have that becausewe have to have differences. But it’s aninteresting conundrum.

Do you give the creation andadoption of web standards a lot ofcredit for opening the door for a lotof innovation?

Most definitely. Without thewidespread adoption of CSS, imaginehow crazy it would be if we were stillworking with just HTML. In 1999, Iwas working at a company where wedid both a refresh and redesign of thewebsite within 6 months of each other.Back then, the website was flat HTMLbefore dynamically-driven websites andcontent management systems. I wasin charge of managing both projects.So, I managed the refresh where wechanged the color palette a little bit.

We swapped out some images but

didn’t change the structure of the HTMLat all. The outward-facing website wasflat HTML pages and, in order to justchange the font colors, we had to do asearch and replace on over a thousandHTML pages and then we had to QA

almost every page. Then we decided toget really fancy and use Dreamweaveras the tool to control all of the pagesand have libraries and stuff like that

which mimics server-side includesand the like. Later on, the companyactually chose a content managementsystem called Broadvision for theirintranet which, at the time, cost around$250,000 to implement. It was crazytimes. That was how we did it back inthe “ole days” of the web.

It seems ludicrous that we had to searchand replace font and color tags andstuff like that. Now, you change it inone place in the stylesheet and you’redone. With the advent of blogging toolsand content management systems andmaking them open source and availablefor people so they don’t have to getsomething like Broadvision which costumpteen thousands of dollars andonly available to enterprise-based

teams was a huge change in the right

“I mostly see standardsas a way to spur

innovations, a way toencourage people to seethings differently” 

16 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 78/130

TERVIEW DENISE JACOBS

direction. Along with that, what washappening in web standards was theseparation of presentation and content,the rise of using CSS and CSS-basedlayouts, JavaScript and the beginningof JavaScript libraries and so on.

Everything just tumbled together andgrew together. Now we the complexity just keeps growing. I look at the progress and applaudit because that is innovation at itsfinest. Everyday we get on the webwe are actually seeing the product ofinnovation and innovative ideas - apps

on our phone and tablets and all kindsof things. So, it’s great. I’m all for it.

I’ve gotten to the point where I’m clearthat I personally am not going to beinnovating these products or apps -- Iwill be innovating other things. But thepeople I talk to and the audiences I talkto are some of those people are going

to be creating the next big innovations.So, I always try to encourage them bysaying, “Look, this is a problem andone of you here can probably solve thisproblem.” If someone’s got the toolsand the drive and the interest, passionand creativity - then they should do it:go out there and solve a problem! 

Nobody saw people like Harry Roberts,Nicholas Gallagher, Lea Verou, Paul

17 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 79/130

TERVIEW DENISE JACOBS

Irish -- or any of the other people whoare developing phenomenal things-- coming out of the woodwork. But,all of a sudden here they are buildingHTML5 awesomeness  and whatnot.So I say, go and build and start solving

problems. Whatever is annoying to you,figure out a way to fix it. I’m sure thatyou’re one of a few people, but releasethe information and put it on Github,fork it, play with it and keep spurringand sparking other people.

 What has been your involvement/contributions in the Web Standards

Project and InterAct?

I did some work with them in 2009and partnered with a woman namedStephanie Troeth  who is a badassUX Designer who also currently doessome consulting work for MailChimp.Stephanie and I developed the ProjectManagement curriculum  together.The InterAct group built that and thenbasically stopped. Since then, herehasn’t really been a lot more activity withInterAct -- it’s been somewhat dormantsince everyone who was part of it hasbeen doing a lot of other work. So,that was my contribution and that’s upon the site and I think that’s becomingpart of the W3C’s curriculum which isvery cool. For everybody who wants todo project management or a numberof things such as web design anddevelopment can get that informationand get it for free. Then they can eitheruse it in a class or teach themselves, orwhatever they want.

How did you become involved with

this project?

My love of web standards is what gotme involved in the Web StandardsProject. I had been watching their workand wanting to be involved with it from

2002 - 2003. So imagine how delightedI was to be at South by Southwest in2009 and have them approach meabout getting involved in the WebStandards Project! I was at a party and talking to GlendaSims  who is one of the people whowas in charge of the Web Standards

Project. I told her that I used to teachweb design and web developmentand she suggested I get involved inthe education branch of WASP calledInterACT. She made the connectionsand it just worked out. It was great tobe a part of it and to get to work withthe people that I worked with on theproject and making the curriculum.It was really enjoyable. I kept beingable to do the kind of work that I do -instructional design, so it’s great to beable to do this and contribute to thegreater good.

18 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 80/130

TERVIEW DENISE JACOBS

How much does well or poorly designedCSS impact site performance? I don’t necessarily think it impacts thesite performance much. I think the moretelling impact it has is on the peoplewho are working on the site and howeasy it is to add, modify and find styles.Almost everybody I have talked to hasshared the sentiment that looking atsomeone else’s CSS code is almost aspainful as being poked in the eye with

a stick. So, the easier it is to access your

code, look at it, sandbox stuff so thatwhen multiple people have their handsin it, they can read it easier, the better. In terms of the performances -Steve Souders  at Google is a webperformance/web optimization guru.He talks a lot about HTTP requests andspeed, especially speed and velocity.In terms of speed itself, the more CSSyou have and the more you have crazyselectors that are built on elements

very high up in the DOM, like a body

DENISE JACOBSABOUT CSS AND PERFORMANCE

19 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 81/130

TERVIEW DENISE JACOBS

tag with a class or a body class withan ID or something like that, then thelonger it takes to resolve that style.It’s not necessarily perceivable to ussince we humans don’t perceive timewell. But, certainly it is something that

is measurable. Also, I think it affectsthe backend in terms of what thedevelopment team is dealing with andwhat they have to do and it makes thewhole process inefficient.

 When you code CSS, how much doyou do by scratch vs. using tools suchas CSS Generators?

I usually do it by scratch. I don’tusually use tools like CSS generatorsunless I’m doing gradients. I’ll use agradient generator because gradientsare painful. I use the ColorZilla CSSGradient Editor because it has all of thedifferent permutations and it keeps upwith the syntax between the differentbrowsers and has the vendor prefixesand has them in the right order and allof that good stuff. It’s a pretty powerfultool, pretty awesome.

 What are some tools or techniques we can use to develop more efficientCSS?

I’m not developing much any more butI still like text editors. I’ve been using

TextWrangler on the Mac, but I usedNotepad ++ on a PC. I know a lot ofpeople use Coda, there’s such a longlist of editors. If I were coding more, Iwould be more into them, but becauseI’ve been spending so much timespeaking and writing etc, I’m not in thatworld any more. But some things I thinkare helpful tools and techniques are

scalable and modular CSS like OCSS,SMACSS CSS for Grownups.

Testing and troubleshooting?

For testing and troubleshooting, I ama strong believer in Firebug, ChromeDeveloper, Inspector and still the W3C Validator - the HTML and CSS validator- I know it’s old school, but it’s true. Itstill works. I had a project that I wasworking on earlier this year that hadsome craziness in IE8 and I found theproblem with the W3C Validator. CSSLint is still good to learn about CSSredundancy and how redundant yourstyles are.

 Any other tools we should be using?

There are a lot of people getting intothe preprocessors such as LESS andSASS who don’t know how they thingsbefore these tools. I haven’t gotteninto them, I am aware of them, I thinkthey do lovely things. But, I have also

talked to people who just like to know

“I would love to

see entity selectors for HTML entitiesthat start with theampersand and endwith the semicolon.” 

20 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 82/130

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 83/130

TERVIEW DENISE JACOBS

For incorporating differences inbrowsers?

I talked about the scalable stuff andsome of the differences in browsersin one of my presentations about

normalize.css  - which “normalizes”the css as opposed to a standardCSS reset. Different people havetold me they have different opinionsabout it. Some people like to start offwith HTML5Boilerplate. I looked atHTML5Boilerplate and it has a lot ofstuff in it -- a lot of stuff that isn’t alwaysnecessary. So I think it’s important to

understand what’s in it and understandwhat you can take out that you don’tuse so you can personalize it.

Do we still need to plan for“Progressful Degrahancement”?

I feel like because IE6 and IE7 aren’t thekey players as they were a few years ago,you don’t necessarily need to adopt anapproach like that. IE8 is still probablyhas a large user base. For example, myold computer I just replaced with thiscomputer had XP still on it because Inever upgraded to Windows 7 -- don’t judge me [laughs]. So I couldn’t use IE9even if I wanted to. I’m sure there arequite a number of people who are stillin that boat. So, it’s kind of choose your battlesor have a progressive enhancementapproach in the first place and buildthe site as if you were building it forsomething really low - which you wouldhave to have if you were to have a

mobile first approach anyway. So yes,

that’s it: the high-level methodologyfor developing CSS, or developinga site, is to already be approaching asite from a mobile first or responsiveperspective even if you’re not going tonecessarily going to do it. If you have

the thinking behind it so that anythingyou do is just building on that base.

22 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 84/130

TERVIEW DENISE JACOBS

Can you tell us about Rawk the Web(e.g., mission, goals, status, successstories, etc.)?

It’s a brainchild that I have not beenable to put out into the world to thedegree that I want to yet. I have a lotof ideas on how to expand it and makeit more of how I see it.

Basically I hear a lot of “I don’t knowthat many women who do things in thetechnical industry or I don’t know manypeople of color who do it either”. I speak

at a lot of conferences and, I have tosay, that when I go to conferences andif there are any brown people there, Iam surprised. Usually I can count on myfingers and toes out of a conference ofthousands of people the numbers ofpeople of color.

And there still aren’t that many womenat these conferences either! I met awoman at the Oredev conference inSweden - I loved that conference - shewas with her husband and they broughttheir baby. It was awesome. She said,

DENISE JACOBSOTHER PROJECTS

23 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 85/130

TERVIEW DENISE JACOBS

“We’re both developers and we bothwanted to be here and we both wantedto come and neither of us wanted tostay home.” I saw a couple of womenthere who were pregnant which wasgreat, but it’s very rare.

Part of the problem is conferenceorganizers not knowing how tofind people. But part of the otherproblem is that there are a lot of great,accomplished folks who aren’t visiblefor one reason or another. They are notmaking themselves visible on the web,they don’t know that part of being

considered an expert or an industry“rock star” is just letting other peopleknow about you and what you aredoing. So, I wanted to start somethingthat was a resource for people who werepotential rock stars but are currentlyinvisible.

A lot of people say “I see you speakat conferences, I want to speak atconferences too, what can I do?” andI’ll talk to them about speaking. Orthey say “I’m writing a book and it’snot finished” and I give them the low-down on writing. I tell them, “if youwant to write a book, this is what youhave to do....don’t do the same thing Idid!” because I made a lot of mistakeswhen it came to self-promotion. With Rawk The Web, I wanted to havea resources in a one-stop shop forpeople who want to be seen in the webindustry (or any industry for that matter)but who don’t know how to go aboutit. I mostly wanted to do interviews

with other women and other people of

color in the industry who have done it-- become rock stars -- so that peoplecan get inspired and see themselvesin those roles. A lot of times peoplesaid “It’s so nice to see you here: I feelbetter being here by seeing you here”.

I’ve even had white men and womenwrite me afterwards and say “I wasreally happy to see you on the stagebecause I see guys who look like meall the time and I don’t get to see adiversity of opinions and experiencesand I was really happy to see you therespeaking.” How cool is that?! 

I would like to go to more conferencesand not say oh there’s 20 women and180 men. I’d like to go to conferencesand start seeing more diversity onspeaker lineups, I would like to seemore diverse attendees, I would like tosee more web experts, industry expertslike Lea Verou and Dan Mall who youdon’t look at them and automaticallyexpect them to be a white guy. Notthat I have a problem with white guys --my boyfriend was a white guy [laughs].They’re great, but they’re not the onlyones. I think that even with getting morediverse attendees that knowing thatthere are more people that you wantto see at these conferences. One my“secret” nefarious plans with Rawk theWeb is to put together a Rawk the Webconference and have the whole lineupbe women and people of color. Justto have a lineup like that where it’s alltotally industry experts, all rockstars,all people who are badasses - it just

happens to be as opposed to other24 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 86/130

TERVIEW DENISE JACOBS

conferences where it’s all white guysand one woman and one brown person,instead it’s all women and all people ofcolor. I just think it would be cool. Thesepeople are all around everywhere andthey are amazing, they do amazing workand I just brought them all in one place.

For all the people who put conferencestogether and say they “couldn’t findanybody”, I would say “I have a wholeconference of them. I found them andthey’re all friends of mine.” Not hard. It would be such a great case in pointand the epitome and case in pointof what I’m trying to do in the world.

What I am trying to do as a person.Part of what I do is what I do becauseI love it and it’s who I am and it’s in thefiber of my being. But part of what Ido is also to show other people thatthey can do it too. I want people to seeme on stage and think, “Hey that’s awoman, I’m a woman, I can do that” orhave them say “Wait, she’s brown, I’m

brown, I can do that!”.

Success stories?

One of my followers on twitter,Senongo Akem  is half Nigerian andhalf American and we’d had a few

exchanges on Twitter. At one point, hecontacted me about how he could domore public speaking at conferences.We got on Skype and I told him I wasspeaking at the Future of Web Designin New York and, since he lives in New York, that I would put him in touch withthe right people to take part in a trackcalled “Rising Stars” where there were

several spots still unfilled. So, I put himin touch with the conference organizerand made an introduction. The other reason I wanted him tospeak there is because he was talkingabout multicultural considerationsin web design. Not just localizingwith language, but localizing through

25 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 87/130

TERVIEW DENISE JACOBS

visuals, colors, cardinal directions andall kinds of things. I knew this wasa really important presentation forpeople in web design to see. It was verytimely and important information. Notonly had he grown up in both Nigeria

and the US, but he lived in Japan for7 years and his wife is Japanese. Hehas experiences that the average webdesigner in the U.S. is probably notgoing to think about and they are notgoing to have the range of experienceshe has. If he wasn’t the right messengerfor this content information, I don’tknow who is.

 He was nervous and hesitant at first,but he did an awesome job and gotgood feedback. I was so proud! So,that’s what I’m talking about. It’s soimportant that I want to continue toproliferate this level of opportunity andI want to be the one who helps peoplemake that change in their lives.

Can we look forward to more booksfrom you in the future?

 Yes. I have several ideas for books.Most of them are around creativity andthe creative process. At this point, I’mnot sure if I’m going to try to publishthem through a standard publisher ortry to publish them myself, so we’ll seehow it all shakes down.

Also, through Rawk the Web, I waslooking through all of my ideas that Iwould love to implement if I had thetime and resources. That’s always theconundrum - Have the money but

don’t have the time; or have the time

but don’t have the money. I’d like to doan eBook series through Rawk the Webon a lot of the things I’ve been talkingabout like speaking, self-publishing,self-branding, and things like that.Applying the visibility, teaming up and

collaborating to be able to create greatideas. I have several ideas in the works.

I have a feeling next year is going tobe a much more prolific year for me inregards to the things I am writing andputting out into the world. This yearwas kind of a retreat year and next yearwill be and advance year.

In what ways do you practice beingthe change you want to see in the world?

I call it “the transformative power ofcreativity” because I feel like embracingand expressing my creativity haschanged my life in a really positiveway. So I plan to continue to do thisand hopefully encourage other peopleto do it as well. Through my actionsand the way I am in the world I hopeto help people see that those thingsare possible. Things that were biggoals and dreams of mine that I haveaccomplished that when I look at them- I can’t believe what I’ve been able toaccomplish - this was my dream to bea published author. The potency of itcame from the desire to be a publishedauthor and then realizing that I am. I’vebeen wanting to be a creative person -and I am.

Then I have these moments when I

going to a conference to speak and I26 of 27 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 88/130

TERVIEW DENISE JACOBS

think, “I’m on another airplane...wait,I’m on another airplane!” It’s amazing --I wanted to be an international speakerand I am! So when I think about thingslike that, I think I have experiencedhaving a really important goal or dream

and then realizing it and I would liketo give back to other people and havethem feel that.

Several years back, I had momentswhere I was sitting in the office cryingafter a team meeting because mymanager decided that was the time hewas going to dress me down in front

of everybody and telling me “youneed to be in the office by 9 in themorning at the latest!” when no oneelse on the team needed to be. Orwhen I was working and doing painfulproject management and thinking “I just want to do something creative withsomebody, please!” And now, 4 years later, I am doing thething that I’ve been saying I’ve beenwanting to do for years. I’ve beensaying that I want to be an evangelistand telling this to people for years. Ithought “well, if no one is going tohire me to be an evangelist then I’m just going to be an evangelist on myown until someone realizes that I’mawesome and wants to hire me to doit.” But I went ahead and just startevangelizing on my own. So, it’s amazing and I think that bymy example, without even talking topeople that people can see that andsay “wow I am really inspired by that”.

There are a lot of other people who

inspire me and I have goals that I’mstill moving towards and hoping toachieve because of how other peoplehave inspired me. So, I just hope thatI can inspire other people to makechanges that help their lives and help

them move forward as well. Ultimately,I just hope that I can continue to inspirepeople and help them do what they dobetter. That’s kind of all I can ask for.

 As a Sagittarius, where will you shootyour arrow next?

The thing that is that I have been doing

all of this stuff independently. So, mynext goal is to team up with people-- I don’t want to keep being a lonewolf. Ideally, I’d like to be part of ateam of people who are evangelizing,who I can work with and have morefirepower behind me to make a lotof these ideas I have for events andcontent that I want to put out in theworld happen. That way, I can have areally good foundation to move fromand put things forth. I’d like to havea home or a team of folks that I workwith that do this. That’s my next mainthing because I have so many ideas andso many things I want to write aboutand so many pieces of information andworkshops I want to develop and createand put out. I’m ready! It’s been hard todo it on my own to try to manage that,plus client work, plus the speaking, plusthe travel, etc. It’d be nice to have itall in one complete, coherent package.That’s where my focus is going to befor the next little while: discover who Ican team up with and then go out and

kick some butt!

TERVIEW BY MAILE VALENTINE

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 89/130

appliness LIBRARY OF THE MONTH GRUNT BOOKMARK / SHARE / TO

Grunt: A build toolfor front-end projects

by FredericHemberger

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 90/130

BRARY  GRUNT: A BUILD TOOL FOR FRONT-END PROJECTS

by FredericHemberger

2 of 7 

Most front-end developers already use some kind of build processes for their projects,even if the might not know – or don’t use the term for it: They concatenate files forproduction, minify JavaScript code to speed up page loading and convert Sass or Lessfiles into CSS for the browser.

Grunt helps to manage all these steps in one single location and orchestrate thirdparty components.

All previously existing solutions had their roots in different areas of programming. Asthey were not primarily built for front-end development, all of them had their ownquirks and hindrances. Some involve knowledge of other languages (make, rake) oruse individual XML dialects (ant, maven), which have to be learned at first and weren’teasy to customize.

So why not have a tool explicitly built for the web workflow written in a language front-end developers work with every day, making it easy for them to modify and enhancethis tool to their needs? Grunt is written entirely in JavaScript and running on Node.js,it can be used on various platforms.

Grunt is already around for a while, but underwent some major changes in the freshlyreleased version 0.4: Now it only consists of a small command line client and a core

task runner. All further functionality is based on plug-ins, so you can set it up for yourspecial project needs without any bloat.

Grunt and all its plug-in dependencies are bundled within your project directory tomake sure that everything you need to build and ship your project always stays in place.And if you check in the configuration settings into your Subversion or Git repositories,everything can be set up in no time.

Even if Grunt is still quite at an early stage, there are already plenty of plug-ins, for

WHY ANOTHER BUILD TOOL?

HELLO GRUNT!

“With Grunt, front-enddevelopers have a very

flexible tool at hand”

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 91/130

(almost) all your development needs:

Minification of JavaScript and CSS, integration of pre-processors for CSS andJavaScript like Sass/Compass, Less and Stylus, CoffeeScript or LiveScript, file sizeoptimization for PNG and JPEG image files and automatic inlining and spriting of

images.

If you plan to write larger web applications, Grunt also integrates optimizations withRequire.js and Google Closure Compiler and lets you precompile your templatesfor Handlebars, Jade, Underscore, Mustache, Eco or Hogan. There are also alreadyplug-ins for the most common testing frameworks like Jasmine, Mocha, QUnit, andCucumber.

All available plug-ins are linked on the Grunt website (and if someone publishes a

new Node.js module with the keyword “gruntplugin”, it is automatically added tothe list).

So as you can see, Grunt does not only help you building your project, but alsoserves as central configuration hub for external tools.

Now you have a first impression what Grunt is all about, it’s time to get started.First of all, be sure that Node.js is installed on your computer. There are installersavailable for various platforms, which let you start right away. Open a terminal andtype

npm install grunt-cli -g

to install the Grunt command line tool.

Older versions of Grunt came with a set of predefined core tasks. In order to be

more flexible and customizable, they were removed in the recent 0.4 release andcan be installed as individual tasks plug-ins, which leave you with a little bit morework to set up:

First, create a file in the root folder of your project called package.json. If you’refamiliar with Node.js, you may already be familiar with this file, we’ll start with themost basic one for our project.

INSTALLATION AND GETTING STARTED

3 of 7 

BRARY  GRUNT: A BUILD TOOL FOR FRONT-END PROJECTS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 92/130

{  “name”: “my-project-name”,  “version”: “0.1.0”,  “devDependencies”: {  “grunt”: “~0.4.0”,  “grunt-contrib-jshint”: “~0.1.0”,

  “grunt-contrib-concat”: “~0.1.1”,  “grunt-contrib-uglify”: “~0.1.0”,  “grunt-contrib-watch”: “~0.1.4”  }}

Besides the name and the version of our project, it lists the dependencies neededfor development. We are going to install Grunt with some of the most basic tasks.Open up the Terminal (or Command Prompt on Windows), change to your projectdirectory and type npm install.

After Grunt and all the dependencies needed for our project are installed, it’stime to start with the Grunt configuration itself. Therefore, we add a file calledGruntfile.js to our project root, next to the previously created package.json file.

A basic configuration file might look like this:

module.exports = function(grunt) {

  // Initializes the Grunt tasks with the following settings  grunt.initConfig({

  // A list of files, which will be syntax-checked by JSHint  jshint: { … },

  // Files to be concatenated … (source and destination files)  concat: { … },

  // … and minified (source and destination files)  uglify: { … },

  // Tasks being executed with ‘grunt watch’  watch: { … }  });

  // Load the plugins that provide the tasks we specified in package.json.  grunt.loadNpmTasks(‘grunt-contrib-jshint’);  grunt.loadNpmTasks(‘grunt-contrib-concat’);

4 of 7 

BRARY  GRUNT: A BUILD TOOL FOR FRONT-END PROJECTS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 93/130

  grunt.loadNpmTasks(‘grunt-contrib-uglify’);  grunt.loadNpmTasks(‘grunt-contrib-watch’);

  // This is the default task being executed if Grunt  // is called without any further parameter.

  grunt.registerTask(‘default’, [‘jshint’, ‘concat’, ‘uglify’]);

};

So you see all the configuration you need is purely written in JavaScript. Basically,you need three different functions to work with Grunt: grunt.initConfig,grunt.loadNpmTasks and grunt.registerTask.

The first one defines all options and parameters for all the tasks you plan to use,

the tasks itself are loaded with grunt.loadNpmTasks.

Each task can be called separately from the command line by passing it’s name asa command line parameter: For example

grunt jshint

would only execute the linting task of your project. With

grunt.registerTask

you define a default task to run when Grunt is called without any parameter. Itexecutes the listed tasks in the given order, in our case “jshint”, “concat” and“uglify”.

CHECKING YOUR JAVASCRIPT WITH JSHINT

JSHint is a tool to detect errors and potential problems in your JavaScript code,for example the proper setting of semicolons, unclosed brackets or functions calls,which were not defined before. It also helps spotting typos, which might take longto find during debugging in the browser.

If you’re working on a larger project, it’s also a great help to enforce codingconventions for your team. It’s very flexible and can easily be adjusted to your

EXAMPLE GRUNT TASKS

5 of 7 

BRARY  GRUNT: A BUILD TOOL FOR FRONT-END PROJECTS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 94/130

needs.

For this plug-in, all files that should be checked are listed in an array:

jshint: {

  files: [‘Gruntfile.js’, ‘lib/**/*.js’]},

In this example, the Grunt configuration itself is checked first, afterwards allJavaScript files in all subfolders of “lib”.

CONCATENATION OF FILES

This is a so called “multi task”. You can specify multiple groups of files which will

be concatenated. The name of the groups is up to you, it just needs to be a validJavaScript identifier:

concat: {  js: {  src: [‘lib/module1.js’, ‘lib/module2.js’, ‘lib/plugin.js’],  dest: ‘dist/script.js’  }  css: {  src: [‘style/normalize.css’, ‘style/base.css’, ‘style/theme.css’],  dest: ‘dist/screen.css’  }},

During the build process, all files in these groups will be concatenated. If you justneed to update one particular part, you can pass the task’s name as parameter,e.g. grunt concat:css.

MINIFICATION

Minifying your JavaScripts works the same way: You can set up one or multiplegroups of files to be processed. To spare you typing the same file names over andover again, you can reference file names from other tasks as well. In this example,we’ll reuse the target of the JavaScript concat task before (‘dist/script.js’):

uglify: {  dist: {  src: [‘<%= concat.js.dest %>’],  dest: ‘dist/script.min.js’

6 of 7 

BRARY  GRUNT: A BUILD TOOL FOR FRONT-END PROJECTS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 95/130

  }},

AUTOMATIC EXECUTION OF TASKS

All important steps are configured now, the build process is running smoothly.But what can be more annoying than running the process manually over and overagain?

With the »watch« task plug-in, you can execute tasks automatically in the backgroundeach time a set of files changes in your project:

watch: {  files: ‘<%= jshint.files %>’,  tasks: ‘jshint’

},

Starting Grunt with grunt watch, the “jshint” task will be executed as soon asone JavaScript given in the file list of the jshint task-configuration changes.

With Grunt, front-end developers have a very flexible tool at hand which helps a lotwith automating reoccurring tasks. Once set up, you can either let the watch taskdo it’s magic in the background, or integrate Grunt into your IDE or coding editoras external build command (which works great in Sublime Text, for example).

The code validation and testing increases overall quality and helps you maintain aconstant coding standard, which makes Grunt also a perfect tool for teams workingon large scale projects.

THE BOTTOM LINE

Frederic Hemberger

Web Expert

HIS BLOG

TWITTER

SHARE

GITHUB

BRARY  GRUNT: A BUILD TOOL FOR FRONT-END PROJECTS

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 96/130

appliness  VISION CSS BOOKMARK / SHARE / TO

JSCAMP: CSS next

by DivyaManian

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 97/130

SION JSCAMP: CSS next

by DivyaManian

2 of 8 

I talked at JSCamp on 28th November 2012, on some of the newer features of CSS. Igave the talk without slides, so here is a description of all that I covered.

Before I delve into what the newer features of CSS that I am very interested in are,I want to clarify a myth that persists on how there are varying ‘versions’ of CSS like

CSS3 and CSS4. Tab Atkins wrote in detail about why there is no CSS3. Essentially,work after CSS 2.1 specification has been split into independent modules that can allreach stability independent of each other, so specifications can become stable andrecommendations faster.

Open Type Fonts have a features file that exposes ligatures (and other features) to

NO CSS3 OR CSS4

OPEN TYPE FEATURES

“My team is working on aspecification & prototype buildthat brings the power of blend

modes to the web via CSS.”

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 98/130

applications that understand and enable these. Till recently browsers did not havethe ability to expose these features that would allow you to use these ligaturesfrom within stylesheets. But now you can.

To do this, you would have to use font-feature-settings like so (you must add the

appropriate prefixes -ms, -webkit- & -moz- & -o- when Opera supports it):

h1 { font-feature-settings: ‘liga’;}

This tells the browser to enable Common Ligatures in the Open Type font.

Georg Seifert of Glyphs has created a very cool font that exploits these ligatures

to create a lovely clock.

Fonts are essentially a table of glyphs that represent each code point. Browserslook up the table for each code point and render that glyph on the screen.

The @font-face rule used to specify web fonts can include a declaration for unicode-range. When this property is declared, the browser knows that the font specified

in the @font-face rule must only be used when that range of unicode code points are found in text. This way, you can control the rendering of English letters whenthey occur in conjunction with letters of another language instead of defaulting tosystem fonts. Here is how you would use them:

@font-face {  font-family: myJapanesefont;  src: local(‘Bookman Antiqua’);  unicode-range: U+41-5A, U+61-7A, U+C0-FF;}

h1 {  font-family: myJapanesefont, MS-Mincho;}

But this property is also useful if you want to specify better ampersands or usefonts as icons.

UNICODE RANGE

3 of 8 

SION JSCAMP: CSS next

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 99/130

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 100/130

  flow-into: newsflow; /* name of the flow */}

Then, you declare which elements will be the recipients of the content within thenamed flow:

.news-items-container {  flow-from: newsflow; /* name of the flow */}

This means, all elements that have the class news-items-container will no longerdisplay content they originally had, but will only display content that flows intothem through the named flow called newsflow.

The Web Inspector in Chrome Canary has a way to debug which elements are partof a flow and which are recepients of a flow.

It is now possible to use image processing functions such as greyscale, sepia,blur on HTML and SVG elements. You can do this by using a CSS property knownas filter like so:

.banner {

  filter: blur(10px);}

These are known as native filters as the functions are provided out of the box bybrowsers. You can use this feature in Safari 6, Mobile Safari & Chrome.

Here is how blur has been used to simulate depth of field.

Instead of using browser-provided filters, you can use your own. To do this, youwould use GLSL shaders  - that are typically used in WebGL - via custom filterfunction.

.banner { filter: custom(url(/path/to/shader.vs));}

NATIVE FILTERS

CUSTOM FILTERS

5 of 8 

SION JSCAMP: CSS next

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 101/130

The above declaration tells the browser to create vertice maps for each elementthat matches the selector, run them through the shader provided within the customfunction and finally render the results on the screen. The interesting thing is theseshaders can also take custom arguments that would determine the extent to whichyou want to apply these shaders.

Altered Qualia has a great in-depth article on how to write and use Shaders forCustom Filtering. You can also play with some of the custom filters on CSS FilterLab

In Photoshop and other Graphic Editing tools, there has always been an option tospecify how each layer interacts with other layers below it. This is typically specifiedusing a dropdown of blend modes that have values such as ‘overlay’, ‘multiply’,

‘darken’, ‘lighten’, ‘difference’, etc.

My team at Adobe has been working on a specification and a prototype build outthat brings the power of those blend modes to the web via CSS. This would happenvia specifying the property blend-mode on the elements you want to target:

.banner h1 {  blend-mode: difference;}

 You must use styles responsibly, especially properties such as flex box which can leadto drastically unreadable results in unsupported browsers. Previously, Modernizr came to the rescue. But now, there is a specification that adds conditional rules natively via @supports:

@supports (font-feature-settings: ‘liga’) or  (-webkit-font-feature-settings: ‘liga’) or  (-moz-font-feature-settings: ‘liga=1’) {  h1 {  font-family: ‘A Common Ligatured Font’, serif;  }}

Browsers that understand @supports would then check if any of the declarations(font-feature-settings: ‘liga’ or -webkit-font-feature-settings:

BLEND MODES

RESPONSIBLE STYLING

6 of 8 

SION JSCAMP: CSS next

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 102/130

‘liga’) is supported and if so, render the styles for the h1 selector within the @supports rule. This way of writing CSS may be familiar to you via Media Queries.

This is a great way to do feature-detection natively and specify different rules whenadvanced features are supported while providing a basic but readable experience

on other browsers. Chris Mills has written in greater depth about this rule on dev.opera.com

@supports rule is available in Opera and Firefox (under a flag), and soon in WebKit.

WebKit browsers have had, for more than 2 years, support for writing to a canvas

that is used as a background image for elements. This is specified as such:

.banner {  background-image: canvas(contextForCanvas);}

Instead of writing the pixels to the context of a Canvas element, you would writeit to the context of that background image (contextForCanvas):

var context = document.getCSSCanvasContext(‘2d’, contextForCanvas, canvasWidth, canvasHeight);

The use of canvas as a background image is somewhat similar to a Mozilla proposalto have elements as background images:

.banner {  background-image: element(#elementID);}<div class=’banner’>This is a banner</div><p id=’elementID’>This is the element that will be a background.</p>

Simurai created this interesting kalaidescope effect using this property.

Personally, I find the element function confusing and easy to make mistakes with(e.g. adding a twitter widget to a supposedly empty element suddenly has it appear

CANVAS AS BACKGROUND IMAGE

ELEMENTS AS BACKGROUND IMAGE

7 of 8 

SION JSCAMP: CSS next

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 103/130

SION JSCAMP: CSS next

as a background to another element). Hopefully, some middle-ground betweencanvas as a background image and elements as a background image will be arrivedat.

There are lots of new and interesting features out there and it would be awesome ifyou could take the time to play with them and provide feedback. There are plentyof new features I did not cover because I thought I was out of time (I wasn’t!) likeFlexbox, Grid Layout, Variables, Calc(), and more.

My talk was just several browsers each with pinned tabs of each demo. Here is alist of all of the demos I showed.

CONCLUSION

Divya ManianWeb PM at Adobe

HER BLOG

TWITTER

SHARE

GITHUB

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 104/130

appliness TUTORIALS CSS BOOKMARK / SHARE / TO

CSS Things ThatDon’t Occupy Space

by LouisLazaris

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 105/130

UTORIALS CSS THINGS THAT DON’T OCCUPY SPACE

by LouisLazaris

2 of 6 

In most cases, when you place an element on the page inyour markup, if you don’t specify any special styles, it willoccupy exactly the same space that it appears to occupyvisually.

In other words, if you place a box sized at 200px by 200pxon your page, anything you place after it in the source order,

with no further styles added, will occupy the space below orbeside the green box, outside of those set boundaries.

But not everything on an HTML page occupies space that is honored by other elements.I thought it would be interesting to list and describe all the things in CSS that don’toccupy this kind of physical space in an HTML document.

This means any element that is set to position: absolute or position: fixed.These elements are taken out of the document flow, so elements that appear after themin the source order will not flow around or below them. So basically, other elementsbehave as if the absolutely positioned elements are not even there.

 Launch JS Bin demo

ABSOLUTELY POSITIONED ELEMENTS

“Not everything on anHTML page occupies space

that is honored by otheelements. ”

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 106/130

UTORIALS CSS THINGS THAT DON’T OCCUPY SPACE

Unlike absolutely positioned elements, elements with position: relative dooccupy space. But the offsets that you specify on relatively positioned elementsusing top, right, bottom, or left, do not occupy space. This might seem a bit

odd at first, but look at this example:

 Launch JS Bin demo

The pink box follows the blue box in the source order, so naturally, the blue box’soccupied space is not available. So the pink box drops below. Next, the fact that

the blue box is relatively positioned and then offset, causes the blue box to move.But this offset (20px from the top and 20px from the left) does not affect theposition of the pink box. This is because the offset space on a relatively positionedelement does not occupy any space.

The outline property is very much like the border property, the difference beingthe fact that outlines don’t add to the occupied space of the element on which the

outline is applied. This is why web developer tools can use outlines to highlightelements for debugging purposes, without causing elements around it to move orreposition themselves.

Look at this example:

OFFSET VALUES FOR RELATIVELY POSITIONED ELEMENTS

OUTLINES

3 of 6 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 107/130

UTORIALS CSS THINGS THAT DON’T OCCUPY SPACE

 Launch JS Bin demo

Notice that the blue box has a 50px solid yellow outline. The outline overlaps thepink box below it, rather than pushing it down, as would happen if you change theoutline to a border.

Transforms, in many ways, have similar behaviour to relatively positioned elements.The most obvious types of transforms that do this are translation transforms,declared using the translate() function.

Translating an element using thetransform

 property will cause the transformedelement to reposition itself, pretty much the same way discussed above underrelative positioning. This means that the original space occupied by the elementwill remain intact, as if the element hasn’t moved. But the offset created by thetranslation does not occupy space.

 Launch JS Bin demo

OFFSETS CAUSED BY TRANSFORMS

4 of 6 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 108/130

UTORIALS CSS THINGS THAT DON’T OCCUPY SPACE

Similarly, when an element is rotated, skewed, or scaled, the original space occupiedby that element is honored, but any areas covered by offsets due to any of thesetransforms will not affect the flow of other elements around.

Box shadows and text shadows both fall under the category of elements that don’tcause reflow around them, thus not occupying any actual space in the document.When shadows are applied, as is the case with all of the other features discussedin this post, they don’t affect the position of any surrounding elements.

 Launch JS Bin demo

In the case of shadows, this is actually significant when you’re trying to center anelement either vertically or horizontally. If an element has a shadow on a specificside and not the opposite side, this would make it appear not to be centered. Thisis because something like “margin: 0 auto” does not take into considerationthe size of the shadow when centering the element, so you might have to add anopposing margin or something if you think this affects the aesthetics.

Some other notable things that are created by means of CSS but that don’t occupyspace include:

  - WebKit Reflections  - IE-only proprietary filters  - text-decoration  - Elements with display: none, which are different from elements withvisibility: hidden, the latter of which do occupy space

SHADOWS

OTHER MISCELLANEOUS ITEMS

5 of 6 

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 109/130

UTORIALS CSS THINGS THAT DON’T OCCUPY SPACE

One important thing that should be pointed out here is that even though thesefeatures discussed above do not occupy space in the document, some of themmay cause scrollbars to appear if they are positioned in such a way as to render

outside a parent element, or outside the window.

Something like a text shadow would not do this, but a transformed or relativelypositioned element might. So although the offsets created by transforms orpositioned elements may not take up space or affect surrounding elements, theymay cause their parent element, or even the window, to create necessary scrollbars— unless of course the parent element in question is set to overflow: hidden.

The final thing I’ll say here is that, technically speaking, the phrase “doesn’t occupyspace” may not be the best choice here, even though I’ve used it throughout thispost.

When the spec discusses this sort of thing, it usually uses a phrase like “doesn’tcause reflow”. But I’ve tried to write this primarily with understandability in mind.I think it’s easy to understand what I mean when I say that something “doesn’toccupy space”, so in no way am I implying that my discussion here is semanticallycorrect. The concept is really more important than my choice of words.

WHAT ABOUT OVERFLOWS?

“OCCUPY SPACE” — MAYBE NOT THE RIGHT PHRASE?

Louis LazarisFreelance Web Developer

HIS BLOG

TWITTER

SHARE

GITHUB

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 110/130

appliness TUTORIALS CSS BOOKMARK / SHARE / TO

Discover CSS calc

by DavidWalsh

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 111/130

UTORIALS DISCOVER CSS CALC

by DavidWalsh

2 of 3 

CSS is a complete conundrum; we all appreciate CSS because of its simplicity butalways yearn for the language to do just a bit more. CSS has evolved to accommodateplaceholders, animations, and even click events. One problem we always thought we’dhave with CSS, however, was its static nature; i.e. there’s really no logic, per se. TheCSS calc routine bucks that trend, providing developers an ounce of programmingability within CSS.

WARNING: CSS calc only works on iOS 6 ! 

DEMO:

CSS & CODE

“CSS calc is another exampleof CSS taking over the role o

JavaScript in layout”

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 112/130

The calc routine is especially useful when calculating relative widths. Calculationscan be additions, subtractions, multiplications, and divisions. Have a look:

/* basic calc */.simpleBlock {  width: calc(100% - 100px);}

/* calc in calc */.complexBlock {  width: calc(100% - 50% / 3);  padding: 5px calc(3% - 2px);  margin-left: calc(10% + 10px);}

WebKit and Opera currently require a browser prefix for calc(). Be sure to usewhitespace around operators so that they aren’t construed as positive and negativenotations.

CSS calc is another example of CSS taking over the role of JavaScript in layout, andI think it’s a great thing. As we move more toward responsive design, calc allows usto use percentages for overall block widths, with just a touch of pixel help for someof its components. Have you used calc for your apps? Share how you used calc! 

THE CSS

David WalshWeb DeveloperMadison, Wisconsin

HIS BLOG

TWITTER

SHARE

GITHUB

UTORIALS DISCOVER CSS CALC

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 113/130

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 114/130

UTORIALS BUBBLING IN ENYO2

by DavidPosin

2 of 4 

”Bubble, bubble, toil and trouble” cry the witches of Macbeth. Clearly, they never triedusing Enyo 2 as their JavaScript framework or it would have been “Bubble, bubble,yahoo!”. The event bubbling system is one of the features that makes Enyo 2 feel sopowerful.

The bubble method allows events to be sent up the object hierarchy. This is not thesame thing as bubbling up the DOM. The object structure that is in memory can

be similar to the DOM, but the process will only work against the object hierarchy.Changes to the DOM will need to be rendered separately.

Events can range from UI interactions, such as a tap, to custom events that are firedmanually. Events will bubble starting at the originator and will continue to bubble untilan object handles it and returns true, or if there are no more objects. Events travel inthe form of “oneventName”, such as “ontap” or “onspecialEvent”.

An object in Enyo defines the events it can handle with the “handlers” property. An

Enyo object that responds to a tap event will have an “ontap” handler. The handlerproperty contains the name of the function to call when that event is handled. Theresult is that event and event handling are separated Event and event handling beingdefined arbitrarily provides a great method for decoupling objects and encouragingencapsulation.

INTRODUCTION

“‘Bubble, bubble, toi and trouble’ cry thewitches of Macbeth”

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 115/130

UTORIALS BUBBLING IN ENYO2

3 of 4 

Let’s take a look at a simple example (http://jsfiddle.net/dposin/nY2AD/):

This code uses 2 Enyo kinds to create a page with a “Blank Paragraph” and abutton. Enyo 2 uses the term kind in a way similar to class or type. A kind is adefinition of an object that can be instantiated. The button in the example is a newkind called BubbleButton. It uses the enyo.Button kind as a parent. The buttoncalls the tapped function when it handles an ontap event. Since ontap is a pre-defined event, the button will fire the ontap event when the user presses it with afinger or mouse click.

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 116/130

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 117/130

appliness TUTORIALS WEB STANDARDS BOOKMARK / SHARE / TO

About web standards,speed and time.

by MihaiCorlan

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 118/130

UTORIALS ABOUT WEB STANDARDS, SPEED AND TIME

by MihaiCorlan

2 of 4 

If your work targets the web then it is almost impossible not to hear something likethis: ”Man, the standards are moving so slow!” every now and then. Usually thisintroductory statement is followed by a second part that you wouldn’t say in front ofyour mom/dad/children.

Basically, the belief is that if there were enough motivation it would have been a matterof months (maybe weeks if you are the type who sees unicorns without consuming

stuff legal in Amsterdam and illegal in the rest of the world). Fewer people choose toquestion not the motivation/drive of the people involved in the standards but theirabilities: “if we only have smarter people there”.

If you believe that these are the two main reasons that prevent standards from movingfaster than let me tell you that YOU ARE WRONG!

Let me give you an example that illustrates the fact that things cannot be speed up bygetting the smartest people around and proper motivation. Let’s start with motivation.

What better motivation can a human have then fighting for his own survival? And whatabout having the smartest guys for the job actually on your team? Basically somethingeven better than an “A” team?

Such a thing actually happened in the 20thcentury. I am talking about the ManhattanProject  (this project created the first nuclearbombs). Despite having the best scientists ofthe time (and arguably one of the all time best),

people like Albert Einstein, Enrico Fermi, J.Robert Oppenheimer, and despite having thebest motivation (develop the atomic bombbefore the enemy or else the war could havebeen lost) they needed about seven yearsto complete the task while spending theequivalent of $25.8 billion and employing morethan 130,000 people.

“Web standards havelong passed the point o

becoming uncomplicated.”

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 119/130

UTORIALS ABOUT WEB STANDARDS, SPEED AND TIME

3 of 4 

The sad truth is that complicated things take time. And the web browsers and thestandards have long passed the point of becoming something that can be calleduncomplicated.

In the past two years I have been fortunate to work close with a team at Adobe

that is involved in writing CSS proposals and implementing those proposals inWebKit. I’ve seen ideas moving from inception to hacks/prototypes, and finally toproposals. You know things like CSS Regions, CSS Exclusions, or CSS Custom Filters.And I’ve seen how things that seem to be simple in isolation become complexwhen considering the whole. Basically, if you add something new to CSS you haveto make sure that it will play nicely with the rest of the CSS features.

Another thing you have to take into consideration is to make sure you havethroroughly thought though the security implications of a new feature. The Custom

Filter spec was on hold at some point this year because there was a possibility(although only theoretical) that a pixel shader could be used to find what linkswhere visited.

For browsers vendors a security issue is also something that can crash the browser.A poor implementation of a complex thing does crash the browser. No one wantsthis to happen at least not to his browser :D

If it sounds like there is nothing you can do to speed up this process then keepreading for some ideas :). I think that the people who use these standards in theirdaily jobs web developers and web designers can actually help. And from my pointof view these are things you can do:

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 120/130

UTORIALS ABOUT WEB STANDARDS, SPEED AND TIME

1. Make sure you follow the new standards that make sense to you (help yourprojects/clients). In the unicorn’s country you’d follow all the standards. In thereal world this is not going to work thus focus on what you’ve decided that it isimportant to you.

2. Create examples that use these standards and make sure you share them (blog

posts, conferences, etc). This is hugely important as it helps to validate a proposal.If more people find that spec useful and capable of solving problems then thereis a greater chance that that spec is spot on.

3. Make sure you are vocal about your support for your favorite new specs. Onegood example of being vocal is Mr. Stephen Hay aka Captain Flexbox. Let thepeople who are working on the proposal know what you’ve built and ask peopleinvolved in the standards what they think about these specs. These days if you goto a web conference at least here in Europe you could easily bump into peoplefrom W3C, Chrome, Mozilla, Opera, RIM, Nokia and so forth.

Of course I may be completely wrong here. And maybe these are not the reasonsfor why it takes time to get new standards supported in browsers. If you have adifferent opinion I’d love to hear it.

PS. Although I work for Adobe, this post represents my personal opinion and notmy employer’s.

Mihai CorlanDeveloper Evangelist

HIS BLOG

TWITTER

SHARE

GITHUB

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 121/130

appliness TUTORIALS JAVASCRIPT BOOKMARK / SHARE / TO

History managementin the browser

by RaymondCamden

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 122/130

UTORIALS HISTORY MANAGEMENT IN THE BROWSER

by RaymondCamden

2 of 8 

What follows is an example I built to help me learn how to manipulate browser historywith JavaScript. Do not consider this a tutorial, an example of best practices, or anythingmore than a personal learning exercise. This is a topic I’ve been meaning to learn formonths and I finally took the time to wrap my head around it today. I wrote some codethat seems to work well and wanted to share it, but keep in mind that I’m probablydoing it wrong. Want a good explanation? Try one of the links below:

  - Implementing pushState for twitter.com  - MDN: Manipulating the browser history  - Pushing and Popping with the History API

I began by creating a super simple remote service. It simply returns an array of stringsalong with a ‘total’ value. The idea being that the front end is going to allow you toview one ‘page’ of content at a time. This back end is written in ColdFusion and simplyreturns titles of my blog entries along with a total number of results. You may clickhere to see a sample of the JSON data.

The first iteration of the application was entirely client side. I wrote a quick and uglyapplication with simple Previous/Next links. Again, this is ColdFusion-specific, but youcould imagine this in any language.

<cfparam name=”url.page” default=”1”><cfset data = application.service.getData(url.page)> <h2>Titles</h2> 

<cfdump var=”#data.titles#”> <p/> <cfoutput><cfif url.page gt 1>  <a href=”?page=#url.page-1#”>Previous</a><cfelse>  Previous</cfif> /<cfif (url.page*10)+1 lt data.total>

LEARNING EXERCISE

“The idea being that thefront end is going to allow you to view one ‘page’ o

content at a time.”

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 123/130

  <a href=”?page=#url.page+1#”>Next</a><cfelse>  Next</cfif></cfoutput>

LAUNCH THE DEMO IN YOUR BROWSER

Obviously this is kind of a lame example, but if you imagine the page using “real”layout, then every page would be a complete reload of header graphics, CSS, etc.

In the next iteration, I rebuilt the front end using JavaScript. This is also kinda ugly,but it uses XHR to fetch pages of content.

<html lang=”en”><head></head> <body> <h2>Titles</h2> <div id=”dataDiv”></div> 

<p/> <button id=”prevLink”>Previous</button> / <button id=”nextLink”>Next</button> <script>var page=1; function $(e) { return document.querySelector(e); } document.addEventListener(“DOMContentLoaded”, init, false); 

function init() {  loadData(); 

$(“#nextLink”).addEventListener(“click”, handleNext, false);  $(“#prevLink”).addEventListener(“click”, handlePrev, false);} function loadData() {  var req = new XMLHttpRequest();  req.open(“get”,”../api/service.cfc?method=getdata&page=”+page);

3 of 8 

UTORIALS HISTORY MANAGEMENT IN THE BROWSER

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 124/130

 req.onload = function(e) {

  var result = JSON.parse(e.currentTarget.response);  var titleHTML = “”;  for(var i=0; i<result.titles.length; i++) {  titleHTML += result.titles[i]+”<br/>”;

  }  $(“#dataDiv”).innerHTML=titleHTML; 

if(page > 1) {  $(“#prevLink”).removeAttribute(“disabled”);  } else {  $(“#prevLink”).setAttribute(“disabled”,”disabled”);  } 

if((page*10+1) < result.total) {  $(“#nextLink”).removeAttribute(“disabled”);

  } else {  $(“#nextLink”).setAttribute(“disabled”,”disabled”);  }  } 

req.send();} function handleNext() {  page++;

  loadData();} function handlePrev() {  page--;  loadData();} </script></body></html>

LAUNCH THE DEMO IN YOUR BROWSER

Better, right? Now each page is loaded without a full page reload. You can quickly jump back and forth to different pages. But it has two issues that the History APIcan help with. First, it doesn’t allow you to bookmark a page. Second, if you use

4 of 8 

UTORIALS HISTORY MANAGEMENT IN THE BROWSER

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 125/130

your browser’s back button, you actually end up leaving the page entirely.

Using the History API is - for the most part - pretty simple. You can use pushStateto update the URL of the browser (but not the title, all the browser vendors ignorethis) as well as push information to the new page. So a simple example may look

like this:

history.pushState({something:1, somethingelse:2}, “Title that won’t workfor crap”, “index.htmlORcfmORphp?anythingheretoo”);

Note that third argument there - you really can change the URL to anything. SoI could switch to index.ruby if I wanted. But here’s the crucial bit - if the userbookmarks that URL and returns to it later, your server better respond to it.

The other part that confused me was the first argument. I kept thinking of it as dataI was sending to the new page. That isn’t exactly right. Rather, you are associatingdata with that part of your history. I don’t think I’m doing a great job explainingthis, but think of it as data you want to use when, in the future, you return to thisnew history item you are creating. So for example, going from page 1 to page 2,I’ve passed an object. When I go to page 3, and then hit back to page 2, then Imake use of that object.

 You make use of that data using the popstate event handler.

window.addEventListener(“popstate”, handlePop, false);function handlePop(e) {  console.log(“You’ve returned! Here is what I have in my state... “);  console.dir(e.state);}

Now - here is where things get tricky. In Chrome, if you listen for the popstateevent, you get one immediately after the page loads. If you use Firefox, you don’t.From what I know, the draft spec says you should get one on page load, so Firefox

is wrong here, but it is a draft spec, not a final spec.

That made things very tricky for me. I essentially had to figure a way to ignorean initial popstate event in Chrome but not in Firefox. I found some possibleworkarounds, but none that worked well for me.

I finally came to a realization. I only needed to worry about popstate once I’vemade at least one change. So I simply wrote some simple code that waited until

5 of 8 

UTORIALS HISTORY MANAGEMENT IN THE BROWSER

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 126/130

you had loaded your first new page and then registered the event listener.

//earlier...var didOnce = false;//more junk here.. 

if(!didOnce) {  didOnce=true;  window.addEventListener(“popstate”, handlePop, false);}

Make sense? Here’s the complete new version. It isn’t that much different from theearlier version. Also note the support for checking location.search on page load.This allows me to handle a bookmarked version of the application. (That codecould be tighter!)

<!doctype html><html lang=”en”><head></head> <body> <h2>Titles</h2> <div id=”dataDiv”></div>

 <p/> <button id=”prevLink”>Previous</button> / <button id=”nextLink”>Next</button> <script>var page=1;var didOnce=false; function $(e) { return document.querySelector(e); }

 document.addEventListener(“DOMContentLoaded”, init, false); function init() {  if(location.search) {  //remove ?page=  if(location.search.indexOf(“?page”) === 0) {  console.log(“note we are on a specific page”);  page = location.search.split(“=”)[1];  }  }

6 of 8 

UTORIALS HISTORY MANAGEMENT IN THE BROWSER

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 127/130

  loadData(); 

$(“#nextLink”).addEventListener(“click”, handleNext, false);  $(“#prevLink”).addEventListener(“click”, handlePrev, false);} 

function handlePop(e) {  console.log(“pop”);  if(!e.state && page != 1) {  page=1;  loadData();  } else if(e.state) {  page = e.state.page;  loadData();  }} 

function loadData() {  var req = new XMLHttpRequest();  console.log(“lets load page “+page);  req.open(“get”,”../api/service.cfc?method=getdata&page=”+page); 

req.onload = function(e) {var result = JSON.parse(e.currentTarget.response);

  var titleHTML = “”;  for(var i=0; i<result.titles.length; i++) {  titleHTML += result.titles[i]+”<br/>”;

  }  $(“#dataDiv”).innerHTML=titleHTML; 

if(page > 1) {  $(“#prevLink”).removeAttribute(“disabled”);  } else {  $(“#prevLink”).setAttribute(“disabled”,”disabled”);  } 

if((page*10+1) < result.total) {  $(“#nextLink”).removeAttribute(“disabled”);

  } else {  $(“#nextLink”).setAttribute(“disabled”,”disabled”);  } 

if(!didOnce) {  didOnce=true;  window.addEventListener(“popstate”, handlePop, false);  }  } 

7 of 8 

UTORIALS HISTORY MANAGEMENT IN THE BROWSER

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 128/130

  req.send();} function handleNext() {  page++;  history.pushState({page:page}, “Titles - Page “+page,”index.

html?page=”+page);  loadData();} function handlePrev() {  page--;  loadData();} </script></body>

</html>

I tested this in Chrome and Firefox and it seems to work reasonably well. Check itout below.

LAUNCH THE FINAL DEMO

Raymond CamdenDeveloper Evangelistat Adobe

HIS BLOG

TWITTER

SHARE

GITHUB

UTORIALS HISTORY MANAGEMENT IN THE BROWSER

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 129/130

appliness NEWS BY BRIAN RINALDI BOOKMARK / SHARE / TO

MultipleInheritance in ES6

with Proxiesby Jussi Kalliokoski

FlashlessAnimation

byRachel Nabors

CSS 

Architectureby PhilipWalton

Perfor-mance

with Stringby PanagiotisTsalaportas

HTML5 Datalistto provide

autocompleteby David Walsh

Scriptloaderpattern

by PhilipTellis

Canvas-drivenbackground

imagesby Eric Bidelman

WebRTChits Firefox

by SamDutton

CSSClick

Eventsby HugoGiraudel

Redesigning theMedia Query

byLes James

appliness MORE NEWS ON HTTP://REMOTESYNTHESIS.COM/

8/13/2019 Appliness #10 – January 2012

http://slidepdf.com/reader/full/appliness-10-january-2012 130/130

appliness EOF FOLLOW US BOOKMARK / SHARE / TO

Now what?SUBSCRIBE TO OUR 

MONTHLY  NEWSLETTERN

FOLLOW US

ON TWITTER