A Fresh Take on Categorised Views

As promised yesterday here's an example of a Flex app that does some basic data reporting on a set of backend documents.

For the sake of demonstration I've invented a Staff Skills Database. Each document records a member of staff and what programming skills they have.

In the Notes client the "person" document look like this:


In reality the form is more likely to be web-based but I want to keep this simple for the sake of the Flex demo.

All very straight forward, no?

The screengrab below is of a standard Notes view showing the staff documents. The first column is categorised by the multi-value Skills field and shows documents with more than one value in more than one category. The last column of the view reports how many people have that skill. Still, all very simple and standard Notes stuff.


This is all very well, but how do we represent this on the web and, more specifically, in Flex.

Categories On The Web

There are various way of representing Notes categorised views on the web. They all seem to try and mimic the Notes view paradigm though and I've never really understood why. The web isn't Notes, so why try and fool users in to thinking it is!?

In Flex the data consumed is, most likely, going to be XML. In XML a document with a multi-value field would be represented like so:

<document id="JHOT-7WBJWG">
        <name>Aaliyah Andrews</name>
                <cat>HTML / DHTML / XML</cat>
                <cat>Java Developer</cat>

Using this data structure it's possible with Flex to "categorise" the documents without having to load the same document over and over again for each category, which seems a silly way of doing it.

Traditionally, if you have 10 categories and 100 documents, which happen to be in all ten categories then you'd have to load 1,000 rows of data.

Why not just load all documents once and process the data client side? That's what I've made Flex do. Here's the example (click to go to the demo):


Let's take a closer look:


The left hand pane is a list of all the skills and includes a count of the number of staff with each. Selecting any one skill filter the grid (view) to only show staff members with those skills.

Much better than a drop-down box to select a category and have it fetch a new set of documents each time, no?

Although I've put the title "By Category" above the list I don't think I'd do that in a real world app. That's just for us. In reality I'd avoid the use of the word category completely.

Other Features

Some other cool features of the demo:

  • Notice you can filter the grid using the search field above it. This is in combination with the skill selection from the left. So if you have a skill selected the search operates on that subset of document.
  • You can "group" the view using the checkbox top-right. This is more normally what we'd call categories.
  • Below the view is a tally of the number of documents currently being shown.
  • Bottom right of the view is a button to copy the currently displayed documents to the clipboard in CSV format.

It's worth looking at the XML consumed by the Flex app. Notice that almost everything is controlled from there -- what columns to add to the view and in what order, which of the columns can be "grouped" and which are to highlight matches from the search field. The XML also defines the whole set of categories/skills as well as storing all of the documents for the demo. All this in one hit!


Hopefully, once fully loaded, you'll be amazed at how quick the filtering works. Both when selecting a skill and/or using the search field. That's because it's not going back to the server each time.

To be able to avoid a server round-trip each time you need to be confident that the dataset is never going to grow to the point where it's not practical to load it all in one go. In this example we're loading 2500 staff members and the load is ~600kb.

If your dataset is likely to grow without bounds then the approach falters a little. It can still work, but would need to go the server each time you select a category or use the search field.


The concept of the staff skills might be a little bogus, but hopefully it gets the idea across? There are always different ways of doing something that has always been done the same way in the past.

The code for the Flex app and Notes database is coming tomorrow/later on, along with a bit of a challenge for any XPage lovers.

Update: Download

You can download the Notes database here. The Flex source is in the Zip files in the File Resources section.


  1. What? Only 3 people know Lotus Domino... and they're NOT in the IT Dept. :)

    OK, despite some obviously dodgy data, I really like this flex stuff. It's something I've been meaning to get involved with for a while now. Whilst XPages is obviously a good addition to the Domino playground, I think Flex has far more commercial appeal. What you're doing here is blazing a trail for all of us who come behind to pick up. Same as you've been doing for years. Keep it up.

    • avatar
    • Jake Howlett
    • Wed 30 Sep 2009 05:38 AM

    That's probably realistic data Dragon ;-)

    Glad you like it. I was going to say that this is just scratching the surface. It's not exactly pushing the boundaries of Flex. Just something I knocked up fairly quickly. Going back to what I was saying yesterday, it took a lot less time to do this in Flex than it would in DHTML.

  2. Very Nice! Can't wait to see the code.

    • avatar
    • Aaron Hardin
    • Wed 30 Sep 2009 02:25 PM

    Curt - You can view the XML here


    Great article. Loving Flex and I don't even have a project using it yet. But love learning it off of Adobe's site and here, but really seeing practical application HERE!!!

    Thanks brother.


    • avatar
    • Heba
    • Mon 2 Nov 2009 09:05 PM

    Hi Jake,

    This looks like a terrific tool. I'm trying to implement in one of my applications. Are the SWF files dynamic so that I can apply to any view or does the it need to be recompiled for each view needing this functionality.



      • avatar
      • Jake Howlett
      • Tue 3 Nov 2009 02:50 AM

      As it stands you would need to recompile the SWF from Flex Builder if you wanted to change the view as the URL to the XML of the view is hard-coded. You could change it so that you pass the view's name as a URL parameter or in the "flashVars" though.

      Show the rest of this thread

    • avatar
    • Heba
    • Tue 17 Nov 2009 07:53 AM

    Hi Jake,

    I was trying to implement a date range filter as well and am having a little trouble.

    I was able to get it to work as long as one of the other criteria (category or filter view) is selected but using the date range alone doesn't seem to do anything.

    Do you have any suggestions? I can provide all the mxml code if needed.

    Thanks much,


    private function handleXML(event:ResultEvent):void{

    categories = new XMLList(event.result.config.categories.category);

    departments = new XMLList(event.result.config.departments.dept);

    documents = new XMLListCollection(event.result.documents.document);

    searchable = new XMLList(event.result.documents);

    total = documents.length;

    documents.filterFunction = function(item:XML):Boolean {

    return (

    filter.text.length == 0 && cbCategory.selectedIndex == 0



    filter.text.length > 0 &&

    ( item.trans.toLowerCase().indexOf(filter.text.toLowerCase()) != -1 )||

    ( item.@id.toLowerCase().indexOf(filter.text.toLowerCase()) != -1 )



    (cbCategory.selectedIndex==0 ||

    (cbCategory.selectedIndex > 0 &&

    (!cbCategory.allowMultipleSelection && XMLList(item.cats.(descendants("cat").contains(cbCategory.selectedItem[0].toString()))).length()>0 )

    || (cbCategory.allowMultipleSelection && XMLList(item.cats.(matchArray(descendants("cat"), cbCategory.selectedItems.join().split(",")))).length()>0 ))



    (dateStart.selectedDate == null

    || dateStart.selectedDate <= DateField.stringToDate(item.date,'MM-DD-YYYY'))

    && (dateEnd.selectedDate == null

    || dateEnd.selectedDate >= DateField.stringToDate(item.date,'MM-DD-YYYY'))


    return result;



    <mx:ApplicationControlBar width="100%">

    <mx:Label text="Show from"/>

    <mx:DateField id="dateStart" editable="true" formatString="MM/DD/YYYY" change="dateFilter(event)" />

    <mx:Label text="to"/>

    <mx:DateField id="dateEnd" editable="true" formatString="MM/DD/YYYY" change="filterGrid(event)" />


      • avatar
      • Heba
      • Thu 19 Nov 2009 02:11 PM

      Hi Jake,

      Got it working. Updated this line:

      (filter.text.length == 0 && cbCategory.selectedIndex == 0 && dateStart.selectedDate == null && dateEnd.selectedDate == null)

      Thanks so much for this wonderful tool!


    • avatar
    • Heba
    • Wed 2 Dec 2009 12:08 PM

    Hi Jake,

    I got this working great, until of course I turned on SSL. Then I get an http error. I've done some research but with no success.

    Do you have any suggestions that may lead me in the right direction?



      • avatar
      • Jake Howlett
      • Wed 2 Dec 2009 02:27 PM

      No reason it shouldn't work with SSL. What's the error?

Your Comments


About This Page

Written by Jake Howlett on Wed 30 Sep 2009

Share This Page

# ( ) '


The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social

About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »

More Content