EECS 1012 Net-centric Introduction to Computing Lecture "Putting It All Together" and a little bit of AJAX Acknowledgements The contents of these slides may be modified and redistributed, please give appropriate credit. (Creative Commons) Michael S. Brown, 2017. M.S. Brown, EECS York University 1
2 HTML, CSS, PHP, and JavaScript
HTML 3 HTML Provides the markup language to generate the structure and content of a webpage.
CSS 4 CSS Provides the markup language to modify the appearance of the webpage.
PHP (server-side scripting) 5 PHP Allowed dynamic generation of HTML content. This could be used with HTML forms to generate content based on data sent by the user.
JavaScript (client-side scripting) 6 JavaScript Allowed our pages to be interactive, without having to contact the server. Provided the ability to add "behavior" to the webpage.
The sweet spot 7 JavaScript Putting this all together, we create the best of our web experiences. PHP HTML CSS
8 Putting it all together
Three examples 9 1. Keeping track of # of visitors (PHP only) 2. Inspirational quotes 1. without AJAX 2. with AJAX 3. Online "to do" list
10 Example 1: # of visitors
Tracking # of visitors to your page 11 Revisit our initial webpage aboutme.html
HTML page redirected to PHP 12 We'd prefer the user to type in an HTML page instead of a PHP page We can "redirect" the initial HTML page to our PHP page
HTML Redirect 13 We can have our initial HTML page redirected to a PHP version. aboutme.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> : Lab 1 </title> <meta http-equiv="refresh" content="0; URL='http://localhost/aboutme.php'"> </head> <body> </body> </html> Re-directs to aboutme.php after waiting 0 seconds
HTML Redirect 14 <meta http-equiv="refresh" content="0; url='http://localhost/aboutme.php'"> Note that the content attribute has double quotes around the following: wait_time_in_seconds; url='url to be redirected to'
Back to our example 15 Revisit our initial webpage aboutme.html Our PHP code will modify this part of the webpage only.
PHP code added to HTML page 16 HTML code <?php /* First check if file exists, if doesn't exist save "1" to it */ if (file_exists("visitorcount.txt") == false) { file_put_contents("visitorcount.txt", "1"); /* retrieve content, add one to it, write it back*/ $count = file_get_contents("visitorcount.txt"); $count = $count + 1; file_put_contents("visitorcount.txt", $count); /* write back to file */ /* print the visitor's count info */ print "<p style=\"text-align: center;\"> ". /* concat this */ "You are visitor $count </p> \n"; /* w/ next line */?> </body> </html>
What is going on? 17 Client (browser) Server visitorcount.txt File Client requests HTML page. 1) HTML page redirected to PHP 2) PHP opens the "visitorcount.txt". Adds one to the value, writes it back to the file. Prints the value from the file, writes it to the HTML page.
18 Example #2 - Quotes Revisited
Remember this PHP code? 19 Every time you visited the page, it returned a different quote!
How this PHP code worked 20 PHP code <?php $quotes = file("quotes.txt"); $i = array_rand($quotes); $output = htmlspecialchars($quotes[$i]); print "<p> <quote> $output </quote> </p> \n";?> "quotes.txt" Quote1... Quote2... Quote3 Quote. Opens a "quotes.txt" file as an array. Selects random an array index. Converts string using htmlspecialchars(..). Prints the string to a <p> tag.
Quotes using PHP 21 Client (browser) Quote Access PHP file Random Quote appears. We page is refreshed in browser Server File Open's quote.txt generates a new HTML sends it If you want another quote, you have to access the PHP code again.
Problem? 22 To change the quote, we need to call the PHP file again (i.e. refresh the webpage) This will update the entire webpage Can we somehow pass the data in the "quotes.txt" to our JavaScript file?
We want an interactive quote via JS 23. Add quotes here. These change on their own every 3 seconds.
PHP creates the quote in the HTML 24 <div id="box"> <?php print "<p>"; print '<button id="next">next</button><button id="stop">stop</button>'; print " <quote id=\"quote_footer\"> $output </quote> </p> ";?> </div>
25 Javascript code var timerid = null; var quoteid = 0; window.onload = function () { $("next").onclick = nextquote; $("stop").onclick = stoptimer; timerid = setinterval(nextquote, 3000); Set up "onclick" events. Set timer to change to next Quote. Be nice to have an array of all the quotes on the client side (i.e. inside JavaScript) function nextquote() { $("quote_footer").innerhtml = quotes[quoteid]; quoteid++; if (quoteid >= quotes.length) quoteid=0; function stoptimer() { clearinterval(timerid); nextquote changes to new quote in array quotes[ ]; stoptimer() clears the intervaltimer.
Where do we get the "quotes[]"? 26 function nextquote() { $("quote_footer").innerhtml = quotes[quoteid]; quoteid++; if (quoteid >= quotes.length) quoteid=0; function stoptimer() { clearinterval(timerid); Variable we use should contain all the quotes from the "quotes.txt" file. But this file is on the server! "quotes.txt" Quote1... Quote2... Quote3 Quote. Ideally, we'd like: quotes = [ "Quote1", "Quote2", "Quote3",., "QuoteLast" ];
Use PHP to modify our JS file! 27 <?php $quotes = file("quotes.txt"); /* open file */ $write_to_java = "var quotes=[ "; /* generate JS code */ $count = count($quotes); /* an array named "quotes" */ for($i=0; $i < $count-1; $i++) /* loop through quotes */ { $output = htmlspecialchars(trim($quotes[$i])); /* convert */ $write_to_java.= "\"$output\","; /* write to array string */ $output = htmlspecialchars(trim($quotes[$count-1])); /* last Quote */ $write_to_java.= "\"$output\" ];"; /* print with ]; end */ /* open JS "template" file read whole file in as a string */ $JSFile = file_get_contents("quotes_template.js"); /* write the variable part to the string using concatenate. operator */ $JSFile.= $write_to_java; file_put_contents("quotes.js", $JSFile); /* save the JS file */?>
What just happened? 28 aboutme2.php quotes.txt Client (browser) Access PHP file HTML output + updated JS file Server File quotes_template.js JS File (1) There is only one call to the PHP file. It modifies the JS file as necessary. (3) All necessary data is now in JS file. We can update quote using JS. Client (browser) Quote (2) PHP file modified the JS code. copy quotes_template.js's content + add the generated var quotes = ["Quote1", "Quote2", "Quote3", ]; JS File with array from Quote
JS code generated by our PHP program 29 var quotes=[ ""If you want to achieve greatness stop asking for permission." -- Anonymous",""Things work out best for those who make the best of how things work out." --John Wooden",""To live a creative life, we must lose our fear of being wrong." --Anonymous",""If you are not willing to risk the usual you will have to settle for the ordinary." --Jim Rohn",""Trust because you are willing to accept the risk, not because it's safe or certain." --Anonymous",""Take up one idea. Make that one idea your life--think of it, dream of it, live on that idea. Let the brain, muscles, nerves, every part of your body, be full of that idea, and just leave every other idea alone. This is the way to success." --Swami Vivekananda",""All our dreams can come true if we have the courage to pursue them." --Walt Disney",""Good things come to people who wait, but better things come to those who go out and get them." -- Anonymous",""If you do what you always did, you will get what you always got." --Anonymous",""Success is walking from failure to failure with no loss of enthusiasm." --Winston Churchill",""Just when the caterpillar thought the world was ending, he turned into a butterfly." --Proverb",""Successful entrepreneurs are givers and not takers of positive energy." --Anonymous",""Whenever you see a successful person you only see the public glories, never the private sacrifices to reach them." --Vaibhav Shah" ];
Code generation 30 This style is known as "code generation" That is, the PHP program generated new code This is generally considered bad style, but is fairly common This style of code generation is working within the synchronized mode of web server access
Synchronous web access 31 In this case "event" is submitting a form, or loading a page. synchronous: user must wait while new pages load the typical communication pattern used in web pages (click, wait, refresh)
32 AJAX
Asynchronous access 33 Result is sent to JavaScript. JS can be used to modify the page. The key here is "partial page". JS is used to update the webpage.
Asynchronous JavaScript And XML 34 AJAX (Asychronous JS and XML) XML = extensive markup language AJAX This is a method to encode up data This is also a slightly incorrect term, because AJAX does not require XML as we will see. Allows JS to make a request to the server using XMLHttpRequest When request returns, an event hanlder is called with the result JS can update the webpage based on the result
How it works 35 https://www.w3schools.com/xml/ajax_intro.asp
AJAX - for our quotes example 36 var quote = null; var timerid; window.onload = function () { $("next").onclick = updatequote; $("stop").onclick = stoptimer; timerid = setinterval(getquote, 3000); function updatequote() { $("quote_footer").innerhtml = quote; function stoptimer() { clearinterval(timerid); function getquote() { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (this.readystate == 4) { if (this.status == 200) { quote = this.responsetext; updatequote(); ; xmlhttp.open("get", "quotes.php", true); xmlhttp.send(); AJAX code
Examining the AJAX Request 37 function getquote() { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (this.readystate == 4) { if (this.status == 200) { quote = this.responsetext; updatequote(); ; xmlhttp.open("get", "quotes.php", true); xmlhttp.send(); Create an "AJAX request" Define an anonymous function to handle the result when it comes back. When the event results, check status to make sure it worked (see next slide). Set variable "quote" to the response from the AJAX call. Call the "updatequote()" function. This opens the connection to the browser. We send a "GET" post (like forms). We call the PHP file "quotes.php". send() sends the request established in "open". "true" means this is an asynchronous call.
readystate and status 38 Property onreadystatechange Description Stores a function (or the name of a function) to be called automatically each time the readystate property changes. This is the event handler that processes the result after the rquest has been sent. readystate Holds the status of the XMLHttpRequest. Changes from 0 to 1-4: 0: request not initialized 1: server connection established 2: request received 3: processing request 4: request finished and response is ready status 200: "OK" (everything was fine) 404: Page not found (something went wrong) See previous slide, we check to make sure the readystate=4 and status=200.
Example PHP quotes.php 39 <?php $quotes = file("quotes.txt"); /* open file as an array */ $i = array_rand($quotes); /* select random index into array */ $response = htmlspecialchars($quotes[$i]); /*convert to HTML */ /*special char encoding */ print $response; /* output response this will returned to the */ /* XMLHttpRequest(); */?> This is the PHP code called by our XMLHttpRequest(); Note how it doesn't have any HTML output only prints out the string directly.
What is happening? 40 Client (browser) Access PHP file HTML output to browser aboutme2.php Server quotes.txt File JS sends AJAX request JS updates webpage when request returns Client (browser) Quote AJAX access PHP file AJAX return to JS (Does not require webpage to be refreshed) quotes.php Server quotes.txt File
41 Example #3 Online Todo
Online 'ToDo List' 42 todo.html, todo.css, todo.js List items are stored on the server. When the webpage loads, we retrieve the items. If we delete or add, we send the info to the server.
Todo HTML and Todo PHP 43 todo.html Client (browser) Basic HTML page with JS code Server todo.php todo.txt Client JS code makes (browser) three types of AJAX calls: (1) todo.php?getlist=true (2) todo.pp?delete=item (3) todo.php?add=item Server File PHP application responses depending on type of request
HTML code 44 "myinput" "addbutton" "myul" <body> "messagespan" <div id="mydiv"> <h2>my Online ToDo List</h2> <p> New item: <input type="text" id="myinput"> <button id="addbutton">add</button> </p> <ul id="myul"> </ul> <p> <span id="messagespan">hi</span> </p> </div> </body>
Multi-purpose PHP code 45 Our JS code will make the following three calls to the PHP program: 1. todo.php?getlist=true 2. todo.php?add=item_to_add 3. todo.php?delete=item_to_delete
Multi-purpose PHP code 46 <?php /* Get the list */ if (isset($_get["getlist"])) { $content = file("todo.txt"); for($i=0; $i < count($content); $i++) { print trim($content[$i]). "\n"; /* add to list */ if (isset($_get["add"])) { $item_to_add = "{$_GET["add"]\n"; if "getlist" is defined. Opens the file. prints out the content separated by a \n If "add" is defined. Appends the item to the "todo.txt" file. file_put_contents("todo.txt", $item_to_add, FILE_APPEND); print "Item <$item_to_add> added to server"; todo.txt item1 item2 item3 item4
Multi-purpose PHP code -if "delete" is defined. /* 47 delete item */ if (isset($_get["delete"])) { $item_to_delete = $_GET["delete"]; $content = file("todo.txt"); file_put_contents("todo.txt", ""); for($i=0; $i < count($content); $i++) { /* if item found - don't write it to file */ if (trim($content[$i])!= $item_to_delete) { file_put_contents("todo.txt", $content[$i], FILE_APPEND); print "Item deleted on server\n"; todo.txt?> Message returned item1 to AJAX call. item2 item3 item4 -get "item to delete" from client. -open "todo" file. -delete the contents. - loop through each item in the file. - if the name of the item is the same as the one to be delete, don't write it back to the file. don't copy item that is to be delete todo.txt item1 item2 item4
JS code (several pages) 48 /* onload - set addbutton's function */ window.onload = function() { $("addbutton").onclick = additem; getlistfromserver(); /* calls server to get List */
JS code 49 function getlistfromserver() /* will call todo.php?getlist=true */ { var xmlhttp = new XMLHttpRequest(); /* make AJAX request */ xmlhttp.onreadystatechange = function() { if (this.readystate == 4) { if (this.status == 200) { var items = this.responsetext; /* items is a string with each item */ additemsfromserver(items); /* separated by a \n */ postmessage("items loaded from server"); /* posts a message */.. xmlhttp.open("get", "todo.php?getlist=true", true); xmlhttp.send(); Perform AJAX call to get the contents of the list. PHP will return the items as one big string separated by "\n".
JS code 50 function additemsfromserver(items) { /* items is a string passed with each time in the list separated by a \n */ /* items.split is equivalent to PHP explode("\n", $items) */ var itemarray = items.split("\n"); /* splits string into array */ for(var i=0; i < itemarray.length; i++) /* for each item in the array */ { if (itemarray[i]!= "") { /* make sure items isn't empty */ var newli = document.createelement("li"); /* create new item */ newli.onclick = clickli; /* set its click event */ newli.innerhtml = itemarray[i]; /* add content */ $("myul").appendchild(newli); /* append to myul list */ Break the string into an array of items. Add each item as an <li> element to the DOM tree.
JS code 51 function postmessage(msg) /* msg is a string to be posted */ { $("messagespan").innerhtml = msg; /* Set a timeout to clear this message after 5 */ /* use an anonymous function to clear message after 3 seconds */ settimeout(function () { var messagespan = document.getelementbyid("messagespan"); $("messagespan").innerhtml = "";, 3000); Simple message function that display something in the "messagespan".. and then creates a timer event to delete the contents after 3 seconds.
JS code 52 function clickli() { /* will call todo.php?delete=item_to_delete */ var result = confirm("do you want to delete this item?"); if (result == true) { var item = this.innerhtml; /* item_to_delete */ $("myul").removechild(this); /* remove from HTML using DOM */ var xmlhttp = new XMLHttpRequest(); /* send PHP a message to delete */ xmlhttp.onreadystatechange = function() { If an "li" is clicked, we use a pop-up if (this.readystate == 4) { window to ask if we want to delete if (this.status == 200) { the item. postmessage(this.responsetext); If so, do an AJAX call to delete the item. xmlhttp.open("get", "todo.php?delete=" + item, true); xmlhttp.send();
JS code 53 function additem() { /* will call todo.php?add=item_to_delete */ { if ($(myinput).value!= "") { /* if value is empty do nothing */ var newli = document.createelement("li"); /* create item */ newli.innerhtml = $("myinput").value; /* add content */ newli.onclick = clickli; /* add clickevent */ $("myul").appendchild(newli); /* append new element to DOM tree */ var xmlhttp = new XMLHttpRequest(); /* Create AJAX call */ xmlhttp.onreadystatechange = function() { if (this.readystate == 4) { if (this.status == 200) { If "addbutton" is clicked. postmessage(this.responsetext); /* post Add message a new */ item to the list, call PHP code to add the item. xmlhttp.open("get", "todo.php?add=" + $("myinput").value, true); xmlhttp.send();
Recap 54 Three examples to help see how we can put everything together Example #2 shows how to do "code generation" where we use PHP to modify our JS code Example #2 and #3 show examples using AJAX Most of the social network platforms use this style of asynchronous communication between server and client NOTE: AJAX will not be on the final exam or labtest