Preloading and DOM DOM Table Object and JSON File upload, HTML5 File Web workers web sockets and node.js jQuery, AngularJS and other libraries CMS systems Image rollover and pre-loading

• An image rollover should use pre-loaded images, since viewing images that has to be downloaded take time

Rollover with mouse events

Move your mouse over the image to see the result

Animation in the DOM

• You can use JavaScript to create animations and effects • DOM elements (,

or any other HTML element) can be moved around the page • The timer functions are used to create many effects • Together with certain style.* attributes as position • Other positions than relative are: static (default), absolute, fixed, inherit

// This function calls function after duration milliseconds from now. var timeoutVar = setTimeout(function, duration); // This function calls function repeatedly every duration milliseconds. var timeoutVar = setInterval(function, duration); // This function clears any timer set by the functions above. clearTimeout(timeoutVar); // declare that the object have a relative position myObj.style.position= 'relative'; // Set distance from left edge of the screen. myObject.style.left = distance in pixels or points; animate.html // Set distance from top edge of the screen. myObject.style.top = distance in pixels or points; Finding elements in the DOM

• To access a node in the document tree, we can use parents, children and siblings • But usually we select elements by Id, Name or Type (Tag) EM is a sibling My DOM to SPAN

Select elements by CSS class or Selector

• The DOM in HTML5 also defines the CSS method: getElementsByClassName() that allows us to select sets of document elements based on the identifiers in their class attribute // Find all elements that have "warning" in their class attribute var warnings = document.getElementsByClassName("warning"); • A CSS selector are the identifiers we can use in CSS – #nav (id), div (element), .warning (class) and so on • To select elements with CSS Selector we use the Document methods querySelectorAll() (returns all matching elements) or querySelector() (returns only the first matching element) // Find all elements in the document that match the selector string // and return a node list that represent all these elements var headings = document.querySelectorAll("h1,h2,h3,h4,h5,h6"); // All

elements plus the element with id="log" var elements = document.querySelectorAll("div,#log"); // All radio buttons in the form with id "shipping" var rbuttons = document.querySelectorAll('#shipping input[type="radio"]'); // All radio buttons with name "method" in form with id "shipping" document.querySelectorAll('#shipping input[type="radio"][name="method"]'); Modify the DOM

• The first step is to - create the node (element) you wish to append and fill it with some node text. The next is to find where you wish to append it within the document. The final step is to actually do the appending (In many cases the property innerHTML can be used). • InsertBefore, replaceChild and many other operations are available

// Appending a text node to #myDIV in the document var txtNode = document.createTextNode("This text was added to the DIV."); document.getElementById('myDivId').appendChild(txtNode); // To create an element var newElement = document.createElement("li"); // To create a text node var txtNode = document.createTextNode("Hello. This is a new node."); // To append the above text node to the element newElement.appendChild(txtNode); // do the actual appending to the document document.getElementById('uList').appendChild(newElement); // To create a new element with attributes var linkElement = document.createElement('a'); add-element.html linkElement.setAttribute('href', 'mypage.html'); linkElement.setAttribute('name', 'myanchor'); var newtext = document.createTextNode("This is a new link element."); linkElement.appendChild(newtext); document.getElementById('myDivId').appendChild(linkElement); XML and the DOM

• We can display and update XML data with the DOM functions - before we show our markup on a page

add-xml-element.html DOM Table Object with JSON 1

• The following example shows how to create a PHP JSON response from an search request

Artistame($Artistame); if(!empty($Title)) $this->Title($Title); if(!empty($Date)) $this->Date($Date); } } //get the query parameter from URL $query = $_GET["query"]; DOM Table Object with JSON 2

• PHP JSON AJAX response cont. try{ if($DBH == null) $DBH = new PDO($dsn); searchjson.php } catch (PDOException $e){ echo 'PDOException: ', $e->getMessage(); die(); }

$sql = "SELECT artistname, title, date FROM artists, cds WHERE artists.artistid"; $sql .= " = cds.artistid and artists.artistname LIKE :query"; $STH = $DBH->prepare($sql); $STH->execute(array(':query' => '%'.$query.'%')); $STH->setFetchMode(PDO::FETCH_CLASS, 'ArtCds'); $notvisited = TRUE; $artcdarr = array();

while ($artcd = $STH->fetch()){ $artcdarr[] = $artcd; // put ArtCd object in array $notvisited = FALSE; } $DBH = null;

if ($notvisited) $response = "No artist found with name: " . $query; else $response = json_encode($artcdarr); // serialize the objects

echo $response; //output the response ?> DOM Table Object with JSON 3

• Handling the PHP JSON response with JavaScript

Search for an artists CDs searchjson.html

Type an artist name (can be partial) in the input field below:

Artist Name:

Modify the DOM with JSON • Handling the PHP JSON response with JavaScript alternative solution function handleXMLHttpresponseNode(json) { var jsonData = JSON.parse(json); var table = document.getElementById("myTable"); table.style.border = "2px solid"; table.style.width = "500px"; //build table header searchjson.html var row = document.createElement("tr"); var thda = Array(document.createElement("th"), document.createElement("th"), document.createElement("th")); thda[0].appendChild(document.createTextNode("ArtistName")); thda[0].style.border = "2px solid"; thda[1].appendChild(document.createTextNode("Title")); thda[1].style.border = "2px solid"; thda[2].appendChild(document.createTextNode("Date")); thda[2].style.border = "2px solid"; for (i = 0; i < 3; i++) { row.appendChild(thda[i]); } table.appendChild(row); //build table for (var artistcd in jsonData) { row = document.createElement("tr"); thda = Array(document.createElement("td"), document.createElement("td"), document.createElement("td")); thda[0].appendChild(document.createTextNode(jsonData[artistcd].ArtistName)); thda[0].style.border = "2px solid"; thda[1].appendChild(document.createTextNode(jsonData[artistcd].Title)); thda[1].style.border = "2px solid"; thda[2].appendChild(document.createTextNode(jsonData[artistcd].Date)); thda[2].style.border = "2px solid"; for (i = 0; i < 3; i++) { row.appendChild(thda[i]); } table.appendChild(row); } } Upload a file or files with form • Single file? Remove attribute [] in name and multiple, foreach in PHP must be removed as welll • In Linux/Unix you use single slash (/) instead • Does not work well with big files
fileupload.html

$error) { if ($error == UPLOAD_ERR_OK) { $tmp_name = $_FILES["filesToUpload"]["tmp_name"][$key]; $name = $_FILES["filesToUpload"]["name"][$key];

if(move_uploaded_file($tmp_name, "$uploads_dir\\$name")) echo "The file: ". $name . " has been uploaded
"; else echo "There was an error uploading the file(s), please try again!"; } } uploads.php ?> http://www.thebuzzmedia.com/html5-drag-and-drop-and-file-api-tutorial/

fileapi.html HTML5 DnD and File API

• (DnD API) Starts with the drop event when the user releases the mouse and the mouse-up event occurs. • (DnD API) Get the DataTransfer object from the drop event • (File API) Call DataTransfer.files to get a FileList, representing the list of files that were dropped. • (File API) Iterate over all the individual File instances and use a FileReader object to read their content. • (File API) Using the FileReader.readAsDataURL(file) call, every time a file is completely read, a new “data URL” (RFC 2397) formatted object is created and an event wrapping it is fired to the onload handler on the FileReader object. – The “data URL” object is Base64-encoded binary data, with a spec-defined header sequence of chars. Browsers understand them. • (File API) Now that we have the “data URL” object from the event, we can do cool things with it like replace the src attribute of an tag to immediately show the value on-screen OR upload the Base64-encoded portion of the data to a server to process as binary data. HTML5 File API with AJAX • Currently only works with Firefox, Chrome and Safari? • Asynchronous file uploads is a popular feature in modern AJAX web-applications – However standard XHR (XmlHttpRequest) does not have capabilities to process or send files selected with "file dialog" (input type="file") – Web developers have to use non-standard ways to solve it • With the level 2 specification of XHR, the HTML5 FileReader, the File APIs and the DataTransfer object (Drag and Drop) this is solved – In XHR2 the send method accepts a file object and also supports progress event • What this means is that we can drag files from our desktop and drop them onto our web applications where we can use JavaScript to read in their data or pass them off to be uploaded • http://www.profilepicture.co.uk/ajax-file-upload- -level-2/ fileapi-upload.html PHP receiving the XHR2 file

if ($contentLength < 1) throw new Exception('No file uploaded!');

file_put_contents($path . $fileName, file_get_contents("php://input")); return true; } catch(Exception $e){ file_put_contents($path . $fileName . "-error.txt", $e->getMessage()); } ?> Web Workers

• JavaScript is single-threaded - a browser will never run two event handlers at the same time for example • Concurrent updates to application state are not possible, and client-side programmers do not need to think about concurrent programming • This is the reason that Ajax APIs are always asynchronous • The Web Workers specification defines effectively parallel threads of execution • Web workers live in a self-contained execution environment, with no access to the Window or Document object and can communicate with the main thread only through asynchronous message passing • Creating a new worker is not a heavyweight operation like opening a new browser window, but workers are not flyweight threads either, and it does not make sense to create new workers to perform trivial operations Worker objects

/* To create a new worker, use the Worker() constructor, passing a URL that specifies the JavaScript code that the worker is to run: */ var worker = new Worker("utils/loader.js");

/* Once you have a Worker object, you can send data to it with postMessage(). The value you pass to postMessage() will be cloned and the resulting copy will be delivered to the worker via a message event: */ worker.postMessage("file.txt");

/* You can receive messages from a worker by listening for message events on the Worker object when the worker use its postMessage function: */ worker.onmessage = function(e) { var message = e.data; // Get message from event console.log("Worker message contents: " + message); // Do something with it }

/* If a worker throws an exception and does not catch or handle it itself, that exception propagates as an event that you can listen for: */ worker.onerror = function(e) { // Log the error message, including worker filename and line number console.log("Error at " + e.filename + ":" + e.lineno + ": " + e.message); } Worker example


Web Worker results:

(not started yet)

} } Server-side JavaScript

• Node.js is a fast C++-based JavaScript interpreter with bindings to the low-level Unix/Windows APIs for working with processes, files, network sockets, etc., and also to HTTP client and server APIs • Except for some specially named synchronous methods, Node’s bindings are all asynchronous, and by default Node programs never block, which means that they typically scale well and handle high loads effectively • Because the APIs are asynchronous, Node relies on event handlers, which are often implemented using nested functions and closures (a sub function value) • Docs and examples: https://nodejs.org Web Sockets

• The WebSocket API allows client-side code to create secure long-lived bidirectional TCP socket-type connections to servers that support the WebSocket protocol /* First, create a socket with the Web Socket() constructor: */ var socket = new WebSocket("ws://ws.example.com:1234/resource"); /* The argument to the WebSocket() constructor is a URL that uses the ws:// protocol (or wss:// for a secure connection. The URL specifies the host to connect to, and may also specify a port ( use the same default ports as HTTP and HTTPS) and a path or Resource. Once you have created a socket, you generally register event handlers on it:*/ socket.onopen = function(e) { /* The socket is now connected. */ }; socket.onclose = function(e) { /* The socket closed. */ }; socket.onerror = function(e) { /* Something went wrong! */ }; socket.onmessage = function(e) { var message = e.data; /* The server sent us a message. */ }; /* In order to send data to the server over the socket, you call the send() method of the socket:*/ socket.send("Hello, server!"); /* The WebSocket API supports only textual messages, and sends them as UTF-8 encoded Strings. But the WebSocket protocol includes support for binary messages. When your code is done communicating with the server, you can close a WebSocket by calling its close() method */ jQuery 1

• Many programmers find it easier to write web applications using a JavaScript framework or utility library to simplify common tasks and hide the differences between browsers • Because the jQuery library has become so widely used, web developers should be familiar with it. Even if you don’t use it in your own code you are likely to encounter it in code written by others What jQuery does well: Why It Is Successful: • Simplified AJAX • Well Designed • DOM Manipulation • Easy to extend with • Event Management plugins • Animations • Great Documentation • Normalizes Browser • Large jQuery Community Differences • Cross-browser jQuery 2 • The jQuery library is focused on queries • A typical query uses a CSS selector to identify a set of document elements and returns an object that represents those elements • This returned object provides many useful methods for operating on the matching elements as a group • Whenever possible, these methods return the object on which they are invoked, which allows a succinct method chaining idiom to be used • The jQuery library defines a single global function named jQuery() or the shortcut $() • The value returned by this function represents a set of zero or more DOM elements and is known as a jQuery object • There are 4 ways to use $() – Pass a CSS selector (a string) to $() – Pass it an Element or Document or Window object

– Pass it a string of HTML text jQuery(function() { /* Invoked when the – document has loaded */ Pass a function to it // All jQuery code goes here }); jQuery samples

/* Here is how we ask for the set of all

elements in a document: */ var divs = $("div"); /* Below is code that finds, highlights, and quickly displays all hidden

elements that have a class of “details”: */ $("p.details").css("background-color", "yellow").show("fast"); /* The code below finds all elements in the document that have the CSS class “clicktohide” and registers an event handler on each one. That event handler is invoked when the user clicks on the element and makes the element slowly “slide up” and disappear: */ $(".clicktohide").click(function() { $(this).slideUp("slow"); });

jQuery Demo

Go to jQuery.com

6-10b.html jQuery mobile

• Mobile framework using jQuery • Cross-browser, cross-platform – Most mobile web browsers are supported • Create web apps that feel as close to native as possible • Markup driven, minimal code required to get up and running • Focused on progressive enhancement, graceful degradation • Tutorial in Docs section at: http://jquerymobile.com or download the jquery.mobile-1.0.1.zip (JavaScript, CSS, and images) file cars-mobile.html AngularJS

• AngularJS (or Angular) is a complete JavaScript-based open- source front-end framework – It is mainly maintained by Google and by a community of individuals and corporations to address many of the challenges encountered in developing single-page applications (SPAs) • It aims to simplify both the development and the testing of SPAs for client-side MVC and MVVM architectures – The AngularJS framework works by first reading the HTML page, which has embedded into it additional custom tag attributes – Angular interprets those attributes as directives to bind input or output parts of the page to a model that is represented by standard JavaScript variables – The values of those JavaScript variables can be manually set within the code, or retrieved from static or dynamic JSON resources • https://en.wikipedia.org/wiki/AngularJS • http://www.w3schools.com/angular/ Other libraries, utilities etc. • 50 jQuery Tools for Awesome Websites – http://www.problogdesign.com/resources/50-jquery-tools-for-awesome- websites/ • Download ready-made JS programs at sites as – http://www.hotscripts.com/ or http://dynamicdrive.com/ • HTML5 enabling script that enables all new elements for old IE – http://remysharp.com/2009/01/07/html5-enabling-script/ • Bootstrap is a free and open-source front-end for designing websites and web applications. It contains HTML- and CSS-based design templates for typography, forms, buttons, navigation and other interface components, as well as optional JavaScript extensions. Unlike many web frameworks, it concerns itself with front-end development only – http://getbootstrap.com/javascript/ • Modernizr is an open-source JavaScript library that helps you build the next generation of HTML5 and CSS3-powered websites – http://www.modernizr.com/ • Indexed Database API – http://en.wikipedia.org/wiki/Indexed_Database_API – http://hacks.mozilla.org/2010/06/comparing-indexeddb-and-webdatabase/ Content Management Systems (CMS)

• The most popular CMS:s according to web admins are Wordpress, Drupal and Joomla • Which one to select depends on the purpouse with your website • Wordpress may be better for a simple website • Joomla is not so customizable • Drupal is more diffucult to install and manage but may be better for a more complex website