XMLHttpRequest
object is an important part of the Ajax
web development technique
title
elements
from retrieved document as list items of an invisible ul
element below (with id="details"
)
<form> <input type="button" value="BBC news" onClick="outputFeeds(0)" /> <input type="button" value="Guardian news" onClick="outputFeeds(1)" /> <input type="button" value="New York Times news" onClick="outputFeeds(2)" /> </form>
outputFeeds
function is defined on the next slide
function outputFeeds(i) { var feed = new Array( "http://feeds.bbci.co.uk/news/rss.xml?edition=uk", "http://feeds.theguardian.com/theguardian/uk/rss", "http://www.nytimes.com/services/xml/rss/nyt/World.xml"); var doc = loadXMLHTTP(feed[i]); var ul = document.getElementById("details"); ul.innerHTML = feedToList(doc); }
loadXMLHTTP
function loads XML from URL into DOM document (next slide)
ul
element for output has id="details"
feedToList
function converts titles to list items (later slide)
function loadXMLHTTP(url) {
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", 'proxy.php?url=' + escape(url), false);
xmlhttp.send(null);
return xmlhttp.responseXML;
}
url
and returns it
false
argument means call is synchronous: interpreter waits for response
before continuing
send
sends request to server; content is null for GET
responseXML
method makes response available as XML
<?php header('Content-type: text/xml; charset=utf-8'); $url = $_GET['url']; echo file_get_contents($url); ?>
header()
is used to send an HTTP header
$_GET['url']
gets value of url
parameter from query string
file_get_contents
returns file contents as a string
function feedToList(doc) { var title; var out = ""; var items = doc.getElementsByTagName("item"); for (var i = 0; i < items.length; i++) { title = items[i].getElementsByTagName("title")[0].firstChild.nodeValue; out = out + "<li>" + title + "</li>"; } return out; }
getElementsByTagName
returns a collection
title
child of an item
, so access 0'th
member of collection
nodeValue
can only be applied to a text node
<form>
<input type="text" id="txtSearch" name="txtSearch"
onkeyup="searchSuggest();" autocomplete="off" />
<div id="search_suggest">
</div>
</form>
id="txtSearch"
searchSuggest()
(next slide)
is called in response to an onkeyup
event
autocomplete="off"
turns off browser default to suggest recently entered data
div
with id="search_suggest"
is where suggestions will appear
var searchReq = getXmlHttpRequestObject(); function searchSuggest() { if (searchReq.readyState == 4 || searchReq.readyState == 0) { var str = escape(document.getElementById('txtSearch').value); searchReq.open("GET", 'searchSuggest.php?search=' + str, true); searchReq.onreadystatechange = handleSearchSuggest; searchReq.send(null); } }
getXmlHttpRequestObject
is similar to our earlier
loadXMLHTTP
function, but just returns an XMLHttpRequest object
id="txtSearch"
open
are now asynchronous
handleSearchSuggest
) when
readyState
changes
readyState
are:
<?php header("Content-Type: application/json; charset=utf-8"); ... $suggestions = array("Ajax","ASP","Javascript","JSP","XML","XPath","XSD","XSLT"); $result = array(); // Make sure that a value was sent. if (isset($_GET['search']) && $_GET['search'] != '') { $search = $_GET['search']; foreach ($suggestions as $suggestion) { // Add each suggestion to the $result array if (strpos($suggestion,$search)===0) $result[] = $suggestion; } echo json_encode($result); } ?>
foreach
allows iteration through array
strpos
returns first position where
second argument is found in first argument, or FALSE
if not found
FALSE==0
is true in PHP, need to use strict comparison
===
to check types are equal too
$search
matches $suggestion
at 0'th position
$suggestion
to $result
array
$result
array as JSON using json_encode
//Called when the AJAX response is returned. function handleSearchSuggest() { if (searchReq.readyState == 4) { var ss = document.getElementById('search_suggest'); ss.innerHTML = ''; var str = JSON.parse(searchReq.responseText); // PTW modified for JSON // For loop to build list of suggestions goes here (next slide) } }
div
element under textbox in form has id="search_suggest"
responseText
since response is text (in JSON format)
JSON.parse()
parses JSON text, returning a JSON type
for
loop is on the next slide
... // Returned suggestions are in array str for(i=0; i < str.length; i++) { //Build our element string. This is cleaner using the DOM, //but IE doesn't support dynamically added attributes. var suggest = '<div onmouseover="javascript:suggestOver(this);" '; suggest += 'onmouseout="javascript:suggestOut(this);" '; suggest += 'onclick="javascript:setSearch(this.innerHTML);" '; suggest += 'class="suggest_link">' + str[i] + '</div>'; ss.innerHTML += suggest; } ...
div
element with
mouseover
,
mouseout
and
onclick
events
suggestOver
,
suggestOut
and
setSearch
are defined on next slide
//Mouse over function function suggestOver(div_value) { div_value.className = 'suggest_link_over'; } //Mouse out function function suggestOut(div_value) { div_value.className = 'suggest_link'; } //Click function function setSearch(value) { document.getElementById('txtSearch').value = value; document.getElementById('search_suggest').innerHTML = ''; }
suggest_link_over
is a CSS class value which highlights the suggestion
suggest_link
unhighlights the suggestion
setSearch()
enters the value in the search box and clears the suggestions
ajax_search.js
and
the CSS file suggest.css
http://www.php.net/
AJAX is covered in Chapter 9 in [Jacobs]. It is also mentioned in Section 7.3.3 of [Tanenbaum].