se 480: client side scripting languages week 10: ajax data sources copyright © steven w. johnson...
TRANSCRIPT
SE 480: Client Side Scripting Languages
Week 10: Ajax Data SourcesCopyright © Steven W. Johnson
October 1, 2014
2
Ajax using XML, JSON, MySQL
Overcoming Ajax weaknesses
Introduction to JSON
Week 10
3Web 1.0
logic
structure: HTML
presentation
locations
Web 1.0: HTML is “star of the show”
Web 1.0: uses ‘pages in a book’ paradigm
All about page transmission using HTTP
What is Ajax?
4Web 2.0 Web 1.0
What is Ajax?Web 2.0: applications and ‘web-as-a-movie’
download an interface
transmit data to update the page
5
What is Ajax?A new Separation of Concerns?
Structure
Presentation
Logic
Data
6
Many problems:
any page-based idea no longer applies
page navigation
bookmarks
‘send me your URL’
search engines: dynamic content is ‘deep web’
security concerns (injecting content)
JavaScript issues
no graceful degradation
What is Ajax?
7
Douglas Crockford, a big name in JavaScript
Described JSON (2002)
Part of ECMAScript, RFC 4627 (2006)
JavaScript Object Notation (JSON)
8
Does have a logo
Has a web site (json.org)
Incorporated into ISO; standardized
JavaScript Object Notation (JSON)
9
Data interchange (kavşak) format
Serializes (sıralı) objects into strings, to be sent from server to client, keeps them in ‘objectness’
Serial: one bit or digit per cycle; one event
Parallel: several bits per cycle; many events
JavaScript Object Notation (JSON)
10
Basic form: uses name/value pairs
Similar to XML, but no closing tags
Easy access to data, human-readable
JavaScript Object Notation (JSON)
{“firstname”: “Canan”}
firstname = “Canan”;
11
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
All data sources are like 2-dimensional arrays
Table: records (rows) and fields columns
JavaScript Object Notation (JSON)
{“name”: “Ali”, “age”: 20, “bolum”: “MBBF” }
12
Many string values identified in same “record”
Information defining one person/entity
Strings in quotes; numbers not
JavaScript Object Notation (JSON)
array = [[“Cem”, “Ali”, “Eda”],[18, 22, 24]];
{students = [ {“name”:“Ali”, “age”:20, “bolum”:“MBBF” }, {“name”:“Bahar”, “age”:21, “bolum”:“ITF” }]}
13
Arrays used to represent objects
Curly brackets define entities
Square brackets define entire source
Quotes on text, numbers left alone
JavaScript Object Notation (JSON)
students = [ {“name”:“Ali”, “age”:20, “bolum”:“MBBF” }, {“name”:“Bahar”, “age”:21, “bolum”:“ITF” }];
14
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
All three represent the same data; “records”
Effectively a database table
JavaScript Object Notation (JSON)
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
An array of arrays or a database with 2 tables
‘Company’ is DB, tables ‘employees’, ‘managers’
JavaScript Object Notation (JSON)
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”;
Updating table values
JavaScript Object Notation (JSON)
17
indx = 1;JSONObj = JSON.parse(xmlhttp.responseText);document.getElementById(“a”).innerHTML = JSONObj[indx].first; //Annadocument.getElementById(“b”).innerHTML = JSONObj[indx].last; //Smith
[ {"first":"John" , "last":"Doe" , "age":18}, {"first":"Anna" , "last":"Smith" , "age":20}, {"first":"Peter" , "last":"Jones“ , "age":21}]
JSON.parse converts objects into strings
Native (dahil) in browsers since IE 8
JavaScript Object Notation (JSON)
XML:XMLObj = xmlhttp.responseXML;
JSON:JSONObj = JSON.parse(xmlhttp.responseText);
18
Similar to XML except:
Both are read from ‘inside’ Ajax
Different in:
XML uses ‘getElementsByTagName’
JSON uses JSON.parse()
JavaScript Object Notation (JSON)
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;
19
‘JSON.parse’ method exposes data to Ajax
JavaScript Object Notation (JSON)
20
data.txtdata.json
.json and .txt are both text file formats
File holds an object/array (data source)
Ajax calls object and extracts data
JavaScript Object Notation (JSON)
21
page.html
array = []
json.txtdata.json
Concept: JSON data source on server
Call server with address in array/database
Update page without refreshing entire page
JavaScript Object Notation (JSON)
22
“students”= [ {“name”: “Ali”, “age”: “20”, “bolum”: “MBBF”, “gender”: “Erkek” }, {“name”: “Bahar”, “age”: “21”, “bolum”: “ITF”, “gender”: “Hanim” }]
<?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 vs. XML:
JavaScript Object Notation (JSON)
23
<name>Steve</name>
“name”: “Steve”,
JSON vs. 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
JavaScript Object Notation (JSON)
24
Advantages to JSON:
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)
JavaScript Object Notation (JSON)
25
Disadvantages to JSON:
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
XML is more precise tool (has its own
DTD)
XML has better support (libraries, etc)
JavaScript Object Notation (JSON)
26
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
x-dimensional array saved as ‘employees’
objname[i].fieldname
JavaScript Object Notation (JSON)
27
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
x-dimensional array saved as ‘employees’
Create JSON data source
TV stars or singers
Use JavaScript to ‘document.write’ out data
Lab: JSON
Break
29
<name>Ali</name>
{“name”:“Ali”}
Name
Ali
Arguably hardest part of labs/assignment
Data formats have same idea:
‘field name’
‘data’
Lab: JSON
30
<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+ ‘”}’
Utilities do exist to transfer data
Can manually convert using a language
Data formats
31
<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+ ‘”}’
Utilities do exist to transfer data
Can manually convert using a language
Lab: conversion
32
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’
Lab: harika harran’s
33
Beginning interface:
Lab: harika harran’s
34
Move to 12 and do with jQuery?
Lab: harika harran’s
35
Make the database: registerdb
3 tables:
register data (mix user and pass)
area code
city code
Lab: harika harran’s
36
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)
Lab: harika harran’s
37
Make the database: registerdb
Create table ‘areacodes’ with 2 fields:
codeId (int, 5, primary, auto-increment)
areacode (varchar, 4, unique)
Lab: harika harran’s
38
Make the database: registerdb
Create table ‘officecodes’ with 3 fields:
officeId (int, 5, primary, auto-increment)
codeId (int, 5)
officecode (int, 3, unique)
Lab: harika harran’s
39
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);
Lab: harika harran’s
40
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);
Drags on performance:
Lab: harika harran’s
41
Open register folder, register.php:
Form built, table started
Lab: harika harran’s
42
25 pixels wide
Make the form (tab at end of row to make new row)
Lab: harika harran’s
43
Use these ids, give each the same name: box
Lab: harika harran’s
44
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"
Add these ids, classes
Lab: harika harran’s
45
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
46
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
47
Username: 6 to 12 characters (letters/numbers)
Password: 6 to 12 characters (letters/numbers)
Password == Verify password
Lab: harika harran’s
48
Telephone: NAPN
11 digits
1: ==0
2: != 1
5: !=1
Area code in table
Office code must match
Disadvantages of Ajax
49
0232 0532 0287254 508 841
274 400 305
337 387 261
City code and area code must ‘match’
Disadvantages of Ajax
50
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
Disadvantages of Ajax
51
for( ) { flag[i] = 0;}
How about the ‘submit’ button?
Lab: harika harran’s
52
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
53
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
54
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();}
“error routine”:
insert red “X” and error text (vary)
reset focus, selection
Lab: harika harran’s
55
function submitbutton() { document.getElementById("Submit").disabled=false; for (i=0; i<7; i++) { if(flag[i]==0) {
document.getElementById("Submit").disabled=true; break;
} } }
Setting the submit button
Lab: harika harran’s
56
<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;}
Create .js file: scripts.js
Save files, test
Lab: harika harran’s
57
<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>
Create embedded styles:
Lab: harika harran’s
58
flag=[];flag[0] = 0;flag[1] = 0;flag[2] = 0;flag[3] = 0;flag[4] = 0;flag[5] = 0;flag[6] = 0;
Initialize the flags (for validation):
Lab: harika harran’s
59
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; }}
Drags on performance:
Disadvantages of Ajax
60
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; } }}
Drags on performance:
Disadvantages of Ajax
61
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; } }}
62
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; } }}
63
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; } }}
64
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; } }}
65
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 }}?>
66
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);?>
67
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);}?>
Quiz:
1. What is the address of the value 24?
68
12 16 175 8 123 24 6
[2, 1]
Quiz:
2. Place this array in the table:
69
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?
70
<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?
71
<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
72
1
<aaa> <bbb> <ccc>11</ccc> <ccc>22</ccc> <ccc>33</ccc> </bbb></aaa>
22
Quiz:
9. JSON array of 3 names:
73
friends = [ {“name”:”Ali”, “name”:”Bahar”, “name”:”Canan”}];
Quiz:
10. What is the value of company.employees[1].age?
74
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
SE 480: Client Side Scripting Languages
Week 10: Ajax Data SourcesCopyright © Steven W. Johnson
October 1, 2014
76
Labs:
Register (validate, check user table)
Folk music:
DHTML
XML
JSON
Assignment: Your hobby
Lab: folk music
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
Drags on performance:
Disadvantages of Ajax
78
Make Web 2.0 application using Ajax
Labs: folk music
79
Make Web 2.0 application using:
No-jax (DHTML)
3 Ajax alternatives:
XML
JSON
MySQL
Use ‘highly-borrowed’ Turkish Folk Music site
Labs: folk music
80
page.html
Our choices. Which is best?
Labs: folk music
81
Process is same regardless of data source
store and maintain the data*
build and maintain the site*
access the data
identify the required record
insert values to layers
Lab: folk music
82
DHTML data:
Lab: folk music
function kemanedisplay() { document.getElementById("text").innerHTML = "<p>The kabak kemane (gourd fiddle) is commonly used in the Aegean region of Turkey. It is the present evolution of the old iklig. Traditionally made from a water gourd, the body can be constructed of wood as well. The bow is strung with either horsehair or monofilament.</p>"; document.getElementById("pix").innerHTML = "<img src='images/kemane.png' width='185' height='250' alt='Kemane' title='Kemane'>";}
83
<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
XML data:
Lab: folk music
84
[{ “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
JSON data:
Lab: folk music
85
MySQL data:
Lab: folk music
86
page.html
Ways to do DHTML:
‘show/hide’ layers based on ‘click’ event
‘.innerHTML’ values based on ‘click’
Hardest to update/modify?
Lab: folk music - DHTML
87
Difference:
seven sections with content for layers
seven functions with content for one-section
Lab: folk music – DHTML layers
<section>
<section>
<section>
<section><section>
<section>
<section>
<section>
88
Start with ‘insert data from functions’ option
Pix of process: 3 layers across bottom
Lab: folk music - DHTML
picture text
89
Each link inserts unique data to same place
Use event listeners to select function used
ID the links:
Lab: folk music - DHTML
<section id="links"> Instruments:<br> <a href=“#” id=“baglama”>Baglama</a><br> <a href=“#” id=“darbaka”>Darbuka</a><br> <a href=“#” id=“kemane”>Kabak Kemane</a><br> <a href=“#” id=“kemence”>Karadeniz Kemence</a><br> <a href=“#” id=“kaval”>Kaval</a><br> <a href=“#” id=“tar”>Tar</a><br> <a href=“#” id=“ud”>Ud</a><br> <a href="#” id=“zurna”>Zurna</a><br></section>
ud.addEventListener(‘click’, uddisplay, false);baglama.addEventListener(‘click’, baglamadisplay, false);darbaka.addEventListener(‘click’, darbakadisplay, false);kemane.addEventListener(‘click’, kemanedisplay, false);kemence.addEventListener(‘click’, kemencedisplay, false);kaval.addEventListener(‘click’, kavaldisplay, false);tar.addEventListener(‘click’, tardisplay, false);zurna.addEventListener(‘click’, zurnadisplay, false);
90
Functions are written in ‘dhtml.js’
You need to add event listeners
Lab: folk music - DHTML
function kemanedisplay() { document.getElementById("text").innerHTML = "<p>The kabak kemane (gourd fiddle) is commonly used in the Aegean region of Turkey. It is the present evolution of the old iklig. Traditionally made from a water gourd, the body can be constructed of wood as well. The bow is strung with either horsehair or monofilament.</p>"; document.getElementById("pix").innerHTML = "<img src='images/kemane.png' width='185' height='250' alt='Kemane' title='Kemane'>";}
91
Done. Save your work and view in browser
Lab: folk music - DHTML
92
Open ‘folk’ and ‘dhtmllayers.html’
Application made up of 6 sections (layers)
image and text in same layer
uses ‘innerHTML’
Lab: folk music - DHTML
93
One section for each instrument instead of a general ‘pix’ and ‘text’ section
Use listeners to select the section
Basic page code/style sheet the same
Lab: folk music – DHTML layers
94
Each section needs:
Individual identification (id)
Group identification (class)
Links needs to have:
id (for event listener: layer0-7)
name (unique identifier for instrument: 0-7)
“inst”+name = id for section
Lab: folk music - DHTML
“inst0-7”
“instrument”
95
Stylesheet is ready to go
Instead of #text and #pic; use .instrument
Lab: folk music - DHTML
96
Fix ‘dhtmllayers.html’:
Add id, name to the links (identify
instrument)
Lab: folk music - DHTML
<section id="links"> Instruments:<br> <a href=“#” id=“layer0” name=“0”>Baglama</a><br> <a href=“#" id=“layer1” name=“1”>Darbuka</a><br> <a href=“#” id=“layer2” name=“2”>Kabak Kemane</a><br> <a href=“#” id=“layer3” name=“3”>Karadeniz Kemence</a><br> <a href=“#” id=“layer4” name=“4”>Kaval</a><br> <a href=“#” id=“layer5” name=“5”>Tar</a><br> <a href=“#” id=“layer6” name=“6”>Ud</a><br> <a href=“#” id=“layer7” name=“7”>Zurna</a><br></section>
97
Fix ‘dhtmllayers.html’:
Add id, class to each section with
instrument
Lab: folk music - DHTML
<section id=“inst0” class=“instrument”>//baglama<section id=“inst1” class=“instrument”>//darbaku<section id=“inst2” class=“instrument”>//kemane<section id=“inst3” class=“instrument”>//kemence<section id=“inst4” class=“instrument”>//kaval<section id=“inst5” class=“instrument”>//tar<section id=“inst6” class=“instrument”>//ud<section id=“inst7” class=“instrument”>//zurna
98
Fix ‘dhtmllayers.html’:
create include at bottom of page for
listeners
Lab: folk music - DHTML
</section> <script src=“data/dhtmllisteners.js”></script> </body></html>
99
Create ‘dhtmllisteners.js’
Add the event listeners at top
Lab: folk music - DHTML
layer0.addEventListener(‘click’, instdisplay, false);layer1.addEventListener(‘click’, instdisplay, false);layer2.addEventListener(‘click’, instdisplay, false);layer3.addEventListener(‘click’, instdisplay, false);layer4.addEventListener(‘click’, instdisplay, false);layer5.addEventListener(‘click', instdisplay, false);layer6.addEventListener(‘click’, instdisplay, false);layer7.addEventListener(‘click’, instdisplay, false);
100
Add ‘instdisplay’ function:
pass in name (0-7); count the sections
close all sections first
open the desired section last
Lab: folk music - DHTML
function instdisplay() { number = this.name; quantity = document.getElementsByClassName("instrument"); long = quantity.length; for (i=0; i<long; i++) { document.getElementById(“inst”+i).style.display = "none"; } document.getElementById(“inst”+number).style.display = "block";}
101
Done! Save your work and view
Lab: folk music - DHTML
102
page.html XMLHttpRequest
<instruments> <name>kaval</name> <image><img src…> <text>A Kaval…</text>
pix = <img src=… text = “A Kaval…
Pull in XML file
Find record we want to see
Display it
Lab: folk music - XML
103
Data store in tag hierarchy; use DOM to find
Call in ‘text’ and ‘pix’ for display (collection of 8)
Lab: folk music - XML
<xml version “1.0” encoding=“utf-8”> <instruments> <instrument> <instrumentId>1</instrumentId> <instrument>Darbuka</instrument> <text><p>A darbuka is … basic rhythm. </p></text> <pix><img src=“images/darbuka.png” width=“233”></pix> </instrument>
</instruments>
104
Cannot use ‘<‘ or ‘>’; instead use < and >
No need to escape quotes or apostrophes
Easier to prepare data than JSON
Lab: folk music - XML
<xml version “1.0” encoding=“utf-8”> <instruments> <instrument> <instrumentId>1</instrumentId> <instrument>Darbuka</instrument> <text><p>A darbuka is … basic rhythm. </p></text> <pix><img src=“images/darbuka.png” width=“233”></pix> </instrument>
</instruments>
105
</section> <script src="../xmlhttp.js"></script> <script src="data/xmldata.js"></script> </body></html>
Open xml.html (exactly like DHTML version)
Use the same style sheet
Add include for request object (test connection??)
Create ‘xmldata.js’ in ‘data’ folder
Add include for ‘xmldata.js’ file (text connection??)
Lab: folk music - XML
106
Instruments:<br> <a href="#" id=“baglama” name=“0”>Baglama</a><br> <a href="#" id=“darbuka” name=“1”>Darbuka</a><br> <a href="#" id=“kemane” name=“2”>Kabak Kemane</a><br> <a href="#" id=“kemence” name=“3”>Karadeniz Kemence</a><br> <a href="#" id=“kaval” name=“4”>Kaval</a><br> <a href="#" id=“tar” name=“5”>Tar</a><br> <a href="#" id=“ud” name=“6”>Ud</a><br> <a href="#" id=“zurna” name=“7”>Zurna</a><br>
Place ‘id’ on links to identify instrument
Pass index value; use ‘name’ for that
Save the page
Lab: folk music - XML
107
baglama.addEventListener('click', ajax, false);darbuka.addEventListener('click', ajax, false);kemane.addEventListener('click', ajax, false);kemence.addEventListener('click', ajax, false);kaval.addEventListener('click', ajax, false);tar.addEventListener('click', ajax, false);ud.addEventListener('click', ajax, false);zurna.addEventListener('click', ajax, false);
Open ‘xmldata.js’. To do:
add event listeners
write your function
call in the XML object and save to a variable
parse it into little pieces
Lab: folk music - XML
108
function ajax() { document.getElementById("text").innerHTML = ""; document.getElementById("pix").innerHTML = ""; inst = this.name;
The function:
clear out old data (not absolutely required…)
get the name (determine the XML index)
test readyState and status
read in the XML object and parse
Lab: folk music - XML
109
function ajax() { xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
…
} } xmlhttp.open("GET", "data/xmldata.xml", true); xmlhttp.send(null);}
The function:
test readyState and status
read in the XML object and parse
Lab: folk music - XML
110
xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { XMLObj = xmlhttp.responseXML; replytext = XMLObj.getElementsByTagName("text"); replypix = XMLObj.getElementsByTagName("pix"); document.getElementById("text").innerHTML = replytext[inst].childNodes[0].nodeValue; document.getElementById("pix").innerHTML = replypix[inst].childNodes[0].nodeValue; }} xmlhttp.open("GET", "data/xmldata.xml", true);xmlhttp.send(null);}
The function:
read in the XML object and parse
Lab: folk music - XML
111
xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { XMLObj = xmlhttp.responseXML; replytext = XMLObj.getElementsByTagName("text"); replypix = XMLObj.getElementsByTagName("pix"); document.getElementById("text").innerHTML = replytext[inst].childNodes[0].nodeValue; document.getElementById("pix").innerHTML = replypix[inst].childNodes[0].nodeValue; }} xmlhttp.open("GET", "data/xmldata.xml", true);xmlhttp.send(null);}
Done! Save page and view in browser:
http://localhost/folk/xml.html
Lab: folk music - XML
112
{xxxxx, yyyyyy}
JSON uses any file that holds text (.js, .txt, .json, etc.)
Process is very similar to XML system
Lab: folk music - JSON
page.html XMLHttpRequest
113
[ {"id":“0", "text":"</p>The bağlama … </p>", "pix":"<img src … title="Baglama" />" }, {"id":"1", "text":"<p>A darbuka … </p>", "pix":"<img src=“ … title="Darbuka" />" }, {"id":“2", "text":"<p>The kabak kemane … </p>", "pix":"<img src= … title="Kabak Kemane" />" }, {"id":“3", "text":"<p>The Karadeniz ….</p>”, "pix":"<img src= … title="Karadeniz" />" }, {"id":“4", "text":"<p>The kaval … </p>, pix:”img src= … title="Kaval" />" }, {"id":“5", "text":"<p>The tar … </p>", "pix":"<img src= … title="Tar" />" }, {"id":“6", "text":"<p>The ud … </p>", "pix":"<img src … title="Ud" />" }, {"id":“7", "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
114
</section> <script src="../xmlhttp.js"></script> <script src="data/jsondata.js"></script> </body></html>
To do on json.html:
include request object
include .js file for script
build id and name for links
Lab: folk music - JSON
115
<section id="links"> Instruments:<br> <a href="#" id="baglama" name="0">Baglama</a><br> <a href="#" id="darbuka" name="1">Darbuka</a><br> <a href="#" id="kemane" name="2">Kabak Kemane</a><br> <a href="#" id="kemence" name="3">Karadeniz Kemence</a><br> <a href="#" id="kaval" name="4">Kaval</a><br> <a href="#" id="tar" name="5">Tar</a><br> <a href="#" id="ud" name="6">Ud</a><br> <a href="#" id="zurna" name="7">Zurna</a><br></section>
To do on json.html:
include request object
include .js file for script
build id and name for links
Lab: folk music - JSON
116
Create ‘jsondata.js’ and save to ‘data’ folder:
add event listeners
write our json function:
clear the page
get the name (instrument index)
call in the json data
parse the data
display the data
Lab: folk music - JSON
117
Create ‘jsondata.js’ and save to ‘data’ folder:
add event listeners
Lab: folk music - JSON
baglama.addEventListener('click', json, false);darbuka.addEventListener('click', json, false);kemane.addEventListener('click', json, false);kemence.addEventListener('click', json, false);kaval.addEventListener('click', json, false);tar.addEventListener('click', json, false);ud.addEventListener('click', json, false);zurna.addEventListener('click', json, false);
118
JSON function:
Lab: folk music - JSON
function json() { document.getElementById(“text”).innerHTML = ""; document.getElementById(“pix”).innerHTML = ""; inst = this.name; xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { JSONObj = JSON.parse(xmlhttp.responseText); document.getElementById(“text”).innerHTML = JSONObj[inst].text; document.getElementById(“pix”).innerHTML = JSONObj[inst].pix; } } xmlhttp.open(“GET”, “data/jsondata.json”, true); xmlhttp.send(null);}
119
Done! Save page and view in browser:
Lab: folk music - JSON
120
MySQL: PHP used as interface
Query written in PHP to get data from table
Query is recordset for one record: our index
Lab: folk music - MySQL
page.html XMLHttpRequestaccess.html
Pass parameter (based on link) from Ajax to PHP
PHP uses parameter to define recordset
Recordset sent to HTML, split into “pix”, “text”
Data entered into sections
Lab: folk music - MySQL
mysql.php
122
Turn on web server
Open http://localhost/apanel/phpmyadmin
Click on ‘Databases’ tab
Create database (in textbox) ‘folk’ (“Create”)
Select ‘folk’ database (left window)
Click on “SQL” tab
Insert text ‘mysqldata.txt’ into window (“Go”)
Lab: folk music - MySQL
123
</section> <script src=“../xmlhttp.js”></script> <script src=“data/mysqldata.js”></script> </body></html>
To do on json.html:
include request object
include .js file for script
Lab: folk music - MySQL
124
<section id="links"> Instruments:<br> <a href=“#” id=“baglama” name=“1”>Baglama</a><br> <a href=“#” id=“darbuka” name=“2”>Darbuka</a><br> <a href=“#” id=“kemane” name=“3”>Kabak Kemane</a><br> <a href=“#” id=“kemence” name=“4”>Karadeniz Kemence</a><br> <a href=“#” id=“kaval” name=“5”>Kaval</a><br> <a href=“#” id=“tar” name=“6”>Tar</a><br> <a href=“#” id=“ud” name=“7”>Ud</a><br> <a href=“#” id=“zurna” name=“8”>Zurna</a><br></section>
To do on json.html:
build id and name for links:
id is used for the event listener
‘name’ matches instrument ID in database
Lab: folk music - MySQL
125
Create ‘mysqldata.js’ and save to ‘data’ folder:
add event listeners
write our mysql function:
clear the page
get the name (instrument index)
send the index to the database
on return, split data
display data in sections
Lab: folk music - MySQL
126
Create ‘jsondata.js’ and save to ‘data’ folder:
add event listeners
Lab: folk music - MySQL
baglama.addEventListener(‘click’, mysql, false);darbuka.addEventListener(‘click’, mysql, false);kemane.addEventListener(‘click’, mysql, false);kemence.addEventListener(‘click’, mysql, false);kaval.addEventListener(‘click’, mysql, false);tar.addEventListener(‘click’, mysql, false);ud.addEventListener(‘click’, mysql, false);zurna.addEventListener(‘click’, mysql, false);
127
mysql function:
Lab: folk music - MySQL
function mysql() { document.getElementById(‘text”).innerHTML = ""; document.getElementById(“pix”).innerHTML = ""; inst = this.name; url = “query.php?inst=” +inst; xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { var MySQLObj = xmlhttp.responseText; output = MySQLObj.split(“END”); document.getElementById(“pix”).innerHTML = output[1]; document.getElementById(“text”).innerHTML = output[0]; } } xmlhttp.open(“GET”, url, true); xmlhttp.send(null);}
128
Query steps on ‘query.php’:
find the correct recordset
put ‘text’ and ‘pix’ strings into single string
such that: ‘text’END‘pix’
return that string to ‘mysql.html’
Lab: folk music - MySQL
129
<?php
$id = $_GET['inst']; $host = "127.0.0.1"; $username = "username"; //fix this $password = "password"; //fix this $database = "folk"; $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);?>
Open ‘query.php’ in ‘folk’ folder (ready)
Lab: folk music - MySQL
130
Done! Save files to web server and test:
http://localhost/folk/mysql.html
Lab: folk music - MySQL
Break
132
Make an Ajax site, may NOT use DHTML
Topic: your choice
One type of data (XML, JSON, MySQL)
At least 4 entries
Make your own web page (NOT mine)
Assignment: your hobby
SE 480: Client Side Scripting Languages
Week 10: Ajax Data SourcesCopyright © Steven W. Johnson
October 1, 2014