Today I want to talk about a change in the design of the Topics application. About a week ago I was looking at changing the front page and wanted a way to list the topics alphabetically.
So I thought that it might be nice to implement the same effect as Dojo’s fisheye for the front page. My idea was to put the fisheye in the front page of Topics, the fisheye would display the letters of the alphabet. So when a user clicked on a letter a list of topics which initialize with that letter would show underneath.
I will try to walk you through the steps I did to get things working. An overview of what I did is:
- Downloaded Dojo + Dijit + DojoX
- Included some of the downloaded scripts and styles.
- Created images for each letter in the alphabet. Placed them in the relative path “/topics/images/”. The image file name had the form letter_<lettter>.png ie. letter_a.png
- Added the html code for the fisheye to display.
- Added event handlers for the fisheye elements to make ajax requests on user clicks.
- Created a jsp that would serve as the Ajax response.
- Created an action that would handle the Ajax request.
The included scripts and files were:
<link rel="stylesheet" href="styles/fisheye.css"> <script type="text/javascript" src="scripts/dojo/dojo.js"></script> <script type="text/javascript" src="scripts/src.js"></script>
The files src.js has the following content:
/*
Copyright (c) 2004-2009, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
dojo.require("dojox.widget.FisheyeList");
dojo.require("dojo.parser");
dojo.addOnLoad(function(){dojo.parser.parse();});
function load_app(id){alert("icon "+id+" was clicked");};
The code to get fisheye showing was the following:
<div class="descr outerbar"> <div dojoType="dojox.widget.FisheyeList" itemWidth="17" itemHeight="35" itemMaxWidth="50" itemMaxHeight="80" orientation="horizontal" effectUnits="1" itemPadding="10" attachEdge="top" labelEdge="center" id="fisheye1" > <s:iterator value="characters" var="ch"> <div dojoType="dojox.widget.FisheyeListItem" id="alpha_<s:property value="ch"/>" label="<s:property value="ch"/>" class="watermarkForAjax" iconSrc="/topics/images/letter_<s:property value="ch"/>.png"> </div> </s:iterator> </div> </div> <div id="ajaxContainer" class="box"> <div id="ajaxContent"></div> </div>
Notice the div container with id “ajaxContainer”. On load the div will be empty. But when the user clicks on one of the letters in the fisheye it will get populated with content.
Next was adding the events to the fisheye elements to make the ajax request and handle the response, after a user clicks on a letter. The code to do this was:
<script type="text/javascript">
dojo.addOnLoad(function() {
dojo.query(".watermarkForAjax").connect("onclick", function(e) {
var node = this;
init(node.id.substr(6));
});
});
var init = function(alpha) {
var contentNode = dojo.byId("ajaxContent");
dojo.xhrGet( {
url : "alpha.html?alpha=" + alpha,
handleAs : "text",
load : function(data, args) {
// fade out the node we're modifying
dojo.fadeOut( {
node : contentNode,
onEnd : function() {
// set the data, fade it back in
contentNode.innerHTML = data;
dojo.fadeIn( {
node : contentNode
}).play();
}
}).play();
},
// if any error occurs, it goes here:
error : function(error, args) {
console.warn("error!", error);
}
});
};
</script>
Now in struts I had an action defined as follows:
<action name="alpha" class="welcomeAction" method="alpha"> <result type="tiles">.alpha</result> </action>
As you will notice I am using tiles, at the end it was a jsp that all it did was iterate over a list:
<div class="descr">
<ul>
<s:iterator value="accountList">
<s:url value="/twitter/%{username}.html" var="urlValue"/>
<li><a href="<s:property value="urlValue" />"><s:property value="%{preffix}" /> (@<s:property value="%{username}" />)</a></li>
</s:iterator>
</ul>
</div>
I think those were the major steps. I am mostly writing this so I don’t forget myself. Because right after I had made the change I decided that I was going to remove it. It was not going to work well with SEO because of the ajax requests. I want the pages in my site indexed by search engines, because they are all public. For internal pages though I might use this concept later.