Grease up the iSchool webpage


Once word gets around that you can handle HttpRequests and can unpack XML, folks like these (do you see Scott Barker over to the left?) will hire you to develop code for their webpages.

This project extends the project "ABC iSchool course web services". Here, the goal is to put an HTML select widget on the iSchool webpage. A student could use this select widget to show courses beginning the letter "a", letter "b" or letter "c".

The challenge would seem to be (1) Targeting an element on the iSchool webpage, (2) Reach out to the the XML file (i.e., aCourses.xml, bCourses.xml, cCourses.xml), (3) Unpack the XML contents, (4) Construct an HTML select widget, (5) Hang it onto the iSchool webpage, and finally, (6) Expropriate some real estate on the iSchool webpage to show the course information.

In short, we're going to grease up the iSchool webpage and make it our own!


The iSchool web page ungreased   cute!




Greased! Select an option to get "A" courses




Greased! Select an option to get "B" courses




Greased! Select an option to get "C" courses







Some developer notes



Since we're going to "grease up" (i.e., mash up) the iSchool web page with Greasemonkey, the information that we're going to place on the iSchool web page can live anywhere (e.g.: we're not limited to the iSchool domain). For this project, our XML source documents are here:




Finding a hook on the iSchool webpage

The iSchool webpage is a handsome page that features a left navigation bar.




The following script targets this left nav bar and puts my name as the last element of this list.




///////////////////////////////////////////////////////////
// Create a new HTML element

var liElement = document.createElement("li");
var textElement = document.createTextNode("Terry");
liElement.appendChild(textElement);  
  
//////////////////////////////////////////////////////////
// Use Xpath to get left nav list elements

var myNodeList;
myNodeList = document.evaluate(
	"//div[@id='nav']/ul[@id='LeftNav']",
	document,
	null,
	XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
	null);

// isolate left nav
var leftNavNode;
for (var i = 0; i < myNodeList.snapshotLength; i++) 
{
	leftNavNode = myNodeList.snapshotItem(i);
}

///////////////////////////////////////////////////////////////
//  Hang the new text node on the left Nav on the iSchool page

leftNavNode.appendChild(liElement);   
    


What does a clickable select widget look like?

<script type="text/javascript">
  function showChoice(inChoice)
  {
  	alert("You just selected " + inChoice);
  }
</script>

...

<select>
  <option value ="volvo" onclick="showChoice('volvo')">Volvo</option>
  <option value ="saab" onclick="showChoice('saab')">Saab</option>
  <option value ="opel" onclick="showChoice('opel')">Opel</option>
  <option value ="audi" onclick="showChoice('audi')">Audi</option>
</select>




Hang a select widget on the iSchool webpage



The script that does this.


///////////////////////////////////////////////////////////////////////
// functions called on user choice of records	

function doARecords()
{
	alert("You want the A records");	
}

function doBRecords()
{
	alert("You want the B records");
}
function doCRecords()
{
	alert("You want the C records");
} 
  
///////////////////////////////////////////////////////////
// Create a new HTML element
var selectElement = document.createElement("select");

	var optionO = document.createElement("option");
	var optionOText = document.createTextNode("Choose one");
	optionO.appendChild(optionOText);
	selectElement.appendChild(optionO);

	var option1 = document.createElement("option");
	var option1ValueAtt = document.createAttribute("value");
	    option1ValueAtt.nodeValue = "A";
	option1.setAttributeNode(option1ValueAtt);
	var option1Text = document.createTextNode("A records");
	option1.appendChild(option1Text);
	option1.addEventListener("click", doARecords, false);
	selectElement.appendChild(option1);

	var option2 = document.createElement("option");
	var option2ValueAtt = document.createAttribute("value");
	     option2ValueAtt.nodeValue = "B";
	option2.setAttributeNode(option2ValueAtt);
	var option2Text = document.createTextNode("B records");
	option2.appendChild(option2Text);
	option2.addEventListener("click", doBRecords, false);
	selectElement.appendChild(option2);
	
	var option3 = document.createElement("option");
	var option3ValueAtt = document.createAttribute("value");
	     option3ValueAtt.nodeValue = "C";
	option3.setAttributeNode(option3ValueAtt);
	var option3Text = document.createTextNode("C records");
	option3.appendChild(option3Text);
	option3.addEventListener("click", doCRecords, false);
	selectElement.appendChild(option3);	
		 
//////////////////////////////////////////////////////////
// Use Xpath to get left nav bar

var myNodeList;
myNodeList = document.evaluate(
	"//div[@id='nav']/ul[@id='LeftNav']",
	document,
	null,
	XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
	null);

// left nav
var leftNavNode;
for (var i = 0; i < myNodeList.snapshotLength; i++) 
{
	leftNavNode = myNodeList.snapshotItem(i);
}

////////////////////////////////////////////////////////////////
// Give the select element a little bit of CSS style

var selectStyle = document.createAttribute("style");
selectStyle.nodeValue = "margin-left: 5px; border: solid thin red";
selectElement.setAttributeNode(selectStyle);

///////////////////////////////////////////////////////////////
//  Hang the new text node on the left Nav on the iSchool page

leftNavNode.appendChild(selectElement);



Use Greasemonkey's HttpRequest function to get XML file



The script that does this


 //////////////////////////////////////////////////////////////////////
 // The HttpRequest for the source files
 
	GM_xmlhttpRequest({
    method: 'GET',
    url: "http://projects.ischool.washington.edu/tabrooks/343INFO/abcISCHOOL/aCourses.xml",
    headers: {
        'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
        'Accept': 'application/atom+xml,application/xml,text/xml',
    },
    onload: function(responseDetails)
	  {
		alert(responseDetails.responseText);
	  }

    });


Replace the big picture with a scrollable DIV



The script that does this:


//////////////////////////////////////////////////////////////
// Target big picture

var imageNodeList;
imageNodeList = document.evaluate(
    "//div[@id='homepageimage']",	
	document,
	null,
	XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
	null);

// the big picture
var bigImageNode;
for (var i = 0; i < imageNodeList.snapshotLength; i++) 
{
	bigImageNode = imageNodeList.snapshotItem(i);
}

///////////////////////////////////////////////////////////////////
// Create scrollable DIV
var tArea = document.createElement("DIV");
	tArea.setAttribute("style", 
	"border: solid 2px #ff0000; background: yellow; +  // string break for pretty formatting
	     padding: 4px; width: 600px; height: 340px; overflow: auto");

	//////////////////////////////////
	//  Put my name in the scrollable DIV just to show some content
	var name = document.createElement("p");
	name.innerHTML = "Terry";
	tArea.appendChild(name);

/////////////////////////////////////////////////////////////////////
// Remove the big picture, which is a style sheet insert
bigImageNode.removeAttribute("style");

/////////////////////////////////////////////////////////////////////
//  Put the scrollable DIV in its place
bigImageNode.appendChild(tArea);



Unpack the XML documents



The script that does this:


    GM_xmlhttpRequest({
    method: 'GET',
    url: "http://projects.ischool.washington.edu/tabrooks/343INFO/abcISCHOOL/aCourses.xml",
    headers: {
        'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
        'Accept': 'application/atom+xml,application/xml,text/xml',
    },
    onload: function(responseDetails)
	  {
				
			////////////////////////////////////
			// Transform string mash page into DOM object
			var mashPage = document.createElement('div');
			mashPage.innerHTML = responseDetails.responseText;

			// Search mash DOM object
			var mashNodeList;
			mashNodeList = document.evaluate(
			"curricula/curriculum",
			mashPage,
			null,
			XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
			null);
		
			alert(mashNodeList.snapshotItem(1).childNodes[5].firstChild.nodeValue + " - " +
			mashNodeList.snapshotItem(1).childNodes[11].firstChild.nodeValue);
		
	  }

    });