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/JS | Native | |
---|---|---|
Coding | Write once, Test everywhere | Write Everywhere, Test Everywere |
Capabilities | Limited device capabilities | All the deveice capabilities |
Look and Feel | Build your own UI components | Use deveice UI components |
Developers | Many and cheap | Few 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
- Dashcode (Part of Apple's Xcode)
- Aptana Studio (Eclipse based, Open Source)
- Webstorm (IntelliJ IDEA based, $$$)
- Vim
- Emacs
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
- div (block level)
- span (inline)
- span and div
<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);
}
}
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>
JavaScript
JS Bin
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
Appendix
Resources
- git-scm.com the home of Git.
- Learn CSS Layout
- CSS Tricks
- Dive Into HTML5
- [jsFiddle](http://jsfiddle.net/ to play online with HTML/CSS/JS)
- Learn CSS Positioning in Ten Steps
- Examples for responsive design using Media Queries
- Videos how to use Chrome for development
- Eloquent JavaScript
- JavaScript: The Good Parts
- HTML5 canvas to draw objects.
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.