Tabbed Navigation
And no, I am not talking about tabbed tables here. If you already knew that you could have horizontal outlines giving you a tabbed-navigation style instead of the routine, boring left-hand navigation that most LN templates offer, then read no further. For the others:
A bit of history first: outlines were introduced in R5. When I used them for the first time, there was a lot of skepticism from my colleagues (a dinosaur even complained that he couldn’t ‘edit’ them, like he could with plain, ole’ navigators
). But hey, outlines can be used for a whole lot of things, than the conventional templates tell us. Some of the most inventive usages I’ve seen are from Chris at his Interface Matters blog – including a fabulous drag’n'drop feature, and some nifty menus.
Now, let’s take a look at what I was trying to do. At our company, everybody uses the same, old template-style interface, and I have been raring to break the mould. One of those attempts resulted in this:
This is surprisingly easy to do, using a horizontal outline. Just create an outline, and play around with the spacing, its that easy! This is what I used:
Implementing a Domino-Suggest
This is a continuation of the series on implementing an interface similar to Google-Suggest on our typical Domino search pages (The first part in the series dealt with Ajax views).
The basic idea behind Google-Suggest is pretty ingenious; as the user types into the textbox, Google would perform a lookup into its index of search-terms and suggest results. The first suggestion would be automatically populated into the textbox, while the rest of the suggestions appear automatically as a SELECT element under the textbox.
I have borrowed the implemntation of the auto-suggest feature from this awesome article, which explains the underlying concepts better than I ever could. The basic premise behind the implementation is to have two classes: an autosuggest textbox class to handle all user-interaction, and a suggestion-provider class to provide the autosuggest textbox with suggestions.
The autosuggest textbox class would take control over the textbox where the user would type in the search-string. It would impose custom handlers over events such as keyup, keydown, keypress etc. Typically, these custom handlers would track the search-string entered (so far), and pass it onto a requestSuggestions() member-method of the suggestion-provider class. In our case, the suggestion-provider class would basically be the wrapper class around the NotesView class that we discussed earlier.
The auto-suggest dropdown is nothing but an absolutely positioned DIV that is created and populated ‘dynamically’. Part 2 of the article explains this concept as well. With all these concepts in tow, implementing a nifty auto-suggest feature in a Domino database should be a cinch.
Ajax Views
For the uninitiated: Ajax stands for Asynchronous JavaScript and XML. This is the technology that is providing Web applications with rich, desktop-like features; just take a look at Google Suggest and Google Maps, for instance. An Ajax application does away with the standard start-stop-start HTTP mechanism hitherto used, and makes user interaction appear asynchronous. To read more about Ajax, this is a great introductory article.
Now, the conventional mechanism to display a view in Domino is to use the $$ViewTemplate form. Of late, the embedded view has found favor amongst many developers as well. A third way is to build an Ajax view using a JavaScript class (yeah, JavaScript does ‘support’ OOP). This method basically consists of using the ReadViewEntries url-command to build the view.
function NotesView(url)
{
this.xmlDoc = new ActiveXObject(“Microsoft.XMLDOM”);
this.xmlDoc.async = false;
…
this.xmlDoc.load(viewURL + “?ReadViewEntries&count=-1″);
xx = this.xmlDoc.getElementsByTagName(“viewentries”);
c = xx.item(0);
d = c.getAttribute(“toplevelentries”);
this.docCount = d;
this.dbColumn = dbColumn;
}
The usage of the this keyword above indicates that docCount and dbColumn are respectively a member-variable and member-method of the NotesView class, and not mere variables. A simple version of the dbColumn function could look like this:
function dbColumn(colNo)
{
var colEntry = new Array(0);
viewEntries = this.xmlDoc.getElementsByTagName(“viewentry”);
var curCol = 0;
for (i=0;i<viewEntries.length;i++)
{
entryData = viewEntries[i].getElementsByTagName(“entrydata”);
for (k=0;k<entryData.length;k++)
{
curCol = parseInt(entryData[k].getAttribute(“columnnumber”));
if (curCol == colNo)
{
entryText = entryData[k].getElementsByTagName(“text”);
for (j=0;j<entryText.length;j++)
colEntry.push(entryText[j].firstChild.nodeValue);
}
}
}
return colEntry;
}
In this simple version of a dbColumn function, we merely iterate through all the columns until the column# that was passed as a parameter is encountered. Then, all the values in that column are oushed into an array which would form the return value of the function.
With this NotesView class, building a ‘dynamic’ view is no big deal; it is just a matter of collecting all (or just the necessary) columns of the view and displaying it in a well-styled table. I personally use it for categorized views – displaying the categories on the left and the category details using the NotesView class (of course, then the url used by the class would contain a RestrictToCategory parameter as well).
Using nifty ‘Google Suggest’-style search-pages
The new Google Suggest site rocks, I have always thought. Hence while implementing one of those boring search-pages all over again, I thought – why not come up with a stylish auto-suggest interface? The next three articles will be a primer on how to implement this.