Displaying and Updating Records - Exercise

Contact Us or call 1-877-932-8228
Displaying and Updating Records - Exercise

Displaying and Updating Records

Duration: 30 to 40 minutes.

In this exercise, you will create a mini-application for displaying and updating employee records. The server-side files are already created and much of the JavaScript is written for you. You will have to finish the Ajax portions of the code.

  1. From the command line, navigate to the directory AjaxBasics/Exercises/.
  2. Type npm start to start the Node.js server.
  3. Note that the code already created for you makes an Ajax call to /EmployeeList. Generated by Node.js, this call returns a list of the employees, as shown below:
    <ul>
    <li id="emp1">Nancy Davolio</li>
    
    <li id="emp2">Andrew Fuller</li>
    <li id="emp3">Janet Leverling</li>
    <li id="emp4">Margaret Peacock</li>
    <li id="emp5">Steven Buchanan</li>
    <li id="emp6">Michael Suyama</li>
    <li id="emp7">Robert King</li>
    <li id="emp8">Laura Callahan</li>
    <li id="emp9">Anne Dodsworth</li>
    </ul>
    Notice the ids of the list items are the employee id from the database prefixed with "emp".
  4. Open AjaxBasics/Exercises/EmployeeAdmin.html for editing. This is where you'll do your work.
    1. In the getEmployeeList() function where the comment is:
      • open an asynchronous XMLHttpRequest using the GET method and the URL passed into the function.
      • When the readystate of the request changes, call the display() function with the appropriate parameters.
      • Send the request.
    2. In the display() function:
      • Set the innerHTML property of output div to the responseText of the returned xmlhttp object.
      • Test your solution to this piece by opening AjaxBasics/Exercises/EmployeeAdmin.html in your browser. You should see a list of the employees. If you do not, check your getEmployeeList() and display() functions.
    3. Finish the getEmployeeForm() function by setting the appropriate content type for submitting form data and sending the request.
    4. In the updateEmployee() function:
      • Write the code leading up to the call to send() method call.
      • When the readystate of the request changes, call the employeeUpdated() function.
  5. Test your solution in a browser by visiting http://localhost:8080/EmployeeAdmin.html

Challenge

In the employeeUpdated() callback function, we currently call getEmployeeList() to update the list of employees. This updates the entire list after each change. It would be better to just update the record that was changed. There is no need to make a call to the database to find out which record it was or how it was changed. The client already has that information. See if you can figure out how to remove this unnecessary Ajax call and use pure client-side JavaScript to update the list. Be careful not to update the list until you are sure that the record has been successfully updated in the database. The only file you will need to change is EmployeeAdmin.html.

Solution:

AjaxBasics/Solutions/EmployeeAdmin.html
---- C O D E   O M I T T E D ----

	function getEmployeeList(url) {
		var xmlhttp = new XMLHttpRequest();
		var output = document.getElementById("EmployeeList");
		output.innerHTML = "<h2>Loading...</h2>";
		xmlhttp.open("GET", url, true);
		xmlhttp.onreadystatechange = function() {
			display(output, xmlhttp);
		}
		xmlhttp.send(null);
	}

	function display(output, xmlhttp) {
		var employees, eid, target, i;
		if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
			output.style.display = "block";
			output.innerHTML = xmlhttp.responseText;

			if (xmlhttp.responseText.indexOf("Failed") == 0) {
				output.className = "Warning";
			} else {
				employees = output.getElementsByTagName("li");
				for (i = 0; i < employees.length; ++i) {
					observeEvent(employees[i], "click", function(e) {
						target = getTarget(e);
						eid = target.id.substring(3);
						getEmployeeForm("EmployeeForm", eid);
					});
				}
			}
		}
	}

	function getEmployeeForm(url, eid) {
		var xmlhttp = new XMLHttpRequest();
		var output = document.getElementById("FormDiv");
		var fields, field, value, i;
		output.innerHTML = "Loading...";
		xmlhttp.open("POST", url, true);
		xmlhttp.onreadystatechange = function() {
			display(output, xmlhttp);
			fields = output.getElementsByTagName("input");
			for (i = 0; i < fields.length; ++i) {
				observeEvent(fields[i], "change", function(e) {
					target = getTarget(e);
					field = target.name;
					value = target.value;
					updateEmployee("EditEmployee", field, value, eid);
				});
			}
		}
		xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
		xmlhttp.send("eid=" + eid);
	}

	function updateEmployee(url, field, value, eid) {
		var xmlhttp = new XMLHttpRequest();
		xmlhttp.open("POST", url, true);
		xmlhttp.onreadystatechange = employeeUpdated;
		xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
		xmlhttp.send("eid=" + eid + "&field=" + field + "&value=" + value);

		function employeeUpdated() {
			if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
				var msg = document.getElementById("MessageDiv");
				if (xmlhttp.responseText.indexOf("Failed") == 0) {
					msg.className = "Warning";
					msg.innerHTML = xmlhttp.responseText;
				} else {
					msg.innerHTML = "Updated!";
					getEmployeeList('EmployeeList');
				}
				fadeElem(msg, 255, 255, 0, 255, 255, 255);
			}
		}
	}
---- C O D E   O M I T T E D ----

Open http://localhost:8080/EmployeeAdmin.html in your browser to view the solution; be sure to start the Node.js server (by typing npm start from the command line) in the AjaxBasics/Solutions/ directory first.

Function getEmployeeList, invoked when the page loads, makes an Ajax call to /EmployeeList and invokes function display. If the Ajax calls is successful, then function display displays the returned list of employees in div#EmployeeList.

Also in function display we iterate over each of the bulleted names, listening for clicks. A click on any of the names results in a call to function getEmployeeForm, passing along the id of the clicked-upon employee.

Function getEmployeeForm, in turn, makes an Ajax request, via the POST method, to /EmployeeForm, displays the returned form, and adds change handlers on each of the fields of the form.

As a result of the handlers added in function getEmployeeForm, a change to any of the employee-form fields invokes function updateEmployee which, in turn, makes a POST Ajax request to /EditEmployee, sending along the id of the employee, field name, and field value. The function displays a success or failure message based on the status of the returned results.

Challenge Solution:

AjaxBasics/Solutions/EmployeeAdmin-challenge.html
---- C O D E   O M I T T E D ----

	function getEmployeeForm(url, eid) {
		var xmlhttp = new XMLHttpRequest();
		var output = document.getElementById("FormDiv");
		var fields, field, value, i, fname, lname;
		output.innerHTML = "Loading...";
		xmlhttp.open("POST", url, true);
		xmlhttp.onreadystatechange = function() {
			display(output, xmlhttp);
			fields = output.getElementsByTagName("input");
			for (i = 0; i < fields.length; ++i) {
				observeEvent(fields[i], "change", function(e) {
					target = getTarget(e);
					field = target.name;
					value = target.value;
					fname = target.form.FirstName.value;
					lname = target.form.LastName.value;
					updateEmployee("EditEmployee", field, value, eid, fname, lname);
				});
			}
		}
		xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
		xmlhttp.send("eid=" + eid);
	}

	function updateEmployee(url, field, value, eid, fname, lname) {
		var xmlhttp = new XMLHttpRequest();
		xmlhttp.open("POST", url, true);
		xmlhttp.onreadystatechange = function() {
			employeeUpdated(eid, fname, lname);
		};
		xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
		xmlhttp.send("eid=" + eid + "&field=" + field + "&value=" + value);

		function employeeUpdated(eid, fname, lname) {
			var employee, msg;
			if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
				msg = document.getElementById("MessageDiv");
				if (xmlhttp.responseText.indexOf("Failed") == 0) {
					msg.className = "Warning";
					msg.innerHTML = xmlhttp.responseText;
				} else {
					msg.innerHTML = "Updated!";
					employee = document.getElementById("emp" + eid);
					employee.innerHTML = fname + ' ' + lname;
				}
				fadeElem(msg, 255, 255, 0, 255, 255, 255);
			}
		}
	}
---- C O D E   O M I T T E D ----

Open http://localhost:8080/EmployeeAdmin-challenge.html in your browser to view the solution.

In function getEmployeeForm, we now keep track of the first and last name (from the fields with ids FirstName and LastName, respectively) of each employee. We pass these values as parameters in the call to updateEmployee when any of the fields is changed.

Function updateEmployee works largely as before but, upon successful update of the employee (i.e. a successful Ajax response code), the function now sets the displayed name of the relevant employee in the bulleted list.

Next