Skip to content

Latest commit

 

History

History

README.md

Dynamic Web Applications

Francisco Couto, Tiago Guerreiro, and João Guerreiro

AJAX stands for Asynchronous Javascript and XML and, paraphrasing from w3schools "is a developers" dream, because you can:

  • Update a web page without reloading the page
  • Request data from a server - after the page has loaded
  • Receive data from a server - after the page has loaded
  • Send data to a server - in the background"

Suggestions

Start by copying the txt files and the mywebapp.php from a previous module.

Replace the beginning of the mywebapp.php to add the following javascript code:

<html>
<head>
<script>
function showHint(str) {
    if (str.length == 0) { 
        document.getElementById("txtHint").innerHTML = "";
        return;
    } else {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                document.getElementById("txtHint").innerHTML = this.responseText;
            }
        };
        xmlhttp.open("GET", "gethint.php?q=" + str, true);
        xmlhttp.send();
    }
}
</script>
</head>
<body>

    <form action='mywebapp.php' method='get' autocomplete='off'>
        <p>Disease: <input type='text' id="searchDisease" name='disease' onkeyup="showHint(this.value)"/> 
	Suggestions: <span id="txtHint"></span></p>
        <p><input type='submit' /> </p>
    </form>
...

Now create a file gethint.php that generates possible suggestions of diseases matching a given prefix:

<?php
// Array with names
$a = array("Asthma", "Anemia", "Angioma", "Arthritis");

// get the q parameter from URL
$q = $_REQUEST["q"];

$hint = "";

// lookup all hints from array if $q is different from "" 
if ($q !== "") {
    $q = strtolower($q);
    $len=strlen($q);
    foreach($a as $name) {
        if (stristr($q, substr($name, 0, $len))) {
            if ($hint === "") {
                $hint = $name;
            } else {
                $hint .= ", $name";
            }
        }
    }
}

// Output "no suggestion" if no hint was found or output correct values 
echo $hint === "" ? "no suggestion" : $hint;
?>

Now test your web application in the browser by typing in the form and checking the suggestions.

Dynamic photos

Now update your web application so it gets the photos about the disease in a dynamic way.

Add to the mywebapp.php with the following javascript function, that calls itself every 3 seconds (https://www.w3schools.com/jsref/met_win_settimeout.asp).

...
function updatePhotos() {
    str = document.getElementById("searchDisease").value;
    if (str.length == 0) { 
        document.getElementById("latestPhotos").innerHTML = "";
    } else {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                document.getElementById("latestPhotos").innerHTML = this.responseText;
            }
        };
        xmlhttp.open("GET", "getphotos.php?disease=" + str, true);
        xmlhttp.send();
    }
    setTimeout(updatePhotos,3000);
}
</script>
...

Add the onload='updatePhotos()' in the tag body to call the function for the first time (http://www.w3schools.com/jsref/event_onload.asp)

<body onload='updatePhotos()'>

Replace the PHP code that reads and displays the photos by defining the place where the photos will be shown:

echo "<p><span id='latestPhotos'></span></p>"

Create the getphotos.php file with the PHP code removed in the previous step:

<?php
$filename = $_GET['disease']."Photos.txt";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
$photos = explode("\n",$contents);
fclose($handle);

foreach ($photos as $p) {
  echo '<a href="'. $p .'"><img src="'. $p .'" /></a></br>';
}
?>

Now test your web application in the browser and check that the images are shown and removed dynamically, without the need to click the submit button.

Now try to change the photos txt file, for example using the tac tool (type man tac to know more about tac):

cp AsthmaPhotos.txt AsthmaPhotosOriginal.txt 
tac AsthmaPhotosOriginal.txt  > AsthmaPhotos.txt 

Check now in the browser the order of the photos, and return to their original order:

cat AsthmaPhotosOriginal.txt  > AsthmaPhotos.txt

To keep the disease name in the text input after clicking the submit, add the following code inside the input of type text.

value="<?php echo htmlspecialchars($_GET['disease']); ?>"

Using Web Services

The mywebapp.php should not retrieve data directly from the data files or a database, instead it should invoke the RESTful Web Services URIs to access the data resources.

Thus, the gethint.php and getphotos.php should be converted into RESTful Web Services that return a JSON response, as it was done in the previous module.

The mywebapp.php code that reads the articles about a disease from the files should also be replaced to invoke a RESTful Web Service using the xmlhttp.open and parse the JSON result.

To request a JSON response do not forget to set the request header:

...
xmlhttp.open("GET", "disease/" + str + "/photos/", true);
xmlhttp.setRequestHeader('Accept', 'application/json');
xmlhttp.send();
...

Consider that the web service returns the following response (this is just an example):

{"photos":[
  {"link":"https://farm8.staticflickr.com/7834/47246897321_32ddb1b7e8.jpg", "title":"Ventolin Inhaler 100 mcg"},
  {"link":"https://farm8.staticflickr.com/7926/32306113307_ecab9c7bd9.jpg", "title":"Asthma attack girl"},
...
]}

To parse such response you could use the JSON.parse function:

...
var myArr = JSON.parse(this.responseText);
var elm = document.getElementById("latestPhotos");
elm.innerHTML = '';
for (var i = 0; i < myArr.length; i++) {
    myImg = '<a href="'. myArr[i].link .'"><img src="'. myArr[i].link .'" alt="'. myArr[i].title .'" /></a></br>';
    elm.insertAdjacentHTML( 'beforeend', myImg );
}
...

For displaying multiple images, for example you can generate a slideshow or a grid (not mandatory) with them:

More information: https://www.w3schools.com/js/js_json_php.asp

Additional Exercise for Evaluation - Submit by June 3rd

  • (2 points) Complete this script by converting the gethint.php and getphotos.php functions into RESTful Web Services that return a JSON response. You can reuse (and extend) last week's RESTful web service. Note that you should add the URIs related to these two new GET requests and be able to handle such requests.

  • (1.8 points) When presenting the PubMed results (completed in prior scripts), present the rating of each article alongside the respective title. In addition, include two buttons/icons that decrease or increase the rating. Using the RESTful web service implemented in the last script (both to GET the rating and to UPDATE the rating) will be valued.

  • Note that your web application should support at least the following 5 diseases (Alzheimer, Asthma, Cirrhosis, Diabetes, and Tuberculosis). Otherwise (e.g., if you only support Asthma), a small penalty will be applied.

  • (0.2 points) Support the functionality to add a new article, using the POST request added in last week's exercise.

  • All students should submit their files by Wednesday, June 3rd. Submit your relevant files on Moodle - a ZIP file AW-6-XXXXX.ZIP, where 6 means the sixth script, and XXXXX is to be replaced by your student number (for example, AW-6-12345.ZIP).

In your zip file, include a Text File with the link to your web application, as well as the files relevant to this submission.

Additional references