Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Web and mobile development with HTML5, CSS3, JavaScript

Overview

Introduction

  • Build a web site that is mobile enabled.
  • Build an application that can be installed on mobile devices via the Appstore or Google play or ...

The first is obviously needs web techniques such as HTML/CSS and Javascript. For the second one we could use native technologies but we are going to the same web technologies there too.

Technologies used

  • HTML, HTML5
  • CSS, CSS3
  • JavaScript
  • HTML DOM and JavaScript events
  • JQuery and JQuery Mobile
  • Ajax
  • Perl
  • Perl Dancer

Background and overview

Platforms

  • Android
  • iPhone
  • Windows Phone

Others

  • Symbian (Nokia)
  • BlackBerry
  • MeeGo
  • bada
  • Firefox OS
  • Ubuntu
  • ...

Capabilities

  • 3G, 3.5G
  • Internet
  • Voice and Video calls
  • Applications

Development Languages

  • iPhone - Objective C
  • Android - Java
  • Symbian - C++
  • Blackberry - Java
  • Microsoft - .NET

Web based development

  • HTML5/CSS3/JS all the Operating Systems and devices
  • PhoneGap to package

Using PhoneGap to generate stand-alone application using a chrome-less version of the built-in browser of the device.

Using an API to use the specical features of the device to create a Hybrid Application.

Compare

HTML/CSS/JSNative
CodingWrite once, Test everywhereWrite Everywhere, Test Everywere
CapabilitiesLimited device capabilitiesAll the deveice capabilities
Look and FeelBuild your own UI componentsUse deveice UI components
DevelopersMany and cheapFew and expensive

Browsers

  • Firefox
  • Google Chrome
  • Safari
  • Opeara
  • IE - Internet Explorer 9

Web browser engines

  • WebKit (by Apple): Safari
  • Blink (a WebKit fork) Chromium, Google Chrome, Opera
  • Gecko (Mozilla) Firefox
  • Trident (Microsoft) IE
  • Presto (old Opera)

Mobile web challenges

  • Develop and Test on many platforms
  • Adjust UI to various screen sizes - much smaller than Desktop
  • Browser diversity in capabilities
  • Handle mobile UX (User experience)

Screen resolution

Sizes                     diagonal  resolution ppi (pixe/inch)
                          in inch
iPod touch 123x58  mm     (4   )    1136x640  (326 )
iPhone 5   123x58  mm     (4   )    1136x640  (326 )
iPad mini  200x134 mm     (7.9 )    1024x768  (163 )
iPad       241x185 mm     (9.7 )    2048x1536 (264 )
MacBook Air               (11.6)    1366x768
MacBook Air               (13.3)    1440x900
MacBook Pro               (13.3)    2560x1600 (227 )
MacBook Pro               (15.4)    2880x1800 (220 )
Nexus 4                   (4.7 )    1280x768  (320 )
Nexus 7                   (7   )    1280x800  (216 )
Nexus 10                  (10  )    2560x1600 (300 )
Samsung Galaxy Y GT-S5360 (3   )    320x240   (133 )
Samsung S 4               (5   )    1920x1080 (441 )
Galaxy Tab 2              (10.1)    1280x800

Mobile User Experinece (UX)

  • App is used in short bursts = waiting for the bus or subway.
  • App is used while watching TV.
  • App is interrupted by incoming call or SMS.
  • It is much harder to type.

Development Environments

Debugging Applications - Desktop

  • Use Safari/Chrome inspector tools to debug (Free) Chrome developer tools
  • Use iPhone/Android Emulator (Free)
  • Use Ripple to test your hybrid app from Chrome (Open Source)
  • BrowserStack (Live, Web-Based Browser Testing, $$$)
  • Browserling (Interactive cross-browser Testing, $$$)

Debugging Applications - Device

  • Use weinre for on device inspection (Open source)

Deplyoing Applications

  • For online apps every web server will do
  • For offline apps, Adobe PhoneGap (Open Source), service
  • Before deployment use a build script to minimize js/css/html files.

HTML starter toolkits

HTML 5 Boilerplate

  • A ready made starter for html5 mobile apps
  • Cross-platform compatible (Android, iOS, Blackberry, Symbian)
  • Supports all the devices and overcomes many glitches
  • HTML 5 Boilerplate

Twitter Bootstrap

  • Customizable Bootstra
  • Used by the Perl Maven site ...

Mobile frameworks

  • JQuery Mobile
  • Sencha Touch
  • jqMobi

jQuery Mobile

  • Most hyped mobile framework today
  • Built on top of jQuery (slow, big)
  • Themed UI Widgets
  • JQuery Mobile

Sencha Touch

  • Stable and mature mobile framework
  • Works best on iPhone and Android
  • Commercial framework ($$$)
  • Sencha Touch

jqMobi (Intel App Framework)

HTML

Introduction to HTML

  • Opening and closing tags
  • Tags with only opening tag
  • Browsers are flexible

Tags:

  • html, head, title, body, h1, p, br
  • a, img
  • div, span
  • link, style, script

Attributes

  • href, src, alt, width, height
  • id, class
<html>
<head>
<title>Text on the tab</title>
</head>
<body>
<h1>Some title-ish sentence</h1>
<p>
A paragraph of text.
</p>
<a href="http://perlmaven.com/">Perl Maven</a>
<br>
<img src="../img/head-austin.jpg" alt="Austin" width="470" height="75" />
</body>
</html>

HTML Forms

  • form
  • input: text, password, submit
  • select + option
  • radio, checkbox
  • textarea
<html>
<head>
<title>A form</title>
</head>
<body>
<form method="GET" action="/do-something">
<table border="0" width="400">
<tr><td>Fname:</td><td><input type="text" name="fname" size="40" /></td></tr>

<tr><td>Country:</td><td>
   <select name="country">
   <option value=""></option>
   <option value="br">Brazil</option>
   <option value="pt">Portugal</option>
   <option value="es">Spain</option>
   </select>
  </td></tr>

<tr><td>Password:</td><td><input type="password" name="pw" size="40" /></td></tr>

<tr><td>Sex:</td><td>
   male:  <input type="radio" name="sex" value="male" />
   female: <input type="radio" name="sex" value="female" />
   other: <input type="radio" name="sex" value="other" />
   </td></tr>

<tr><td>Technologies:</td><td>
   Perl:        <input type="checkbox" name="tech" value="perl" />
   JavaScript:  <input type="checkbox" name="tech" value="javasript" />
   HTML:        <input type="checkbox" name="tech" value="html" />
   CSS:         <input type="checkbox" name="tech" value="css" />
   </td></tr>

<tr><td>About:</td><td></td></tr>
<tr><td colspan="2">
   <textarea name="about" cols="40" rows="10"></textarea>
   </td></tr>

<tr><td></td><td><input type="submit" value="Send" /></td></tr>

</table>
</form>
</body>
</html>

Using Tables for design is not "in" any more, but that's what we have with HTML only...

CSS - Cascading Style Sheets

Introduction to CSS

  • CSS

  • Where to put CSS

  • Basic selectors: tag, id, class

  • Properties, values

CSS in elements

  • CSS can be added to individual HTML elements.
  • CSS can be embedded in the HTML file in a separate section.
  • CSS can be included from an external file.
<html>
<head>
<title>Text on the tab</title>
</head>
<body>
<h1 style="font-size:40px">Main title - CSS in HTML element</h1>
</body>
</html>

Embedded CSS

<html>
<head>
<title>Text on the tab</title>
</head>
<body>
<style>
h1 {
  font-size: 40px;
}
</style>
<h1>Main title: Embedded CSS</h1>
</body>
</html>

External CSS

<html>
<head>
<title>Text on the tab</title>
<link rel='stylesheet' href='intro.css' />
</head>
<body>
<h1>Main title: External CSS file</h1>
</body>
</html>
h1 {
  font-size: 40px;
}

Basic Selectors

  • HTML tag
  • HTML attributes: id, class
<html>
<head>
<title>The title</title>
<link rel="stylesheet" href="basic-selectors.css" />
</head>
<body>
<h1>Main title</h1>
<p>
First paragraph of text.
</p>
<p class="abc">
Second paragraph of text.
</p>
<p id="part3">
Third paragraph of text.
</p>
<a class="abc" href="http://perlmaven.com/">Perl Maven</a>

</body>
</html>
/*

p {
  background-color: red;
}

.abc {
  background-color: blue;
}

#part3 {
  background-color: green;
}

*/

Descendant and Child CSS Selectors

<html>
<head>
<title>The title</title>
<link rel="stylesheet" href="selectors.css" />
</head>
<body>
<h1>Main title</h1>

<ul>
  <li><a href="http://pm.org/">Perl Monger</a></li>
  <li><p><a href="http://perlmaven.com/">Perl Maven</a></p></li>
</ul>
<p><a href="http://perlmonks.com/">Perl Monks</a></p>

</body>
</html>
/*
a {
  background-color: red;
}


li a {
  background-color: yellow;
}
*/

/*
p  a {
  background-color: green;
}
*/


/*

li > a {
  background-color: green;
}

*/

[List of selectors](http://www.w3.org/TR/CSS2/selector.html" %}

div and span

<html>
<head>
<title>div and span</title>

<style>
#upper {
  background-color: blue;
  border: solid;
}

#space {
  height: 30px;
}

#lower {
  background-color: red;
  border: solid;
}
</style>

</head>
<body>
<div id="upper">
Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
</div>
<div id="space">
</div>
<span id="lower">
Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
</div>
</body>
</html>

Layouts

  • Static layout

  • Dynamic layout

  • Fixed-width

  • Relative

  • Fluid

  • Elastic

  • Hybrid

  • Responsive

What happens when the width is fixed? Horizontal scrollbar or picture disappearing.

Fixed width and text

#article {
  width: 960px;
}
<html>
<head>
<title>Fixed width text</title>
<link rel='stylesheet' href='fixed-width-text.css' />
</head>
<body>
<div id="article">
Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
</div>
</body>
</html>

Relative width and text

#article {
  width: 80%;
}
<html>
<head>
<title>Relative width text</title>
<link rel='stylesheet' href='relative-width-text.css' />
</head>
<body>
<div id="article">
Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
</div>
</body>
</html>

Fixed Image

The actual image is 1280 x 716

#city-view {
  border: solid;
}

<html>
<head>
<title>Image</title>
<link rel='stylesheet' href='fixed-image.css' />
</head>
<body>
<div id="city-view">
<img src="../img/austin-yapc-1280x716.jpg" alt="Austin"/>
</div>
</body>
</html>

Media Query

  • media query
  • @media

Change CSS based on

  • min-width
  • max-width
  • min-height
  • max-height
  • min-device-height
  • max-device-height
  • device-aspect-ratio
  • orientation (portrait or landscape)
  • ...

You can use and, and the comma , to indicate or and even the word not to have the full power of boolean expressions.

You can use @media queries inside a single style-sheet, or you can load different style-sheets base on the @media query.

Probably the most common thing to use @media queries for is to change the site depending on the width of the browser using the min-width and max-width fields, but you can also use the others listed above.

Of course you can also use it to check the media type: screen, print, etc. css media queries

Resize image

<html>
<head>
<title>Media Query: Images</title>
<link rel='stylesheet' href='images-resizing.css' />
</head>
<body>
<div id="city-view">
<img src="../img/austin-yapc-1280x716.jpg" alt="Austin"/>
</div>
</body>
</html>

#city-view {
  border: solid;
}


@media (min-width: 1281px) and (min-height: 800px) {
}

@media (min-width: 800px) and (max-width: 1280px) {
  img {
     width: 700px;
  }
}

@media (max-width: 799px) {
  img {
    visibility: hidden;
    /* display: none; */
  }
}



Replace image

<html>
<head>
<title>Replace Image</title>
<link rel='stylesheet' href='replace-image.css' />
</head>
<body>
<div id="city-view">
</div>
</body>
</html>

#city-view {
  border: solid;
}


@media (min-width: 1281px) and (min-height: 800px) {
  #city-view {
    width: 1280px;
    height: 716px;
    background-image: url(../img/austin-yapc-1280x716.jpg);
  }
}

@media (min-width: 800px) and (max-width: 1280px) {
  #city-view {
    float: right;
    width: 617px;
    height: 716px;
    background-image: url(../img/austin-yapc-617x716.jpg);
  }
}

@media (max-width: 799px) {
  #city-view {
    float: right;
    width: 201px;
    height: 157px;
    background-image: url(../img/austin-yapc-201x157.jpg);
  }
}

css image replacement

Colors

@media (max-width: 499px) {
  body {
    background-color: green;
  }
}

@media (min-width: 500px) and (max-width: 800px) {
  body {
    background-color: red;
  }
}
@media (min-width: 801px) {
  body {
    background-color: blue;
  }
}

<html>
<head>
<title>Media Query: Colors</title>
<link rel='stylesheet' href='colors.css' />
</head>
<body>
</body>
</html>

CSS3

More standardization

  • Rounded Corners (easier)
  • Background Decoration
  • New Colors schemes
  • Text Effects: e.g. text-shadow
  • More powerful selectors (attribute mathching)
  • Transitions
  • Media Queries

Rounded corners

<html>
<head>
<title>Rounded corners</title>

<style>
#pw {
/*
  background-color: #004065;
  color: #FFF;
  font-size: 40px;
  font-weight: bold;

          border-radius: 15px;
     -moz-border-radius: 15px;
  -webkit-border-radius: 15px;

  border: 1px solid #000;
  padding: 10px;
  text-decoration: none;

*/
}
</style>
</head>
<body>
<a id="pw" href="http://perlweekly.com/">Perl Weekly Newsletter</a>
</body>
</html>

rounded corners

JavaScript

JS Bin

jsbin

Node.js

Download Node.js. Run as node. Ctrl-C (twice) to quit.

On Ubuntu I had to install the nodejs package and the command is called nodejs as there was already command called node.

On Mac first install Homebrew and then brew install node.

Maybe you'll need to use the Git bash shell...

> .help
> .exit

> .break

Some JavaScript using the Node.js REPL

Variables and numbers

> a = 23
23
> b = 19
19
> a+b
42

The behaviour of + depends on the operands. If even one of them is a sting,

  • will concatenate them as string. Use parseInt() to convert a string to an integer.
> c = "1"
> a+c
'231'
> a+parseInt(c)
24

String to float conversion

  • parseFloat

use parseFloat

> c = "1.2"
> a+c
'231.2'
> a+parseInt(c)
24
> a+parseFloat(c)
24.2

Number(v) is like parseFloat. Except that Number('4x') returns NaN and parseInt('4x') and parseFloat('4x') both return 4.

Number to string conversion

  • toString

What if you have a number but would like to use it as a sting?

> 1+2
3
> 1+String(2)
12
> a = 1
> b = 2
> a + b
3
> b.toString()
> a + b
'12'

Hello World

console.log('Hello World');

To run, type node example/javascript/hello_world.js

Comments

// lines starting with two slashes

console.log('Hello World');

/*
   text
   between these marks
*/

Variable

  • var
var text = 'Hello World';
console.log(text);

JavaScript strings

name = 'The black cat climbed the green tree';
console.log(name);
console.log(name.length);       // 36
console.log(name[1]);           // h

console.log(name.substr(4, 5)); // black

console.log(name.indexOf('black')); // 4
console.log(name.indexOf('dog'));   // -1

console.log(name.indexOf('e'));     // 2
console.log(name.lastIndexOf('e')); // 35

Boolean values

true
false
Boolean( 2 > 3 )

These are false:
false, null, undefined
"" (the empty string)
0, NaN

Global Scope

name = 'Foo'
console.log(name);    // Foo

function f() {
   console.log(name); // Foo
   name = 'Bar'
   console.log(name); // Bar
}
f();

console.log(name);    // Bar

Having var in the body of the code, in the global scope does not matter. It is the same variable all over, but having it inside a function will restrict the scope of that variable.

var name = 'Foo'
console.log(name);    // Foo

function f() {
   console.log(name); // Foo
   name = 'Bar'
   console.log(name); // Bar
}
f()

console.log(name);    // Bar

Local Scope

name = 'Foo'
console.log(name);    // Foo

function f() {
   console.log(name); // undefined
   var name = 'Bar'
   console.log(name); // Bar
}
f();

console.log(name);    // Foo

var name = 'Foo'
console.log(name);    // Foo

function f() {
   console.log(name); // undefined
   var name = 'Bar'
   console.log(name); // Bar
}
f();

console.log(name);    // Foo

Objects

var phone_of = {
   'Foo' : 123,
   'Bar' : 456
};
console.log(phone_of); // { Foo: 123, Bar: 456 }
for (var k in phone_of) {
  console.log(k + ' - ' + phone_of[k]);
}
// Foo - 123
// Bar - 456

console.log(phone_of.length); //  undefined

Objects - more

var person = {
   'fname' : 'Foo',
   'lname' : 'Bar',
   'grades' : [34, 21, 100],
};
console.log(person)
  // { fname: 'Foo', lname: 'Bar', grades: [ 34, 21, 100 ] }

for (var k in person) {
  console.log(k + ' - ' + person[k]);
}
/*
  fname - Foo
  lname - Bar
  grades - 34,21,100
*/

Objects - deep

var person = {
   'fname' : 'Foo',
   'lname' : 'Bar',
   'subjects' : {
     'Math' : [34, 21, 100],
     'Art'  : [99, 100],
   },
};
console.log(person)
/*
{ fname: 'Foo',
  lname: 'Bar',
  subjects: { Math: [ 34, 21, 100 ], Art: [ 99, 100 ] } }
*/

for (var k in person) {
  console.log(k + ' - ' + person[k]);
}
/*
  fname - Foo
  lname - Bar
  subjects - [object Object]
*/

Arrays

numbers = [1, 6, 4]
console.log(numbers)         // [1, 6, 4]
console.log(numbers.length)  // 3

for (var i=0; i < numbers.length; i++) {
  console.log(i + ' ' + numbers[i])
}
/*
  0 1
  1 6
  2 4
*/
for (var i in numbers) {
   console.log(i)
}
/*
  0
  1
  2
*/

Javascript Core types

  • Numbers
  • Strings
  • Booleans
  • null
  • undefined
  • Objects

Type of variable

a = 2
console.log(typeof a); // number
b = "2"
console.log(typeof b); // string
c = true;
console.log(typeof c); // boolean

d = [1, 2, 3];
console.log(typeof d); // object

e = new Array;
console.log(typeof e); // object

f = { "fname" : 'Foo', "lname" : 'Bar' };
console.log(typeof e); // object

Functions

function add(x, y) {
  var z = x+y;
  return z;
}

console.log(add(2, 3));

Function in var

var add = function(x, y) {
  var z = x+y;
  return z;
}

console.log(add(2, 3));

Function in object

var math = {
  'add' : function(x, y) {
    var z = x+y;
    return z;
  }
};

console.log(math['add'](2, 3));      // 5

math['multiply'] = function(x, y) { return x * y };

console.log(math['multiply'](2, 3)); // 6

random

Math.random() returns a floating point number between 0 and 1. parseInt(Math.random()*6+1) is throwing a dice.

while

var i = 5;

while (i > 0) {
  console.log(i);
  i--;
}

if else if

var i = 10;

while (true) {
  console.log(i);
  i++;
  if (i <= 14) {
    console.log('kid')
  } else if (i < 18) {
    console.log('high school');
  } else {
    console.log('too big');
     break;
  }
}

HTML and Javascript

Document Object Model(DOM)

  • DOM

The DOM is a hierarchy of objects.

getElementById and innerHTML

  • getElementById
  • innerHTML
<div id="text"></div>

<script>
var field = document.getElementById('text');
field.innerHTML = "Hello World";
</script>

getElementsByTagName

  • getElementsByTagName
<div></div>
<div></div>
<div></div>

<script>
var fields = document.getElementsByTagName('div');
for (var i=0; i < fields.length; i++) {
  //console.log(i);
  fields[i].innerHTML = "Hello " + i;
}
</script>

getElementsByClassName

  • getElementsByClassName
<div class="foo">A</div>
<div class="bar">Bar</div>
<div class="foo">C</div>

<script>
var fields = document.getElementsByClassName('foo');
for (var i=0; i < fields.length; i++) {
  //console.log(i);
  fields[i].innerHTML = "Hello foo " + i;
}
</script>

Events handling

  • Mouse: click
  • Keyboard: keypress
  • Interface Events: load, scroll. resize
  • Form: select, change, submit, reset, focus, blur
  • Touch: touchstart, touchend, touchmove, touchenter, touchleave, touchcancel
  • DOM Events

Add event listener

  • addEventListener
  • removeEventListener
  • dispatchEvent
  element.onevent =
  element.attachEvent()       (IE)
  element.addEventListener()   (everything else including IE9 and above)

Example for using event objects

old style

<button>Click me</button>
<script>
var btn = document.getElementsByTagName('button')[0];
btn.onclick = function(e) {
    console.log(e);
};
</script>

Example for using event objects

new style

<button>Click me</button>
<script>
var btn = document.getElementsByTagName('button')[0];
btn.addEventListener('click', function(e) {
      console.log(e);
   }
);
</script>


Schedule event

  • setTimeout
Nothing to see here.

<script>
console.log('now');
setTimeout(function() {
   console.log('later');
      }, 2000);
</script>

Exercise: Update button

Modify the previous example so when the user clicks on the button, the text on it will be updated to 'Clicked'.

Once that's done, change the solution again, so 2 seconds later the text on the button will change back to the original text.

Exercise events

Create a page with two text input boxes and a button. Allow the user to type in one of the boxes.

When text changes in one of the boxes, change the text in the other box as well.

Solution for update button

<button>Click me</button>
<script>
var btn = document.getElementsByTagName('button')[0];
btn.addEventListener('click', function(e) {
      console.log(e);
      document.getElementsByTagName('button')[0].innerHTML = 'Clicked';
   }
);
</script>

Solution for update and reset button

<button>Click me</button>
<script>
var btn = document.getElementsByTagName('button')[0];
btn.addEventListener('click', function(e) {
      console.log(e);
      document.getElementsByTagName('button')[0].innerHTML = 'Clicked';
      setTimeout(function() {
         document.getElementsByTagName('button')[0].innerHTML = 'Click me again';
      }, 2000);
   }
);
</script>


Solution


<input type="text" id="input" size="30">
<input type="text" id="output" size="30">
<input type="button" id="btn" value="Update">

<script>
function update() {
  console.log('update');
  var input = document.getElementById('input').value;
  console.log(input);
  document.getElementById('output').value = input;
}

document.getElementById('btn').addEventListener('click', update);
</script>

DOM API Allows

  • Getting info on elements
  • Chaning element attributes
  • Creating new elements
  • Setting elements style

PhoneGap

PhoneGap

Install PhoneGap

For Android:

For Apple:

  • ...

And some more set-up work...

PhoneGap Build

register and use online (Adobe or Github user)

Sign up for Android

Android Signed

Generating the keys:

$ keytool -genkey -v -keystore ~/.keystore -alias alias_name
   -keyalg RSA -keysize 2048 -validity 10000

Enter keystore password: some_global_secret_that_will_be_shared_with_phonegap
Re-enter new password:
What is your first and last name?
  [Unknown]:  Foo Bar
What is the name of your organizational unit?
  [Unknown]: me
What is the name of your organization?
  [Unknown]:
What is the name of your City or Locality?
  [Unknown]:
What is the name of your State or Province?
  [Unknown]:
What is the two-letter country code for this unit?
  [Unknown]:
Is CN=Foo Bar, OU=me, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
  [no]:  y

Generating 2,048 bit RSA key pair and self-signed certificate (SHA256withRSA)
    with a validity of 10,000 days
	for: CN=Gabor Szabo, OU=me, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Enter key password for alias_name
	(RETURN if same as keystore password):
    (a secondary password of the specic key, also shared with PhoneGap)
New certificate (self-signed):
-keystore path/to.keystore  (defaults to ~/.keystore)
-alias  (8 significant characers?)

keytool -v -list -keystore ~/.keystore can list the existing keys and their aliases in verbose mode.

You will need to provide the alias, and the two passwords to the PhoneGap build system.

Apple

  • Sign up
  • Then sign up to the "iOS Developer Program" for $99/year at ios
  • They promise to process your request in 2 workdays.
  • Then follow this guide
  • Need the uuid of the device. Use the application called 'udid sender' to fetch it.

Process

  • Create a directory for yor project and put a www/ subdirectory in it
  • In the www/ subdirectory create a file called index.html, use external javascript and CSS.
  • Create a Git repository, and push it to Github
  • Add a www/config.xml and push that to Github as well
  • Use Build PhoneGap to generate the application
  • Download the APK file for Android, connect your mobile device to the computer, copy the APK file and from the device click on it to install it.

Git and Github

  • $ git init
  • $ git add .
  • $ git ci -m'initial version'
  • Github

Config

<?xml version="1.0" encoding="UTF-8" ?>
<widget xmlns = "http://www.w3.org/ns/widgets"
    xmlns:gap = "http://phonegap.com/ns/1.0"
    id        = "com.szabgab.mobile"
    versionCode="5"
    version   = "0.0.5">
  <name>Mobile Examples</name>
  <description>
    Mobile Application Examples
  </description>

  <author href="http://szabgab.com" email="szabgab@gmail.com">
    Gabor Szabo
  </author>

  <preference name="phonegap-version" value="2.7.0" />
  <preference name="android-minSdkVersion" value="7" />
  <!-- If you do not want any permissions to be added to your app, add the
    following tag to your config.xml; you will still have the INTERNET
    permission on your app, which PhoneGap requires. -->
  <preference name="permissions" value="none"/>


  <!-- See http://build.phonegap.com/docs/config-xml for more details -->
</widget>
  • id set something for yourself
  • versionCode start from 1
  • version start from 0.0.1
  • name
  • description
  • author
  • phonegap-version The Phonegap Build will tell you when to change this.
  • permissions See the comment and the docs
  • confg-xml

Exercise: PhoneGap Build

Follow the "Process" in the earlier slide: creat a simple web application, eg. an input box, and a button, and when the button is clicked, show the content of the input box elsewhere on the page. Then push it out to github.

Sign up to PhoneGap and set this project as an open source project and build it.

Try to install it on your mobile device.

Then update your application and install it again.

HTML5

HTML5 Features

HTML5 is not one big set of feature, but instead it is a set of individual feature. Each browser supporting a subset of it. Which just makes it more difficult to build using it...

HTML5 adds new tags and corresponding API in the DOM (Document Object Model).

  • Canvas - to draw using JavaScript.
  • Video - to play video without extra plugins.
  • Local Storage - to hold a lot of data on the client.
  • Web Workers - threadding for your JavaScript in the browser.
  • Offline web application - to download web elements and store locally.
  • Geolocation - to know where the client is.
  • Input types
  • Placeholder text in input fields

Input types

  • search for searchboxes
  • number for spinboxes
  • range for sliders
  • color for color pickers
  • tel for phone numbers
  • url for web addresses
  • email for email addresses
  • date for calendar date picks
  • month for months
  • week for weeks
  • time for timestamps
  • datetime for precise, absolute date and timestamps
  • datetime-local for local dates and times

Placeholder

  • input.placeholder

Check for availability

  • Modernizr

Modernizr.inputtypes.TYPE where TYPE is one of the names mentioned previously.

modernizr is a JavaScript library that detects HTML5 and CSS3 features in the user's browser.

<script src="modernizr.min.js"></script>

<script>
if (Moernizr.featurename) {
    // feature supported
} else {
    // feature NOT supported
}
</script>

See also [detect](http://diveintohtml5.info/detect.html" %}

HTML 5 as recognized by Modernizr

Modernizr.

  • canvas
  • canvastext
  • video
  • video.webm
  • video.ogg
  • video.h264
  • localstorage
  • webworkers
  • applicationcache
  • geolocation
  • inputtypes.date
  • inputtypes....

HTML5 features

<!DOCTYPE html>
<html>
<head>
<title>HTML Feature support</title>
<script src="modernizr.js"></script>
</head>
<body>
<h1>HTML feature support checked by Modernizr</h1>

<style>
li {
/* border: solid; */
font-size: 20px;
  display: inline-block;
}
ul li:nth-child(1) {
    width: 100px;
}
ul li:nth-child(2) {
    width: 300px;
}
</style>
<form>
<ul><li>Search:</li>
    <li><input type="search" id="mysearch" placeholder="Perl"></li></ul>
<ul><li>URL:</li>
    <li><input type="url" id="myurl"></li></ul>
<ul><li>Email:</li>
    <li><input type="email" id="myemail" autofocus="true"></li></ul>
</form>

<div id="report">
</div>

<script>
var html = '';
if (Modernizr.canvas) {
   html += 'Your browser supports canvas';
} else {
   html += 'Your browser does not support canvas';
}
html += '<p>\nFeatures:<p>';

for (k in Modernizr) {
  if (k[0] == '_') {
    continue;
  }
  html += k + '<br>';
}

document.getElementById('report').innerHTML = html;
</script>


</body>
</html>

Geolocation

How to determine the location:

  • based on IP address
  • wifi connection
  • cell tower information
  • GPS hardware

New semantic elements

All wrapped in < and > signs.

  • section
  • nav
  • article
  • aside
  • hgroup
  • header
  • footer
  • time
  • mark

See also [semantics](http://diveintohtml5.info/semantics.html" %}

HTML5 Local storage

Several names referring to the same thing:

  • Local Storage
  • Web Storage
  • DOM Storage
  • HTML5 Storage

A simple set of key/value pairs.

Storage as strings

  • localStorage.setItem
  • localStorage.getItem
  • localStorage.removeItem

Values are stored as strings so on retrieval you'll need to use functions

<!DOCTYPE html>
<html lang="en">
<head><title>String</title></head>
<body>
<script>
var a = 23;
var b = 19;
console.log(a+b);
localStorage.setItem('a', a);
console.log(localStorage.getItem('a') + b);
</script>

</body>
</html>

Store and stringify

  • stringify
  • JSON
<!DOCTYPE html>
<html lang="en">
<head><title>Store</title></head>
<body>

Key: <input id="key" type="text" autofocus>
Value: <input id="value" type="text">
<input type="submit" id="save" value="Save">
<input type="submit" id="list" value="List">
<input type="submit" id="clear" value="Clear">
<div id="response"></div>

<script src="store.js"></script>
</body>
</html>
function save() {
  var k = document.getElementById('key').value;
  var v = document.getElementById('value').value;
  var data = get_data('store');
  data[k] = v;
  localStorage.setItem( 'store', JSON.stringify(data) )
  display('Saved ' + k + ' ' + v);

  document.getElementById('key').value = '';
  document.getElementById('value').value = '';
 
  return false;
}

function list() {
  var data = get_data('store');
  var has_keys = 0;
  for (var k in data) { has_keys++; break }

  if (has_keys) {
    var html = '<b>Listing:</b><br>';
    for (k in data) {
        html += k + ' ' + data[k] + '<br>';
    }
    display(html)   
    return false;
  }
  display('Empty');
  return false;
}
function clear() {
  localStorage.clear();
  return false;
}

function display(html) {
  document.getElementById('response').innerHTML = html;
}
function get_data(field) {
  var data_str = localStorage.getItem(field);
  //console.log(data);
  if (data_str == null) {
    return {}
  }
  return JSON.parse(data_str)
}

document.getElementById('save').addEventListener( 'click', save );
document.getElementById('list').addEventListener( 'click', list );
document.getElementById('clear').addEventListener( 'click', clear );

JQuery

Overview

<html>
<head>
  <title>JQuery example</title>
  <script src="../jq/jquery-1.9.1.min.js"></script>
  <script src="jq.js"></script>
</head>
<body>
<input id="name">
<input id="show" type="button" value="Show">
<div id="content">
</body>
</html>
$( document ).ready(function() {
  console.log('document ready');
  $( '#name' ).val(42);

  $('#show').click(function() {
    console.log('clicked');
    var input = $( '#name' ).val();
    console.log(input);
    $( '#content' ).html(input);
  });

});

JQuery Mobile

You can download the full version, or a customized smaller version, or you can use a CDN hosted version. You can also download a zip file including the images needed. Each has its advantages/disadvantages.

<!DOCTYPE html>
<html>
<head>
  <title>JQuery mobile example</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link rel="stylesheet" href="../jq/jquery.mobile-1.3.1.min.css" />
  <script type="text/javascript" src="../jq/jquery-1.9.1.min.js"></script>
  <script type="text/javascript" src="../jq/jquery.mobile-1.3.1.min.js"></script>
</head>
<body>

<div data-role="page" id="main-page">
  <div data-role="header">
    <h1>Main page</h1>
  </div>
  <div data-role="content">
    <p>Hello world</p>
    <p><a href="#dial" data-rel="dialog" data-role="button">dialogue</a></p>
  </div>
  <div data-role="footer" data-position="fixed" >
    <a href="#about-page" data-icon="about">about</a>
  </div>
</div>

<div data-role="page" id="about-page">
  <div data-role="header">
     <a href="#main-page" data-icon="home">Home</a>
        <h1>About</h1>
     <a href="#main-page" data-icon="home" data-theme="b">Home</a>
  </div>
  <div data-role="content">
    <p>Hello Perl Maven</p>
  </div>
  <div data-role="footer" data-position="fixed">
    <h4>This is the end</h4>
  </div>
</div>

<div data-role="page" id="dial" >
  <div data-role="header">
    <h1>Dialog</h1>
  </div>
  <div data-role="content">
    <p>Some dialogue</p>
  </div>
</div>

</body>
</html>

Backend

Start with Dancer

  • dancer

  • dancer -a App::Name

  • cd App-Name

  • perl bin/app.pl

  • browse to http://localhost:3000

  • edit views\index.tt

  • edit App-Name/lib/App/Name.pm

The dancer -a command will create the App-Name subdirectory with several files. Most importantly for us, the App-Name/lib/App/Name.pm

Module

package MEB;
use Dancer ':syntax';

our $VERSION = '0.1';

get '/' => sub {
  template 'index';
};

get '/echo' => sub {
  return 'Echo GET ' . param('txt') . ' at ' . localtime;
};

get '/echo.json' => sub {
  return to_json {
    'method' => 'GET',
    'txt'    => param('txt'),
    'time'   => scalar localtime,
  };
};

post '/echo.json' => sub {
  return to_json {
    'method' => 'POST',
    'txt'    => param('txt'),
    'time'   => scalar localtime,
  };
};

true;

Front-end server

#!/usr/bin/perl
use strict;
use warnings;

use Cwd qw(abs_path);
use File::Basename qw(dirname);
use Plack::App::Directory;

my $root = dirname(abs_path($0)) . '/www';
my $app = Plack::App::Directory->new({ root => $root })->to_app;

Same origin policy

Turn off same-origin-policy in Chrome

chromium-browser --disable-web-security
google-chrome --disable-web-security

Windows: The target in the short-cut:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
   --disable-web-security

Mac:
open /Applications/Google\ Chrome.app/ --args --disable-web-security

In Firefox

Appendix

Resources

Downloads

More frameworks

Project

Create an application for memorizing words in a foreign language: Let the user add word pairs to the system. Then the application will show random words in one of the languages and the user needs to type in the word in the other language. Provide Correc/Incorrect feedback. If it was incorrect, let the user see the correct answer.

Ask the words in the other direction as well.

If a words was guessed correctly reduce its frequency of being asked but never totally eliminate a word.

Provide statistics

Offer this both as an installable application and as a web site.

Create a back-end where users can register and where they can save their data.

My Projects

Feel free to dig around.

Thank You