This site contains the documentation that is relevant to older WSO2 product versions and offerings.
For the latest WSO2 documentation, visit https://wso2.com/documentation/.
Making your Gadget Visually Appealing
In the first part of this tutorial, we explored the basics gadgets, URL and HTML content types, pulling information from the Web and displaying it. In this section, let's investigate how to process content fetched and present it in a more appealing format.
Processing Fetched HTML with JavaScript
The first step in processing received data is to understand what is in the response and the formation. If you visit the following MarkMail URL: http://markmail.org/browse/org.wso2.carbon-commits and view the source of that page, you will notice that there is a div with the ID browse and this div has the main content of the page.
<div id="browse">
Inside this <div> you will find a table with the monthly svn activity data. So from our gadget, we like to pick this <div> and the table with the data, and use that as the main content as opposed to the whole page.
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="WSO2 Open Source Development Data from MarkMail"> <Require feature="dynamic-height" /> </ModulePrefs> <Content type="html"> <![CDATA[ <a href="http://markmail.org/"><img src="http://markmail.org/images/logo_white.gif" alt="MarkMail"/></a> <div id="contentDiv"></div> <span id="hiddenSpan" style="display:none">Hidden</span> <script type="text/javascript"> function getHtml() { var parameters = {}; parameters[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT; var url = "http://markmail.org/browse/org.wso2.carbon-commits"; gadgets.io.makeRequest(url, processResponse, parameters); }; function processResponse(response) { document.getElementById('hiddenSpan').innerHTML = response.text; document.getElementById('contentDiv').innerHTML = "<table>" + document.getElementById('browse').getElementsByTagName('table')[0].innerHTML + "</table>"; gadgets.window.adjustHeight(); }; gadgets.util.registerOnLoadHandler(getHtml); </script> ]]> </Content> </Module>
This gadget extends the previous sample gadget we discussed in the dynamic height section in part 1 of this tutorial. The key difference here is that, instead of using the response text as it is, we use some logic to pick the table with the content.
Since we get the response as text, in order to use some DOM logic to pick the table, we need to attach the text response data into an element on the current HTML document that the Web browser is aware of. For this, we use the hidden <span> element declared on line 10. Note 'style="display:none;"'. This is why the span is not visible on the gadget.
In line 21, we assign the inner HTML of that hidden <span> element to be the response text from inside the process response callback. Once this assignment is done, we can treat the HTML inside the response element as part of the main HTML document and use JavaScript logic to process it.
In line 23, we locate the <div> with ID browse and pick the table element as follows:
document.getElementById('browse').getElementsByTagName('table')[0].innerHTML
We also wrap this content with a tag as the above logic will strip tag:
"<table>" + document.getElementById('browse').getElementsByTagName('table')[0].innerHTML +"</table>"
This processed content is assigned to be the inner HTML of contentDiv. To make sure we give due credit to MarkMail for the content, in line xx we provide the logo and link to the MarkMail gadget. The rest of the logic of this gadget is the same as the previous gadget sample.
Here is the output of the new gadget:
Although the dates on this gadget are links, they do not work as they were originally relative links to MarkMail site. We now display this as processed data and are treated to be relative to the root of the Gadget Server hosting the gadget. With some simple JavaScript logic, we can point these links back to MarkMail.
Using TEXT vs DOM Content Type when Working with HTML
In the gadget that we discussed, we used the content type request parameter set to TEXT as follows:
parameters[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;
There are four content types: TEXT, DOM, FEED and JASON, defined in the Google Gadget API (http://code.google.com/apis/gadgets/docs/remote-content.html#Content_Types). Using the TEXT content type and setting the text content to inner HTML of a hidden element and them processing it as a part of HTML DOM document seems incorrect, when we have the opportunity to use content type DOM.
parameters[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.DOM;
This is not entirely correct, given that our use case is to fetch HTML from a URL, process that and build the gadget content. DOM content type is more appropriate when we want to deal with XML data fetched from SOAP or REST service endpoints. An example on the use of DOM can be found in Google gadget documentation (http://code.google.com/apis/gadgets/docs/remote-content.html#Fetch_XML). The pitfalls of working with HTML using DOM content type is also discussed on iGoogle developer forum (http://markmail.org/message/fophexdfdakwnitr#query:+page:1+mid:d77dptoyzqenxdtu+state:results).
The main point here is that the DOM returned by makeRequest is not part of the HTML document DOM. It is rather a separate DOM representation of the feted content. Since the fetched content’s DOM is not part of the HTML document's DOM tree, even though the fetched content is HTML, it cannot be easily attached to the gadget’s HTML document.
So when working with HTML, we are better off using TEXT content type and adopt the strategy of processing the response as text and attaching to the HTML document as inner HTML.
Using External JavaScript Libraries
Now that we know how to fetch and process HTML within a gadget, let us see how we can use some external JavaScript library to bring in some visual appeal into a gadget. In this step, we will use a JavaScript library to draw a graph based on the data contained in the HTML table.
There are many table-2-graphs libraries out there. Let’s use the Bluff JavaScript graph library: http://bluff.jcoglan.com/
When you deploy additional resources such as JavaScript files, style sheets and images, you can use the registry-based gadget deployment model supported by WSO2 Gadget Server. Details on how to upload resources to registry can be found under Add New Gadgets in the Gadget Repository section.
The three JavaScript files from Bluff library, required to draw graphs, can be uploaded into the registry inside a collection named "js" relative to the location where the gadget is located in registry. This is sown in the image below.
Note the path and the files highlighted in the above screenshot of the WSO2 Gadget Server’s Registry. Once the libraries are uploaded into the path where the gadget is located, we can refer to the JavaScript files, from within the HTML code of the gadget as follows:
<script type="text/javascript" src="js/js-class.js"></script> <script type="text/javascript" src="js/excanvas.js"></script> <script type="text/javascript" src="js/bluff-min.js"></script>
Following is the source code for the complete gadget. On the left hand side is the gadget source and on your right, the description.
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="WSO2 Open Source Development Data from MarkMail"> <Require feature="dynamic-height" /> </ModulePrefs> <Content type="html"> <![CDATA[ <a href="http://markmail.org/"><img src="http://markmail.org/images/logo_white.gif" alt="MarkMail"/></a> <div id="contentDiv"></div> <span id="hiddenSpan" style="display:none">Hidden</span> <canvas id="graph" width="600" height="625">Graph</canvas> <script type="text/javascript" src="js/js-class.js"></script> <script type="text/javascript" src="js/excanvas.js"></script> <script type="text/javascript" src="js/bluff-min.js"></script> <script type="text/javascript"> function getHtml() { var parameters = {}; parameters[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT; var url = "http://markmail.org/browse/org.wso2.carbon-commits"; gadgets.io.makeRequest(url, processResponse, parameters); }; function processResponse(response) { var textData = response.text; textData = textData.replace(/,/g, ''); textData = textData.replace(/td><a/gi, 'th span="row"><a'); textData = textData.replace(/\/a><\/td/gi, '/a></th'); document.getElementById('hiddenSpan').innerHTML = textData; document.getElementById('contentDiv').innerHTML = "<table id='data'><caption>WSO2 Carbon SVN Commits</caption><thead><tr><th></th><th scope='col'>Commits</th></tr></thead>" + document.getElementById('browse').getElementsByTagName('table')[0].innerHTML + "</table>"; var g = new Bluff.SideBar('graph', '600x625'); g.theme_keynote(); g.tooltips = true; g.data_from_table('data'); g.draw(); document.getElementById('contentDiv').style.display = "none"; gadgets.window.adjustHeight(); }; gadgets.util.registerOnLoadHandler(getHtml); </script> ]]> </Content> </Module>
|
<- Start Module < - Module Preferences <- Require the "dynamic-height" feature used to adjust height <- Start HTML content logic <- Link to MarkMail home page <- Content div where we will have the processed data table <- Hidden span to hold fetched data <- Graph canvas element used to hld the graph <- Third party JavaScript libraries used to draw graphs. These are stored in registry and referenced using relative links <- Start JavaScript Logic getHtml function Set content type to be TEXT; Use MarkMail Carbon commits list archive as URL Make request with processResponse as callback processResponse function Use response text Replace ',' in numbers so that 1,200 become 1200, so that graphs library treat those as numbers Replace td elements with th so that graph library treat them as axis labels rather than data Make the processed text data to be inner HTML of hidden span element Locate the table element in browse div of the received data, then wrap it with table caption and column headings and make that the inner HTML of content div Create a side bar graphs with Bluff library and use canvas element with "graph" ID to draw it Set graph theme Enable tool tips on graph Provide the table with ID "data" as data source of the graph Draw the graph Hide the content div, as that has only a table - we want to show only the graph Adjust the height of the window to show the full graph Call getHtml function as the on load handler. This will trigger the fetiching of data and thus the processReponse callback <- End JavaScript Logic <- End HTML content logic <- End Module
|
It is advisable not to incorporate code comments to the code itself. In case of gadgets, even the comments get downloaded to the browser as content, increasing the download size. It is best to keep comments to a minimum.
Here is the output of this gadget, with the graph in place:
This is the end of our guide on how to make a fully-fledged and visually-appealing Google gadget, fetching HTML from a URL, processing the received HTML, and using JavaScript library to present the data in a visually appealing manner.
Also take a look at how to set preferences and make use of the same gadget to present different data in different formats in tutorial Setting User Preferences.