Web ProgrammingSE 480:
Week 10: Ajax Data SourcesCopyright © Steven W. Johnson
October 1, 2012
Week 10:
Ajax using XML, JSON, MySQL
Overcoming Ajax weaknesses
Browser cache
Introduction to XML; JSON
2
Disadvantages of Ajax:
3
Clearly the short-term leader
Many problems:
any page-based idea no longer applies
page navigation different
bookmarks don’t work
‘send me your URL’
search engines: dynamic content is ‘deep web’
Ajax:
Made up of JavaScript and CSS over HTTP
Has security issues like JavaScript, HTTP
Graceful degradation, backwards compatibility
Problem: no place to ‘step down’ to
4
XMLHttpRequest
Disadvantages of Ajax:
Hijax: ‘simplified Ajax’ (Jeremy Keith)
Hijax is an exercise in progressive enhancement
Build site without Ajax, add progressive layers
Link behaviors ‘Hijacked’ (kaçırmak) from HTML;
progressively moved toward Ajax
5
Disadvantages of Ajax:
6
HijaxAjax
Drags on performance:
Number and type of files
IE8 supports up to 6 connections per host
HTTP resources are dealt with one-at-a-time
Auto-loaded scripts interpreted before opening
<head> Javascript, ‘onload’ scripts interpreted before page opens
Place essential scripts in head, load dynamically*7
Drags on performance:
Minimize HTTP requests (use one .js file)
Code performance versus DOM manipulations
Manage your cache; reuse items if it can
Give all content cache life
gZip static content
Minimize ‘onload’ script; NO ERRORS
8
Drags on performance:
9
for(i=0; i<array.length; i++) { do something}
end = array.length;for(i=0; i<end; i++) { do something}
Making Ajax work better:
Cache on the server side:
generated JSON
saved recordsets
Cache on the client side:
Results of Ajax calls
Save data to JavaScript objects
10
11
Browser cache:
Cache: brings resources closer temporarily
CPU cache (register)
L2 & L3 cacheResources
(data)
Resources(data)
12
Browser cache:
Memory in HDD used by browser; “Internet Files”
Keeps copies of files to speed re-use
Stores images (banners, buttons, DATA, etc)Resources
(data)
Resources(data)
Browser cache:
Browser caches:
disk: primary cache
memory: mail, SSL, ‘no-cache’ items
image: for decompressed images (.gif, .png, .jpg)
13
Browser cache:
Issues with the cache:
may want to use more effectively
may want to not use at all
Web designers can manage the cache
cut down on bandwidth; save time
store partial processes; recordsets
14
Browser cache
Problems with cache:
many designers don’t consider it
55% of resources don’t specify max-age*
may be turned off locally
may be full (30%* of people in survey)
mobile devices are a disaster
non-cacheable elements (frames)
15*stevesouders.com
Browser cache:
Browser cache control based in:
freshness: time check; uses current if fresh
validation: cached response still good?
invalidation: current page is over-written
Commands used to check:
16
expiresmax-agelast modifiedif-modified-since
3 main ways to control:
meta tags (client side)
with code (server side)
web server configuration files
17
Browser cache:
Client side meta tags (normal web page)
Meta: ‘thinking about’ or ‘describing itself’
18
<meta name=“Keywords” content=“folk, music”><meta name=“Description” content=“Turkish folk music”>
<meta http-equiv=“Cache-control” content=“public”><meta http-equiv=“pragma” content=“no-cache”> //old<meta http-equiv=“Expires” content=“-1”>
public | private | no-cache | no-store
public: may be cached publicprivate: may be cached privateno-cache: do not cacheno-store: may be cached, but not archived
Browser cache:
Encoding links so each instance is unique
Can use time (milliseconds) or random
Works well in Ajax
19
url = “music.php?instrument=" +id + "&random=" +Math.random();
Browser cache:
jQuery/JavaScript
20
{Cache: false}
Browser cache:
header(“Cache-Control: no-cache, must–revalidate”);header(“Expires: Sat, 18 Mar 2002 23:59:59 GMT”); //past expire dateHeader(“Cache-Control: max-age=32436000);
header(“Pragma: no-cache”);header(“Last-Modified: ” .some date);
Server side defines cache settings before sent
header() function creates HTTP requests
21
$_SERVER['HTTP_IF_MODIFIED_SINCE'] == time
Browser cache:
web server configuration files:
httpd.conf
.htaccess
HTTP header files
22
Browser cache:
Apache set ‘mod_expires’ and ‘mod_headers’
23
ExpiresDefault "<base> [plus] {<num> <type>}*"ExpiresByType type/encoding "<base> [plus] {<num> <type>}*" )
<base>: access, now, modification‘plus’ keyword is optional<num>: a number<type>: years, months, weeks, days, hours, minutes, seconds
ExpiresDefault “access plus 1 month”ExpiresByType image/gif “modification plus 5 hours 3 minutes”
Browser cache:
24
Browser cache:
Data in cache won’t update by F5
Can turn off cache, or cache everything (settings)
abc
abc
F5Reload
Reloads page, not data
XML:
eXtensible (genisletmek) Markup Language
Meta (mecaz) language
Purpose: store data in hierarchical format
Can be rendered in browser (text); not intent
25
¸
XML:
Used to describe data and data relationships
‘Semantic information’
26
XML:
XHTML 2.0 was XML as page markup language
Overall effect is same; not equal ideas
27
=+ +
XML:
28
Point: store data and context (baglam) of data
Elements describe what they hold
HTML: presentation of content
HTML: element names defined
XML: data relationships
XML: name elements to make sense
<Name>Steve</Name> //xml
<h2>Steve</h2> //html
˘
XML:
29
Rules for XML:
case sensitive
tags/elements must be opened and closed
proper nesting (FILO)
attribute values must be in quotes
root element (students)
XML:
30
<?xml version=“1.0” encoding=“utf-8”?>
<students> <student> <name>Ali</name> <age>20</age> <bolum>MBBF</bolum> <gender>Erkek</gender> </student> <student> <name>Bahar</name> <age>21</age> <bolum>ITF</bolum> <gender>Hanim</gender> </student> </students>
“SML” (Students markup language)Table
Fields
Record
Students
Name Age Bolum Gender
Ali 20 MBBF Erkek
Bahar 21 ITF Hanim
XML: 2-dimensional (boyutlu) tables
Maker of flatfile databases
XML:
31
<?xml version=“1.0” encoding=“utf-8”?>
<building> <apartment> <room>living room</room> <room>dining room</room> <room>kitchen</room> </apartment> </building>
An XML markup language
XML:
32
<?xml version=“1.0” encoding=“utf-8”?>
<building> <apartment> <room type=“bedroom”> <item type=“shirt” color=“blue” /> <item type=“pants” color=“green” /> <item type=“clock” kind=“digital” /> </room> </apartment> </building>
Added ‘empty’ elements (item)
Like <br /> instead of <p>Hi</p> in HTML
attributes
XML: advantages/disadvantages
Self-describing; use of custom tags adds clarity
Human and machine readable
Data and presentation are not mixed (HTML)
Hierarchical (adds semantics)
Model complex data relationships
Cross-platform, language independent
Parsed (ayrıstırmak) by many languages33
¸
XML: advantages/disadvantages
Requires processing application (xslt)
Redundant (gereksiz) syntax
Lots of tags; heavy footprint; verbose (söz)
Doesn’t support data types
Issues with non-hierarchical data
Translating out of XML a problem
34
Break
JSON:
All data sources are like 2-dimensional arrays
Table: records (rows) and fields columns
36
array = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]];
0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
0 1 2 3
0 [0,0] [0,1] [0,2] [0,3]
1 [1,0] [1,1] [1,2] [1,3]
2 [2,0] [2,1] [2,2] [2,3]
array[2][1]; //9array[1][3]; //7
JSON:
JavaScript Object Notation
Data interchange (kavsak) format
Passes objects as strings from server to client
Basic form: uses name/value pairs
37
{“firstname”: “Canan”}
firstname = “Canan”;
¸
JSON:
Does have a logo
Has a web site (json.org)
Incorporated into ISO
Douglas Crockford (2002)
Part of ECMAScript, RFC 4627
38
{“name”: “Ali”, “age”: 20, “bolum”: “MBBF” }
JSON:
Many string values identified in same “record”
Information defining one person/entity
Strings in quotes; numbers not
39
array = [[“Cem”, “Ali”, “Eda”],[18, 22, 24]];
{students = [ {“name”:“Ali”, “age”:20, “bolum”:“MBBF” }, {“name”:“Bahar”, “age”:21, “bolum”:“ITF” }]}
JSON:
Arrays used to represent many entities
Curly brackets define entities
Square brackets define entire source
40
students = [ {“name”:“Ali”, “age”:20, “bolum”:“MBBF” }, {“name”:“Bahar”, “age”:21, “bolum”:“ITF” }];
JSON:
All three represent the same data; “records”
Effectively a database table
41
students = [ {“name”: “Ali”, “age”: 20, “bolum”: “MBBF” }, {“name”: “Bahar”, “age”: 21, “bolum”: “ITF” } ];
Students
Name Age Bolum Gender
Ali 20 MBBF Erkek
Bahar 21 ITF Hanim
students[1].age //21
JSON:
An array of arrays or a database with 2 tables
‘Company’ is DB, tables ‘employees’, ‘managers’
var company = {“employees”: [ { "firstName":"John" , "lastName":"Doe" , "age":18}, { "firstName":"Anna" , "lastName":"Smith" , "age":20}, { "firstName":"Peter" , "lastName":"Jones" , "age":21} ], “managers”: [ { "firstName":“Alice" , "lastName":“Williams" , "age":19}, { "firstName":“Carla" , "lastName":“Walker" , "age":23}, { "firstName":“Joe" , "lastName":“Evans" , "age":22} ]}
document.write(company.employees[2].firstName); //Peterdocument.write(company.managers[1].age); //23
JSON:
Update table values also
var company = {“employees”: [ { "firstName":"John" , "lastName":"Doe" , "age":18}, { "firstName":"Anna" , "lastName":"Smith" , "age":20}, { "firstName":"Peter" , "lastName":"Jones" , "age":21} ], “managers”: [ { "firstName":“Alice" , "lastName":“Williams" , "age":19}, { "firstName":“Carla" , "lastName":“Walker" , "age":23}, { "firstName":“Joe" , "lastName":“Evans" , "age":22} ]}
company.employees[2].firstName= “Steve”;
JSON:
JSON.parse converts strings into objects
Native (dahil) in browsers since IE 8
44
JSONObj = JSON.parse(requestObject.responseText);document.getElementById(“a”).innerHTML = JSONObj[1].first;document.getElementById(“b”).innerHTML = JSONObj[1].last;
[ {"first":"John" , "last":"Doe" , "age":18}, {"first":"Anna" , "last":"Smith" , "age":20}, {"first":"Peter" , "last":"Jones“ , "age":21}]
JSON:
JSON.parse:
JSONObj = JSON.parse(requestObject.responseText);
{“employees”: [ { "firstName":"John" , "lastName":"Doe" , "age":18}, { "firstName":"Anna" , "lastName":"Smith" , "age":20}, { "firstName":"Peter" , "lastName":"Jones" , "age":21} ], “managers”: [ { "firstName":“Alice" , "lastName":“Williams" , "age":19}, { "firstName":“Carla" , "lastName":“Walker" , "age":23}, { "firstName":“Joe" , "lastName":“Evans" , "age":22} ]}
company.employees[2].firstName= “Steve”;
45
JSON:
.json and .txt are both text file formats
File holds an object/array (data source)
Ajax calls object and extracts data
46
data.txtdata.json
JSON:
Concept: JSON data source on server
Call server with address in array/database
Update page without refreshing entire page
47
page.html
array = []
json.txtdata.json
JSON versus Ajax:
48
“students”= [ {“name”: “Ali”, “age”: “20”, “bolum”: “MBBF” }, {“name”: “Bahar”, “age”: “21”, “bolum”: “ITF” }]
<?xml version=“1.0” encoding=“utf-8”?>
<students> <student> <name>Ali</name> <age>20</age> <bolum>MBBF</bolum> <gender>Erkek</gender> </student> <student> <name>Bahar</name> <age>21</age> <bolum>ITF</bolum> <gender>Hanim</gender> </student> </students>
JSON versus XML:
Both describe objects as strings
Both suitable for use in web services
Both enjoy broad support, libraries, etc.
Tools to convert, or do so on your own
49
<name>Steve</name>
“name”: “Steve”,
JSON advantages:
JSON is JavaScript
‘XML with anorexia’; faster to parse*
Easier to write, lightweight, less verbose
True data format, not a meta language
Language independent, cross platform
Self-describing and human readable
Hierarchical (values within values, detail on topics)50
JSON disadvantages:
JSON is JavaScript
Requires use of ‘eval’ function*
Reserved JavaScript keywords can’t be
used as Element names
XML is more familiar; more like HTML
More precise tool (has its own DTD)
Better support (libraries, etc)51
JSON and UTF-8:
JSON supports UTF-8; Notepad does not
Must save UTF-8 files using UTF-8; not
ANSI
52
JSON:
x-dimensional array saved as ‘employees’
objname[i].fieldname
53
employees = [{ "firstName":"John" , "lastName":"Doe" , "age":18},{ "firstName":"Anna" , "lastName":"Smith" , "age":20},{ "firstName":"Peter" , "lastName":"Jones" , "age":21}];
document.write(employees[1].age); //20
Making data sources:
Arguably hardest part of labs/assignment
Add data formats have same idea:
‘field name’
‘data’
54
<name>Ali</name>
{“name”:“Ali”}
Name
Ali
Making data sources:
Utilities do exist to transfer data
Can manually convert using a language
55
<name>Ali</name> {“name”:“Ali”}
start = String.indexOf(“<”);end = String.indexOf(“>”);for(i=start+1; i<end-1; i++) { field += string.charAt(i);}
start = String.indexOf(“>”);end = String.lastIndexOf(“<”);for(i=start+1; i<end-1; i++) { value += string.charAt(i);}
write ‘{“’ +field+ ‘”:“’ +value+ ‘”}’
Quiz:
1. What is the address of the value 24?
56
12 16 175 8 123 24 6
[2, 1]
Quiz:
2. Place this array in the table:
57
1 2 34 5 67 8 9
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Quiz:
3. What XML tag is most like a record?
58
<bbb>
<aaa> <bbb> <ccc>data</ccc> <ccc>data</ccc> <ccc>data</ccc> </bbb></aaa>
Quiz:
4. From <aaa>, the address of <bbb>?
5. Child nodes of <ccc>
6. What is the root node?
59
<aaa>[0].childNodes[0]
<aaa> <bbb> <ccc>11</ccc> <ccc>22</ccc> <ccc>33</ccc> </bbb></aaa>
0
<aaa>
Quiz:
7. Children of <aaa>?
8. Value of <bbb>[0].childNodes[1].childNodes[0].nodeValue
60
1
<aaa> <bbb> <ccc>11</ccc> <ccc>22</ccc> <ccc>33</ccc> </bbb></aaa>
22
Quiz:
9. JSON array of 3 names:
61
friends = [ {“name”:”Ali”, “name”:”Bahar”, “name”:”Canan”}];
Quiz:
10. What is the value of company.employees[1].age?
62
var company = {“employees”: [ { "firstName":"John" , "lastName":"Doe" , "age":18}, { "firstName":"Anna" , "lastName":"Smith" , "age":20}, { "firstName":"Peter" , "lastName":"Jones" , "age":21} ], “managers”: [ { "firstName":“Alice" , "lastName":“Williams" , "age":19}, { "firstName":“Carla" , "lastName":“Walker" , "age":23}, { "firstName":“Joe" , "lastName":“Evans" , "age":22} ]}
20
Web ProgrammingCS 450:
Week 10: Ajax Data SourcesCopyright © Steven W. Johnson
October 1, 2012
64
Installing Uniform Server
Turn off Skype; turn on Windows Firewall
Double click/extract “Coral_8_9_2.exe”
To folder “C:\” (keep track of where it goes)
65
Installing Uniform Server
After extraction, ‘Uniserver’ folder in ‘C’ drive
66
Installing Uniform Server
Given two choices:
Start as program (no registry – manual load)
Start as service (added to registry – auto loads)
67
Installing Uniform Server
Asked if UniServer is supposed to load
Set up a MySQL password
68
Installing Uniform Server
Click on ‘Start Both’
Starting Uniform Server
Apache starts first
You must unblock port (80)
69
Starting Uniform Server
MySQL server starts next
You must unblock port (3306)
70
Starting Uniform Server
Lots to do here
Access to:
phpInfo
phpMyAdmin
UniServer page
71
72
73
74
Processes used by UniServer:
Three running processes:
75
Installing Uniform Server
Turn on UniServer: ‘Start Both’
Turn off: ‘Stop Both’
A “web page”:
Labs:
Register (validate, check user table)
Folk music:
DHTML
XML
JSON
Assignment: Your hobby76
Lab: harika harran’s
Features:
accept/reject new username using Ajax
hash password (sha1)
enable/disable the ‘Register’ button
check area code/city code combination
77
Lab: harika harran’s
Validate all entries (disable submit)
Use .innerHTML to show status of errors
image (green check or red X)
text (error message)
On successful completion, go to ‘thanks.html’
78
Lab: harika harran’s
79
Lab: harika harran’s
Make the database: registerdb
3 tables:
register data (mix user and pass)
area code
city code
80
Lab: harika harran’s
Make the database: registerdb
Create table ‘users’ with 8 fields: usersId (int, 5, primary, auto-increment)
username (unique varchar 12)
password (varchar 32)
lastname (varchar 50)
firstname (varchar 50)
telephone (varchar 11)
email (varchar 50)
registerDate (timestamp, Attribute ON UPDATE)81
Lab: harika harran’s
Make the database: registerdb
Create table ‘areacodes’ with 2 fields:
codeId (int, 5, primary, auto-increment)
areacode (varchar, 4, unique)
82
Lab: harika harran’s
Make the database: registerdb
Create table ‘officecodes’ with 3 fields:
officeId (int, 5, primary, auto-increment)
codeId (int, 5)
officecode (int, 3, unique)
83
84
Lab: harika harran’s
Insert data into your databaseINSERT INTO `users` VALUES(1, 'alib', 'denizyuz', 'Balikcioglu', 'Ali', '02325551234', '[email protected]', '2012-01-16 09:14:32');INSERT INTO `users` VALUES(2, 'selmac', 'jogger', 'Canli', 'Selma', '05324029876', '[email protected]', '2012-01-17 21:32:12');INSERT INTO `users` VALUES(3, 'Painterbey', 'pigments', 'VanGogh', 'Ernest', '05324558525', '[email protected]', '2012-01-19 14:42:05');INSERT INTO `users` VALUES(4, 'Musichanim', 'cmajor', 'Kocakeskin', 'Erdinc', '08756512785', '[email protected]', '2012-01-23 17:51:47');INSERT INTO `users` VALUES(5, 'futbol4ever', 'futbolpitch', 'Sehirbey', 'Pele', '04954286751', '[email protected]', '2012-01-24 08:06:19');INSERT INTO `users` VALUES(6, 'fenerrules', 'roberto', 'Buyukbey', 'Bahar', '09452331425', '[email protected]', '2012-01-24 09:37:12');INSERT INTO `users` VALUES(7, 'knitter', 'needleyarn', 'Ross', 'Benjamin', '09427254392', '[email protected]', '2012-01-26 09:14:37');INSERT INTO `users` VALUES(8, 'ieustudent', 'balcova', 'Einstein', 'Robert', '06427356284', '[email protected]', '2012-01-27 22:12:12');INSERT INTO `users` VALUES(9, 'kskrules', 'johann', 'Rooney', 'Mehmet', '08436184287', '[email protected]', '2012-01-27 23:06:41');INSERT INTO `users` VALUES(10, 'sedasinger', 'mavigoz', 'Seviyorum', 'Ilkgenc', '04852579561', '[email protected]', '2012-02-01 11:42:15');INSERT INTO `users` VALUES(11, 'asksong', 'forever', 'Yildizgoz', 'Gunus', '05134798561', '[email protected]', '2012-02-03 13:17:47');INSERT INTO `users` VALUES(12, 'tenderheart', 'poemreader', 'Frost', 'Emily', '05524354189', '[email protected]', '2012-02-03 16:39:52);
85
Lab: harika harran’s
Insert ‘registerdb.txt’ into your database
INSERT INTO `areacodes` VALUES(1, 232);INSERT INTO `areacodes` VALUES(3, 287);INSERT INTO `areacodes` VALUES(2, 532);
INSERT INTO `officecodes` VALUES(1, 1, 254);INSERT INTO `officecodes` VALUES(2, 1, 274);INSERT INTO `officecodes` VALUES(3, 1, 337);INSERT INTO `officecodes` VALUES(4, 2, 508);INSERT INTO `officecodes` VALUES(5, 2, 400);INSERT INTO `officecodes` VALUES(6, 2, 387);INSERT INTO `officecodes` VALUES(7, 3, 841);INSERT INTO `officecodes` VALUES(8, 3, 205);INSERT INTO `officecodes` VALUES(9, 3, 261);
Lab: harika harran’s
86
Open register folder, register.php:
Form built, table started
Lab: harika harran’s
87
Make the form (tab at end of row to make new row)
25 pixels wide
Lab: harika harran’s
88
Use these names
Lab: harika harran’s
89
Add these ids and classes
id=“usernamepix” id=“usererror” class="errortext"
id=“passwordpix” id=“usererror” class="errortext"
id=“verifypix” id=“usererror” class="errortext"
id=“lastnamepix” id=“usererror” class="errortext"
id=“firstnamepix” id=“usererror” class="errortext"
id=“telephonepix” id=“usererror” class="errortext"
id=“emailpix” id=“usererror” class="errortext"
Lab: harika harran’s
90
Use ‘.innerHTML’ to announce errors:
3rd column gets ‘red x’
4th column describes error
When fixed, both error messages turn off
Lab: harika harran’s
91
What and how to validate:
username: validated to table; entry rules
telephone: area code/local must match
all other fields: entry rules
Turn ‘Submit’ on when all fields valid:
check all fields are valid
Lab: harika harran’s
92
Username: 6 to 12 characters (letters/numbers)
Password: 6 to 12 characters (letters/numbers)
Password == Verify password
Lab: harika harran’s
93
Telephone: NAPN
11 digits
1: ==0
2: != 1
5: !=1
Area code in table
Office code must match
Lab: harika harran’s
94
0232 0532 0287254 508 841
274 400 305
337 387 261
Lab: harika harran’s
95
Email prefix:
1st, last chars cannot be “.”
6 to 15 chars
cannot have 2 noktas in a row
@
3-12 char total
1st 3 chars cannot be nokta
ends with: .net, .org, .com, .edu, .tr
Lab: harika harran’s
96
How about the submit button?
for( ) { flag[i] = 0;}
Lab: harika harran’s
97
function validate(value, id) { has value? value is valid: flag = 1; no display if invalid flag = 0 errorentry(text, image, id) function errorentry() { display, focus, select;}
function submit() { submit off loop ‘flag’ values if all ‘1’, submit on}
Lab: harika harran’s
98
General form:function validate(value) { if(value) { //error = value.match(regexp); validate all but Ajax validate Ajax valid flag failed length errorentry() failed content errorentry()}
Lab: harika harran’s
99
“error routine”:
insert red “X” and error text (vary)
reset focus, selection
function errorentry(errortext, pix, box) { document.getElementById(box+"pix").innerHTML = pix; document.getElementById(box+"error").innerHTML = errortext; document.getElementById(box).focus(); document.getElementById(box).select();}
Lab: harika harran’s
100
“submitbutton()”:
function submitbutton() { document.getElementById("Submit").disabled=false; for (i=0; i<7; i++) { if(flag[i]==0) {
document.getElementById("Submit").disabled=true; break;
} } }
Lab: harika harran’s
101
Create .js file: scripts.js
Save files, test
<script src=“validate.js”></script><script type=“text/javascript”> window.onload = initPage;</script>
//scripts for register.phpfunction initPage() { document.getElementById(“username”).focus(); document.getElementById(“Submit”).disabled = true;}
Lab: harika harran’s
102
Create embedded styles<style type="text/css"><!--.mainlayer { position: absolute; top: 25px; margin-left: -260px; width: 520px; left: 50%; background-color: #FFFFFF; border: 1px solid #000000;}body { font-family: Arial, Helvetica, sans-serif; font-size: 15px; background-color: #FFFFF4;}.errortext { color: #FF0000;}--></style>
Lab: harika harran’s
103
Initialize the flags (for validation)
flag=[];flag[0] = 0;flag[1] = 0;flag[2] = 0;flag[3] = 0;flag[4] = 0;flag[5] = 0;flag[6] = 0;
104
Username:
function uservalidate(value, box) { if(value) { data = value.match(/[^A-Za-z0-9]/); if(value.length>5 && value.length<13 && !data) {
ajaxRequest = new XMLHttpRequest(); queryString = "?username=" +value; url = "registerquery.php" +queryString; ajaxRequest.open(“GET", url, true); ajaxRequest.onreadystatechange = callback; ajaxRequest.send(null);
function callback() { //IE only; FF has issues if(ajaxRequest.readyState == 4 && ajaxRequest.status==200) { if(!ajaxRequest.responseText) { document.getElementById("usernamepix").innerHTML = ""; document.getElementById("usernameerror").innerHTML = ""; flag[0] = 1; submitbutton(); } else { errorentry("Duplicate Username", "<img src='images/redx.png'>", box); } } } } if(value.length<6 || value.length>12) errorentry("Username is wrong length", "<img src='images/redx.png'>", box); if(data) errorentry("Illegal characters", "<img src='images/redx.png'>", box); flag[0]=0; }}
105
Username:
function passvalidate(value, box) { data = value.match(/[^A-Za-z0-9]/); if(value) { if(value.length>5 && value.length<13 && !data) { document.getElementById("passwordpix").innerHTML = ""; document.getElementById("passworderror").innerHTML = ""; flag[1]=1; submitbutton(); } else { if(value.length<6 || value.length>12) errorentry("Password is wrong length", "<img src='images/redx.png'>", box); if(data) errorentry("Illegal characters", "<img src='images/redx.png'>", box); flag[1]=0; } }}
106
Username:
function verifyvalidate(value, box, pass) { if(value) { if(value == pass) { document.getElementById("verifypix").innerHTML = ""; document.getElementById("verifyerror").innerHTML = ""; flag[2]=1; submitbutton(); } else { errorentry("Passwords do not match", "<img src='images/redx.png'>", box); flag[2]=0; } }}
107
Username:
function lastnamevalidate(value, box) { data = value.match(/[^A-Za-z\-]/); if(value) { if(value.length<50 && !data) { document.getElementById("lastnamepix").innerHTML = ""; document.getElementById("lastnameerror").innerHTML = "";
flag[3]=1;submitbutton();
} else {
if(value>50) errorentry("Last name is too long", "<img src='images/redx.png'>", box); if(data) errorentry("Illegal characters in last name", "<img src='images/redx.png'>", box);
flag[3]=0; } }}
108
Username:
function firstnamevalidate(value, box) {
data = value.match(/[^A-Za-z\-]/); if(value) { if(value.length<50 && !data) { document.getElementById("firstnamepix").innerHTML = ""; document.getElementById("firstnameerror").innerHTML = ""; flag[4]=1; submitbutton(); } else { if(value>50) errorentry("First name is too long", "<img src='images/redx.png'>", box); if(data) errorentry("Illegal characters in first name", "<img src='images/redx.png'>", box); flag[4]=0; } }}
109
Username:
function phonevalidate(value, box) { if(value) { value = value.replace(/[^0-9]/g, "");
if (value.length==11 && value.charAt(0)=="0" && value.charAt(1) != "1" && value.charAt(4) != "1") { areacode = value.substr(0,4);
office = value.substr(4,3) ajaxRequest = new XMLHttpRequest();
queryString = "?areacode=" +areacode+ "&office=" +office; url = "registerquery.php" +queryString; ajaxRequest.open("GET", url, true); ajaxRequest.onreadystatechange = callback; ajaxRequest.send(null);
function callback() { if(ajaxRequest.readyState == 4 && ajaxRequest.status==200) {
if(!ajaxRequest.responseText) { document.getElementById("telephonepix").innerHTML = "";
document.getElementById("telephoneerror").innerHTML = ""; flag[5]=1; submitbutton(); } else {
errorentry("Phone number invalid", "<img src='images/redx.png'>", box); } }
} } else { errorentry("Phone number invalid", "<img src='images/redx.png'>", box); flag[5]=0; } }}
110
Username:
<?php include ('connection.php'); ?> //registerquery.php<?php
if ($_GET['username']) { $username = $_GET['username']; $query = mysqli_query($con, "SELECT userId FROM users WHERE username = '$username'") or die("Error number: " . mysql_errno() ."<br / >". mysql_error()); $row = mysqli_num_rows($query); if ($row == 0) { echo ""; } else { echo "Duplicate Username"; //passes null or something }}
if ($_GET['areacode']) { $areacode = $_GET['areacode']; $office = $_GET['office'];
$query = mysqli_query($con, "SELECT officeId FROM areacodes, officecodes WHERE areacodes.codeId=officecodes.codeId AND officecode='$office' AND areaCode='$areacode'") or die("Error number: “.mysql_error()); $row = mysqli_num_rows($query); if ($row == 0) { echo "Invalid"; } else { echo ""; //passes null or something }}?>
111
Username:
<?php //connection.php$host = "127.0.0.1";$username = “username";$password = “password";$database = "registerdb";$con = mysqli_connect($host, $username, $password, $database) or trigger_error(mysqli_error(),E_USER_ERROR);?>
112
Username:
<?php include ('connection.php'); ?> //scripts at top of register.php
<?phpif (isset($_POST['Submit'])) {
$salt = "This is the salt"; $username = $_POST['username']; $password = $_POST['password']; $lastname = $_POST['lastname']; $firstname = $_POST['firstname']; $telephone = $_POST['telephone']; $email = $_POST['email'];
$password = sha1($salt.$password); //crypt() $lastname = strtoupper($lastname); $query = "INSERT INTO users (username, password, lastname, firstname, telephone, email) VALUES ('$username', '$password', '$lastname', '$firstname', '$telephone', '$email')"; mysqli_query($con, $query) or die("Failed Query of " . $query); header("location: thanks.html"); mysqli_close($con);}?>
Break
Lab: folk music
114
Make web page/application
Displays instruments & text ‘onclick’
Lab: folk music
115
Make dynamic application:
No-jax (DHTML)
3 Ajax alternatives:
XML
JSON
MySQL
Use ‘highly-borrowed’ Turkish Folk Music site
Lab: folk music
Our choices. Which is best?
116
page.html XMLHttpRequest
Lab: folk music
117
Process is same regardless of data source
data to access
identify a record
insert values to layers
Lab: folk music
118
Making your data XML
<xml version “1.0” encoding=“utf-8”><instruments> <instrument> <text>ud text</text> <pix>images/ud.png</pix> </instrument> <instrument> <text>tar text</text> <pix>images/tar.png</pix> </instrument > <instrument> <text>kaval text</text> <pix>images/kaval.png</pix> </instrument > </instruments>
Fields
Record
Table
Lab: folk music
119
Making your data JSON
[{ “text”:“ud text” , “pix”:“images/ud.png” }, { “text”:“tar text” , “pix”:“images/tar.png" }, { “text”:“kaval text” , “pix”:“images/kaval.png” }]
FieldName value
Record
Table
Lab: folk music
120
Making your data MySQL
CREATE TABLE `instruments` ( `text` varchar(1000) NOT NULL, `pix` varchar(250) NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
INSERT INTO `turkishfolkinstruments` VALUES('ud text', 'images/ud.png');INSERT INTO `turkishfolkinstruments` VALUES('tar text', 'images/tar.png');INSERT INTO `turkishfolkinstruments` VALUES('kaval text', 'images/kaval.png');
Lab: folk music
121
Build web page
Start with DHTML
Modify for XML
Modify for JSON
Modify for MySQL
Lab: folk music – DHTML
DHTML version
Uses JavaScript functions to hold data
Insert data dynamically
122
page.html
Lab: folk music – DHTML
123
Open ‘folkmusic’ and ‘index.html’
Application made up of 6 layers
click on link
purple: image
blue: text about image
uses ‘innerHTML’
Lab: folk music – DHTML
124
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Turkish Folk Music <<Your_Name>></title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><link href="styles.css" rel="stylesheet" type="text/css" /><script type="text/javascript" src="data/dhtml.js"></script></head>
Lab: folk music – DHTML
125
.mainlayer { margin-left: -45%; position: absolute; height: 90%; width: 90%; left: 50%; background: -moz-radial-gradient(50% 25%, #FDF2CE, #F9E086); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FDF2CE', endColorstr='#F9E086',GradientType=0 ); background-color: #F9E086; border-radius: 10px; border: 5px solid #626A39; min-height: 790px;}.title { position: absolute; left: 1%; top: 1%; right: 1%; min-height: 380px;}body { font-family: Papyrus; font-size: 18px;}p { font-family: Papyrus;}
Lab: folk music – DHTML
126
.ad { position: absolute; height: 40%; width: 18%; left: 1%; bottom: 1%; background-color: #999933; border-radius: 7px; border: 5px solid #000000; min-height: 311px;}.nav{ position: absolute; height: 40%; width: 18%; left: 21%; bottom: 1%; min-height: 311px;}.text { position: absolute; height: 40%; width: 38%; right: 1%; bottom: 1%; overflow: auto; min-height: 311px;}
127
.pix { position: absolute; height: 40%; width: 20%; right: 40%; bottom: 1%; text-align: center; min-height: 311px;}h1 { font-family: Caliph; font-size: 72px; text-align: center; line-height: 52px; color: #653123;}a:link { color: #584424; line-height: 1.5em;}a:hover { color: #B33B12; line-height: 1.5em;}a:visited { color: #2E598F; line-height: 1.5em;}img.right { float: right; margin: 8px 0px 8px 8px;}
128
<body><div id="mainlayer" class="mainlayer" z-index:1"> <div id="title" class="title" z-index:2"> <h1>Turkish Folk Music Instruments</h1> <p><img class="right" src="images/players.png" width="137" height="225" alt="Folk music players" title="Folk music players" />I hope you enjoy my wesite about Turkish folk music instruments. Turkish folk music combines the distinct cultural values of all civilisations that have lived in Anatolia and the past territories in Europe and Asia. The instruments used can be classified as being stringed, wind, or percussion instruments. Lively Turkish folk music, which originated on the steppes of Central Asia, marks a complete contrast to the refined Turkish classical music of the Ottoman court. Until recently folk music was generally not written down, instead the traditions have been kept alive for generations by "asiklar", or troubadours and storyteller poets.</p> <p>Local Turkish folk music is comparatively more upbeat and lively than classical Turkish music. One genre of Turkish music is known as Turku which combines elements from both traditional Turkish music and western music and is quite popular in Turkey today.</p> </div> <div id="advertisement" class="ad" z-index:2">Advertisement here</div> <div id="instrumentnav" class="nav" z-index:2"> Instruments:<br /> <a href="#" onclick="baglamadisplay()">Baglama</a><br /> <a href="#" onclick="darbukadisplay()">Darbuka</a><br /> <a href="#" onclick="kabakkemanedisplay()">Kabak Kemane</a><br /> <a href="#" onclick="kemencedisplay()">Karadeniz Kemence</a><br /> <a href="#" onclick="kavaldisplay()">Kaval</a><br /> <a href="#" onclick="tardisplay()">Tar</a><br /> <a href="#" onclick="uddisplay()">Ud</a><br /> <a href="#" onclick="zurnadisplay()">Zurna</a><br /> </div> <div id="instrumentpix" class="pix" z-index:2"></div> <div id="instrumenttext" class="text" z-index:2"></div></div></body></html>
129
function uddisplay() { document.getElementById(“instrumenttext”).innerHTML = “TEXT STRING” obj = document.getElementById(“instrumentpix”); obj.style.top = document.getElementById("mainlayer").offsetHeight*.59 + obj.offsetHeight/2-125 + “px”; document.getElementById(“instrumentpix”).innerHTML = “IMAGE STRING”}
Open data – dhtml.js
Copy function 8 times
Get string and image text from XML doc
Lab: folk music – DHTML
130
function baglamadisplay() { xxx}function darbukadisplay() { xxx}function kabakkemanedisplay() { xxx}function kemencedisplay() { xxx}function kavaldisplay() { xxx}function tardisplay() { xxx}function uddisplay() { xxx}function zurnadisplay() { xxx}
Lab: folk music – DHTML
131
Done! Open in browser and see how works
Lab: folk music – DHTML
132
Up to this point: separation of concern
structure
presentation
logic
DHTML mixes logic and data; 4th concern
Lab: folk music – DHTML
133
Data
Logic
Presentation
Structure
Lab: folk music – DHTML
Lab: folk music – XML
XML version
134
page.html XMLHttpRequest
<instruments> <name>kaval</name> <image><img src…> <text>A Kaval…</text>
pix = <img src=… text = “A Kaval…
Lab: music store – XML
135
Data store in tag hierarchy; use DOM to find
Browser incompatibilities on ‘childNodes’
<xml version “1.0” encoding=“utf-8”> <instruments> <instrument> <instrumentId>1</instrumentId> <instrument>Darbuka</instrument> <text><p>A darbuka is a type of goblet drum commonly … basic rhythm.</p> <pix><img src="images/darbuka.png" width="233" height="250" /></pix> </instrument> <instrument> <instrumentId>2</instrumentId> <instrument>Ud</instrument> <text><p>The ud is a pear-shaped Baghdad … the instrument.</p></text> <pix><img src="images/ud.png" width="233" height="250" /></pix> </instrument> <instrument> </instruments>
Lab: music store – XML
136
Best solution; work from ‘instrument’
childNodes: id, instrument, text, pix
instrument[value] which instrument
childNodes[3] the picture element
childNodes[0].value get its value
<xml version “1.0” encoding=“utf-8”> <instruments> <instrument> <instrumentId>1</instrumentId> <instrument>Darbuka</instrument> <text><p>A darbuka is a type of goblet drum commonly … basic rhythm.</p> <pix><img src="images/darbuka.png" width="233" height="250" /></pix> </instrument> </instruments>
instrument[value].childNodes[3].childNodes[0].nodeValue;
Lab: music store – XML
137
Define picture and text separately
Short DOM pathway; works in both browsers
<xml version “1.0” encoding=“utf-8”> <instruments> <instrument> <instrumentId>1</instrumentId> <instrument>Darbuka</instrument> <text><p>A darbuka is a type of goblet drum commonly … basic rhythm.</p> <pix><img src="images/darbuka.png" width="233" height="250" /></pix> </instrument> </instruments>
image[value].childNodes[0].nodeValue;text[value].childNodes[0].nodeValue;
Lab: music store – XML
138
Cannot use ‘<‘ or ‘>’; instead use < and >
No need to escape quotes or apostrophes
Easier to prepare data than JSON
Data in data/xmldata.xml<xml version “1.0” encoding=“utf-8”> <instruments> <instrument> <instrumentId>1</instrumentId> <instrument>Darbuka</instrument> <text><p>A darbuka is a type of goblet drum commonly … basic rhythm.</p> <pix><img src="images/darbuka.png" width="233" height="250" /></pix> </instrument>
…
</instruments>
Lab: music store – XML
139
Use the same style sheet
Open xml.html
Install ‘request object’ script
<script type="text/javascript">function ajaxObject(value) { var requestObject = new XMLHttpRequest(); requestObject.onreadystatechange=function() { if (requestObject.readyState==4 && requestObject.status==200) { XMLObj = requestObject.responseXML; }requestObject.open("GET","data/xmldata.xml",true);requestObject.send(null);}</script>
Lab: music store – XML
140
Add code to extract data from XML
if (requestObject.readyState==4 && requestObject.status==200) { XMLObj = requestObject.responseXML;
/*single object solution; only works in MS; counting on childNodes inst = XMLObj.getElementsByTagName("instrument"); document.getElementById("instrumentpix").innerHTML = inst[value].childNodes[3].childNodes[0].nodeValue; document.getElementById("instrumenttext").innerHTML = inst[value].childNodes[2].childNodes[0].nodeValue; */
image = XMLObj.getElementsByTagName("pix"); txtdesc = XMLObj.getElementsByTagName("text"); document.getElementById("instrumentpix").innerHTML = image[value].childNodes[0].nodeValue; document.getElementById("instrumenttext").innerHTML = txtdesc[value].childNodes[0].nodeValue; } }
Lab: music store – XML
141
Build the links
Index is the order number in XML file
Instruments:<br /> <a href="#" onclick="ajaxObject(2)">Baglama</a><br /> <a href="#" onclick="ajaxObject(0)">Darbuka</a><br /> <a href="#" onclick="ajaxObject(3)">Kabak Kemane</a><br /> <a href="#" onclick="ajaxObject(4)">Karadeniz Kemence</a><br /> <a href="#" onclick="ajaxObject(5)">Kaval</a><br /> <a href="#" onclick="ajaxObject(6)">Tar</a><br /> <a href="#" onclick="ajaxObject(1)">Ud</a><br /> <a href="#" onclick="ajaxObject(7)">Zurna</a><br />
Lab: music store – XML
142
Done! Upload to server and test
Lab: folk music – JSON
JSON version
Can use any file that holds text (.js, .txt, etc)
143
json.html XMLHttpRequest jsondata.json
{xxxxx, yyyyyy}
144
[ {"id":"1", "text":"<p>A darbuka … </p>", "pix":"<img src=“ … title="Darbuka" />" }, {"id":"2", "text":"<p>The ud … </p>", "pix":"<img src … title="Ud" />" }, {"id":"3", "text":"</p>The bağlama … </p>", "pix":"<img src … title="Baglama" />" }, {"id":"4", "text":"<p>The kabak kemane … </p>", "pix":"<img src= … title="Kabak Kemane" />" }, {"id":"5", "text":"<p>The Karadeniz ….</p>”, "pix":"<img src= … title="Karadeniz" />" }, {"id":"6", "text":"<p>The kaval … </p>, pix:”img src= … title="Kaval" />" }, {"id":"7", "text":"<p>The tar … </p>", "pix":"<img src= … title="Tar" />" }, {"id":"8", "text":"<p>The Zurna … </p>”, pix:"<img src … title="Zurna" />" }]
Issue: connect to data; find correct ‘record’
‘Records’ identified by array counter
File modified for use by ‘JSON.parse’ method
Lab: folk music – JSON
145
The jobs:
Check our data source (data/jsondata.json)
Build request object on json.html (main page)
[ {"id":"1", "text":"<p>A darbuka … </p>", "pix":"<img src=“ … title="Darbuka" />" }, {"id":"2", "text":"<p>The ud … </p>", "pix":"<img src … title="Ud" />" }, {"id":"3", "text":"</p>The bağlama … </p>", "pix":"<img src … title="Baglama" />" }, {"id":"4", "text":"<p>The kabak kemane … </p>", "pix":"<img src= … title="Kabak Kemane" />" }, {"id":"5", "text":"<p>The Karadeniz ….</p>”, "pix":"<img src= … title="Karadeniz" />" }, {"id":"6", "text":"<p>The kaval … </p>, pix:”img src= … title="Kaval" />" }, {"id":"7", "text":"<p>The tar … </p>", "pix":"<img src= … title="Tar" />" }, {"id":"8", "text":"<p>The Zurna … </p>”, pix:"<img src … title="Zurna" />" }]
Lab: folk music – JSON
146
Open ‘json.html’
Update title with your name
Style sheet from ‘dhtml’ lab
Mission is same: click on link, open image/text
Lab: folk music – JSON
147
The request object: very compressed
<script type="text/javascript">
function ajaxObject(value) { var requestObject = new XMLHttpRequest(); requestObject.onreadystatechange=function() { if (requestObject.readyState==4 && requestObject.status==200) {
JSONObj = JSON.parse(requestObject.responseText); document.getElementById("instrumentpix").innerHTML = JSONObj[value].pix; document.getElementById("instrumenttext").innerHTML = JSONObj[value].text; } }requestObject.open("GET","data/jsondata.json",true);requestObject.send();
}
</script>
Lab: folk music – JSON
148
Data string turned into object
Object’s row found with ‘value’; data extracted
Data located in ‘jsondata.json’
JSONObj = JSON.parse(requestObject.responseText);
document.getElementById("instrumentpix").innerHTML = JSONObj[value].pix;document.getElementById("instrumenttext").innerHTML = JSONObj[value].text;
requestObject.open("GET","data/jsondata.json",true);requestObject.send();
}
</script>
Lab: folk music – JSON
149
Insert event handlers
Index identifies which row to use in array
<a href="#" onclick="ajaxObject(0)">Baglama</a><br /> <a href="#" onclick="ajaxObject(1)">Darbuka</a><br /> <a href="#" onclick="ajaxObject(2)">Kabak Kemane</a><br /> <a href="#" onclick="ajaxObject(3)">Karadeniz Kemence</a><br /> <a href="#" onclick="ajaxObject(4)">Kaval</a><br /> <a href="#" onclick="ajaxObject(5)">Tar</a><br /> <a href="#" onclick="ajaxObject(6)">Ud</a><br /> <a href="#" onclick="ajaxObject(7)">Zurna</a><br />
Lab: folk music – JSON
150
Done!
Upload and test
Lab: folk music – JSON
MySQL version
PHP page is used as interface
151
page.html XMLHttpRequest
Lab: folk music – MySQL
152
2-minute crash course
Process very similar with ‘hello world’
Lab: folk music – MySQL
mysql.phpquery.php
query.php
153
Our system: use HTML for view
Data comes from database as a block of text
Split and entered into layers
Lab: folk music – MySQL
mysql.html
154
Lab: folk music – MySQL
Add data to database
Turn on web server
Open http://localhost/apanel/phpmyadmin
Create database ‘folkinstruments’
Insert text from ‘mysqldata.txt’
155
Lab: folk music – MySQL
Open mysql.html<script type="text/javascript">function ajaxObject(value) { var requestObject = new XMLHttpRequest(); url = "query.php?id="+value; requestObject.onreadystatechange=function() { if (requestObject.readyState==4 && requestObject.status==200) { var MySQLObj = requestObject.responseText; output = MySQLObj.split("END"); document.getElementById("instrumentpix").innerHTML = output[1]; document.getElementById("instrumenttext").innerHTML = output[0]; } }requestObject.open("GET",url,true);requestObject.send(null);}</script>
156
Lab: folk music – MySQL
Create ‘query.php’<?php
$id = $_GET['id'];
$host = "127.0.0.1";$username = “username";$password = “password";$database = "folkinstruments";$con = mysqli_connect($host, $username, $password, $database) or trigger_error(mysqli_error(),E_USER_ERROR);
$query = mysqli_query($con, "SELECT text, pix FROM instruments WHERE instrumentid = '$id'") or die("A MySQL query error has occurred.<br />Error number: ". mysql_errno() ."<br / >". mysql_error());$row = mysqli_fetch_assoc($query);
echo $row['text']."END".$row['pix'];
mysqli_free_result($query);mysqli_close($con);?>
157
Lab: folk music – MySQL
Update the links Instruments:<br /> <a href="#" onclick="ajaxObject(3)">Baglama</a><br /> <a href="#" onclick="ajaxObject(1)">Darbuka</a><br /> <a href="#" onclick="ajaxObject(4)">Kabak Kemane</a><br /> <a href="#" onclick="ajaxObject(5)">Karadeniz Kemence</a><br /> <a href="#" onclick="ajaxObject(6)">Kaval</a><br /> <a href="#" onclick="ajaxObject(7)">Tar</a><br /> <a href="#" onclick="ajaxObject(2)">Ud</a><br /> <a href="#" onclick="ajaxObject(8)">Zurna</a><br />
158
Lab: folk music – MySQL
Done! Update and view your site
159
Assignment: your hobby
Make an Ajax site
Topic: your choice
One type of data (XML, JSON, MySQL)
At least 4 entries
Web ProgrammingSE 480:
Week 10: Ajax Data SourcesCopyright © Steven W. Johnson
October 1, 2012