Searching Domino Simplified

Jake Howlett, 24 January 2005

Category: Miscellaneous; Keywords: search

Getting on for four years ago I wrote an article called Creating a simple search box. The search box itself might have been simple, but the creating it certainly wasn't. Although the article proved to be hugely popular, I have never really been happy with the approach and I've finally redeveloped it.

Over the past few days I've developed a new approach that is somewhat simpler and a whole lot easier to implement. Not only is it easier to develop but it's also better from a web developement stance. My original solution used JavaScrpt. Not only to validate the search query but also to redirect the browser to the actual search page. What if a user without JavaScript wants to search? They can't!

This article describes the principles behind creating a search feature in a Domino database that uses nothing but @Functions. The resulting search is a lot less error-prone than when we rely so heavily on JavaScript.

There's not going to be a lot of code in this article. In fact there's not a lot of code in the database. What the article aims to do is describe how it all works in principle. Some of the methods used are a little obscure and may not be immediately obvious when looking at the source of the attached demo database.

If you feel comfortable hacking the database for yourself then here it is (there's also an online demo if you want to see what I'm talking about). If you want your hand held, read on and I'll try and explain it the best I can. It might be best if you have the database open in Domino Designer so I can talk you through it, piece by piece.

Searching With Domino:

With Domino, adding a site-wide search field has never really been simple. Domino makes things a little tricky for us. Mainly because it insists on creating its own <form> elements. Even when they aren't really needed. This makes it tricky for us because we need to add our own form, so the search field has somewhere to live. The problem is that forms can't be nested. The search field should really live in its own form and this form has to be outside of Domino's form.

Until now I have always used the approach I described all those years ago. The search box we added was just another field on Domino's form. Instead of creating a separate form we included it in the default one. Then all we needed to do was over-write the form's action using some JavaScript. Instead of the form being submitted the page was redirected to a URL that performed the search. If you're interested in the detail of how then take a look at the original article.

What's the problem:

Let's say we add a search field to our form. If you're in read mode and it's the only field on the form, the browser will submit the form if you press enter after typing in your query. Because Domino hasn't given the form any attributes it uses GET to send the fields via the URL, like so:

/store.nsf/0/DOCID?query=search term

Notes can't understand this and throws an error. In our original solution we got round this by preventing the form from ever submitting. This used JavaScript though and so wasn't ideal.

So, we abondon this and try to add our own form. It's best to do this at the bottom of the form, after all other fields. Close Domino's default form with a </form> and create our own. The form tag would look something like this:

<form action="/store.nsf/srch" method="get">

The problem with this is that the URL you end up with is like this:

/store.nsf/srch?query=search term

This also results in an error as Domino needs to recieve the ?SearchView command as well. So, we change the action parameter to "/store.nsf/srch?SearchView", but the browser strips everything after the ? and creates its own query string, based on the fields in the form.

One way round this is to add a blank hidde n field called "SearchView" to the beginning of the form. The resulting URL looks like this and works.

/sto re.nsf/srch?SearchView=&query=search term

It's a hack of sorts, but it works. The result is a simple form that creates a URL with which we can search Notes Views. No JavaScript!

However, it's not perfect. Without the JavaScript we have no way of validating the query field before submitting. There must be a better way.

What's the Solution:

The answer is simple. Switch the form method from GET to POST. Instead of trying to create a URL that Domino is happy with we send all the field values to the server and process them there.

At first I tried doing this with an Agent but that got too complicated for what only needs to be a simple solution. All we really need for this is a simple Form. Here we can take the value of the search field, validate it, build a search URL from it and redirect the browser there. All of this can be done really easily in a computed field called "$$Return". Yep, that simple.

So, how do we POST the data to this Form and get the $$Return field to compute? By making the action parameter of the Form equal to something like this:

/store.nsf/search?CreateDocument

This URL command sends all the field values to the Form, which it then saves as a document. Becuase it's saved, the $$Return field kicks in and redirects the browser. Well, I say saved, but it's not actually. We don't need the fields stored so another field called "SaveOptions" is added. It's value is "0" and so Notes knows not to bother saving the document. What we end up with is a simple Form that acts as a gateway to the search.

The real beauty of this is that the form is simply the database's $$SearchTemplate Form. It couldn't get any simpler. No extra design elements needed. We just give this Form an alias of "search" and we can make it the target of our search form.

To see how the $$Return field works take a look at its value on the search template form. Basically it checks for it being blank (in which case it returns the user to the search template form) and then builds the required search URL.

Something to Note:

Positioning the new search form at the bottom of the Form means it's out of the way and not where we need it. To get it where we need it in this case I've used some absolute CSS positioning. Obviously this isn't possible in all page designs and so isn't perfect. In this case you can move the search form to wherever you like and end Domino's form even earlier. This is ok when you're in read mode and there won't be any other fields and you don't need to worry about affecting the other forms on the page. In edit mode it will cause problems. Maybe here you can hide the search form?

Taking it Further:

In my quest to keep this as simple as possible I think I might have over-simplified it a little. Simple is normally best but it's sometimes good to get carried away and throw caution to the wind.

In this case you might want to do something when users forget to enter a search term. Without JavaScript we can't warn them until the server returns the next page. Maybe the $$Return field could tag a parameter to the end of the URL that meant a message was displayed. Is it worth it though? What kind of idiot presses "Go" without typing in any value?

Maybe we could get really carried away and create Notes search strings that mimic Google search syntax. See Laurens' response to this blog entry for a starting block.

Summary:

Searching with Notes is easy. Searching with Domino is slightly more tricky. Until now I've always found it a little cludgy. Now I'm happy with what is a really simple, yet powerful, approach.

Hope you all find use for it. Even if you don't need a search box you could probably use the principles elsewhere. Say you have a simple form that finds a local store based on the address entered. We could do it using this approach. The possibilities are almos t endles s.

Further Reading:

  1. Creating Inline Documents
  2. Pageing Search Results