Searching Domino Simplified
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:
But.... ?
What's wrong with making the form method post and the action something like: "/database.nsf/search?SearchView&start=1&count=20"
You have a field called 'Query' and even fields like 'SearchWv', 'UseSearchFuzzy' in the search form.
That's the way I've been doing it for years now.
Reply
Re: But.... ?
Now that really is simple. Very nice.
There's nothing wrong with that at all. It's just that it means we can't use the $$Return *computed* field to do anything fancy. Fancy stuff like turning Google-style searches in to Notes-friendly ones. Or dealing with blank searches etc.
Reply
Show the rest of this thread
1998 Article from Notes.net does same
Hi Jake,
I started using this search technique for our company intranet some time ago. I got the idea from reading a Notes.net article from 1998: http://www-128.ibm.com/developerworks/lotus/library/ls-Combining_forms_and_views _Part1/index.html
I agree-- a technique that doesn't require JavaScript is better than one that does.
Great site, Jake-- still with you after many years (if mostly lurking).
-Seth
Reply
I know, but...
While writing this, at the back of my mind, I was aware that it was nothing new. What I didn't know was if it was documented elsewhere or not.
You can guarantee that there are people out there who didn't know of that article (me for one). No matter how many times you reproduce something it will always reach a new audience.
Hopefully my article brings something new to fray as well. Like the use of CSS and a separate form that can work while the form on which it lives is in edit mode.
The trouble with that IBM download, as well as others I've seen, is that they are not very "real world".
Download that accompanying database from the sandbox and have a play with it. Notice how there's only ever one <form>. Note the hard-coded file names!
So, yes, I'm covering old ground. But, I'm doing it in an accessible way that you guys can actually go away and use in a "real world" situation.
Thanks for bursting my bubble ;-)
Reply
Show the rest of this thread
Export the search result view to Excel
Hello, I am very new in lotus..
I would like to ask after the system return a search result view, how can I export this view to Excel ? Can I add any button the result view ?
On the other hand, I would like to know how can I put back the searching criteria to the search result view to be the report header ?
Thanks a lot ~~~~
Reply
Re: Export the search result view to Excel
Hi Anna,
Have you seen this technique? http://codestore.net/store.nsf/unid/BLOG-20040309
You'd have to change the second line to be the search URL. Should be "doable".
Also read the "perfect view" article:
http://codestore.net/store.nsf/unid/EPSD-5VBS6Y
Jake
Reply
Search
Does anybody know how exclude $UpdatedBy field or modify its value during the Domain Search process. I'm getting huge document listing in search results based on $UpdatedBy field using name criteria, which are irrelevent. Does anybody knows the solution for this. Please help. Appreciated.
Reply
Re: Search
You could add " AND NOT [$UpdatedBy]=query" to the end of the URL?
Reply
Show the rest of this thread
Re: Search
I want to only exclude $UpdatedBy field values. This url search string excludes $UpdatedBy field values and, if the form has the field with same value also excluded.
eg. In Employee Profile database, Form has FullName field with value [Dinesh Sanil] As a administrator, if i update any other employees profile, domino stores [Dinesh Sanil] in $UpdatedBy. When I search [Sanil], search ignores even my profile document.
Tried all possible methods, let me know if there is any way to ignore only $UpdateBy values.
Thanks DS
Reply
Show the rest of this thread
Wrong searchbar postion in Opera
Jake,
I noticed that your online demo positions the searchbox at the bottom of the screen in Opera due to the </form> tag.
Is this a bug in Opera ?
Thanks /Thomas
Reply
Re: Wrong searchbar postion in Opera
Thanks Thomas. I fixed it in the online demo (but not the download).
You're right. It's the </form> which is incorrectly nested. I.e. it ends in a div other than the one it starts in. Opera don't like that for some reason or other...
Reply
Related to ur modified searchbox code
Hello Jake, Thanx for giving such a wonderful coding in ur site.I'm new to Lotus Notes only 2 months...Well I used ur searchbox code which was earlier published by you on ur site .I saw the latest one also but that bounced.I'm not getting anything from that code.I don't have any idea about the ViewTemplates n ...I read then on Help but still I'm not getting anything.I used ur earlier searchcode n that is working fine but I need some more finctionality like I want search the documents between two specific dates what is the exact prosedure to do that n one more problem I want to do search with the help of listbox and textbox like I want to make a listbox and on selecting any option from that I want to enter a string in the textbox and want to search that string from the specific view selected from the Listbox .How can i do this ? I'm searching this from very long time .Can u help me in this matter.It will be a great help for me . I'll wait for ur response.Please do reply me asap Thanx Priyanka
Reply
Re: Related to ur modified searchbox code
Hey jake, I mailed u personally also n gave my problem in feedback also do tell me please the solution of my problem ..It's very urgent for me n I need the solution. Thanx Priyanka
Reply
to add the view search
Hello,
I'll assume that you have the basic search box working, and that you just want to add the drop-down option to search a particular view?
In your front-end form, you have a text field called "SearchString" (that is what the IBM article calls it). You need to add another field to let the user choose a view to search. Make this a drop-down (a <select> tag with <option> tags for each of your choices). Call this "SearchView" or something similar.
Then in your back-end form that accepts the POST data (the article calls it "ViewSearch" form), add a text field called "SearchView". You may need to add input translation to strip out spaces, depending on how your views are named. Then, in the $$Return field, instead of calling
"[/" + database + "/" + "AllActionItems" + "?SearchView&Query=" + SearchString + "&Login]"
You'll call: "[/" + database + "/" + ViewSearch + "?SearchView&Query=" + SearchString + "&Login]"
In the first example, the search always searches against "AllActionItems" but in the 2nd, it will search whatever view the user has chosen.
Good luck, hope this helps.
Seth
IBM Article: http://www-128.ibm.com/developerworks/lotus/library/ls-Combining_forms_and_views _Part1/index.html
Reply
need ur advanced search coding
hello Jake, I want to know how u have done the coding of advanced search on ur page.I need the same thing in my application. chk this url http://www.codestore.net/store.nsf/search/ and then tell me how to do it I only need Listbox and Textbox on that page and if possible then date range .. Hey Please tell me I'm really searching this one since so many days ...It's veryyyyy urgent for me Thanx n please do make me reply Priyanka
Reply
does the view need any particular settings
Hey Jake,
Sorry to bother you, but I was wondering if there are any settings for the views that need to be configured?
I downloaded the database but the search doesn't work on it either. My url works fine, it goes to the $$SearchTemplateDefault form, however that form doesn't render the data from the search. I've tried just about everything I can think of.
Any help would be appreciated. Just let me know what you want from your wishlist and its done.
Thanks
Reply
Show the rest of this thread
Please chk my coding
Hello Jake, This is very surprising that it's ur site and u r not replying ......strange..neways I used ur searchbox coding n now with Textbox i want to use a ListBox....something similiar to Advanced Search... I'm new to LN as well as JavaScript so I'm just tryign at my best.I'm enclosing my coding here ..Please chk it n do tell me that where I'm doing wrong ...It's all ur coding
This is SubForm Coding with 'Query' as hidden field of "Computed for display" type
Here qyery field <table width="150",border="0",cellspacing="0",cellpadding="0"> <tr> <td colspan="2">Search by:</td> </tr> <td>
<B>Customer Status: </B> <SELECT NAME="SearchString"> <OPTION>PINView <OPTION>ByTech <OPTION>Inactive</SELECT> <P> </td> <tr> <td> <input type="text" name="Query" size="15"> </td> <td> <input type="button" name="Search" value="Go" size="5" onclick="doSearch(this.form.Query,this.form.SearchString.options[selectedIndex.v alue]);"/> </td> </tr> </table>
Now subform JsHeader Coding :
function openDbRelativeURL( url, target ){ //Check we have a target window; target = (target == null ) ? window : target; //Work out the path of the database; path = location.pathname.split('.nsf')[0] + '.nsf/'; target.location.href = path + url; }
function doSearch ( s ,p) { var regExp1 = /\bfield\b/; var regExp2 = /[(,),<,>,\[,\]]/; var str = s.value; var str2 = p.value; alert("hello"); if ( str == "" ){ alert("Please be sure to enter something to search for."); s.focus(); } else { if ( typeof regExp1.source != 'undefined' ) //supports regular expression testing if ( regExp1.test( str ) || regExp2.test( str ) ){ var alrt = "Please note that you can not include:"; alrt += "\n\nThe reserved word 'field'\nthe characters [, ], (, ), < or >"; alrt += "\n\nin your search query!\n\nIf you are confident that you know"; alrt += "\nwhat you are doing, then you can\nmanually produce the URL required." s.focus(); return alert( alrt ); } openDbRelativeURL("str2?SearchView&Query=" + escape( str ) + "&start=1&count=1000"); } }
It's same as given on ur site. After making the subform I simply Insert it on new form where I have done the HTMLHeadContent ,Jsheader and Onsubmit coding as told in ur article .. Now please check this code or tell me thw way I have to proceed to do this .... I'm in great need Jake and I don't know why are you not responding to my queries... It will be a great help for me.. Thanx Priyanka
Reply
not passing query argument
I have moved the code into a form of mine called test with the alias set as "search" and added the $$Return field, passing it the query variable from my html search form. When I click the submit button it opens the desired form but doesn't pass the variable to the URL. Can you fathom what I've done wrong?
Reply
Re: not passing query argument
>>Can you fathom what I've done wrong?
No Phil. Sorry, but that's your job. I've done my bit already by providing sample code.
I can try and help but I need more info and it would probably cost you an item from my Wishlist for my time.
Reply
Show the rest of this thread
What about placement on center site design.
I have used this new method of searching very successfully. So far, I have only used it on sites that are left justified in design. But I am trying to add it to a design that is centered. Just like your site. This is more of a CSS issue I think. I need the search Div to float at the top Right of the site just like yours. But is I use:
#search{ position:absolute; top:-2px; left: 61%; text-align:right; width:260px; font-size:8pt; }
This works but the search div will move to different parts of the design using the window as its %. I would prefer it anchor its self to the design and not the window. Any Ideas?
Reply
Re: What about placement on center site design.
Why not use the same CSS as mine then if mine works and yours doesn't?
Reply
Show the rest of this thread
How do I search fild values with SiteSearch
Hi,
I have read some of the articles on the URL Queries but whenever I try to search for specific values in fields using SiteSearch, it seems like the queries are not understood. Do the advanced queries work only with SearchView???
So far I have tried ([Form] = Article) also I have tried [Form] CONTAINS Article, basically searching the database for a specific forms.
Any help is appreciated.
Mike
Reply
and with reader access ?
Hi,
I use and test this method for an application, but createdocument is not authorized for profiles as readers: ( I tested by authorizing creation of public document, but without success). Must I choose another method, or pass profiles as authors ?
Thank you,
Reply
Re: and with reader access ?
To get it running for users with Reader-Access
1. ACL: Select "Write public document" 2. Form Properties of from "search": select "Available to Public Access users" 3. Add field $PublicAccess = "1" to form "search"
Reply
"Not is not searchable
Reply
Pressed enter too soon!
I noticed that when I search for "not" as a word, no matches get returned! Even though there is a specific document that has "not" in it. You can find it by searching for "no", and then using IE's find to find the word in the doc.
I am actually having the same problem with my own search engine.
Any suggestions on such a limiation?
Thanks
Reply
Show the rest of this thread
JavaScript access to CFD fields?
I love this site!
Can anyone shed some light on this one for me? I'm finding that the method of closing the domino form and starting a new one causes any Computed For Display fields to appear outside either form, and this apparently makes them inaccessible to JavaScript?
My simple onLoad code is: var d = 0; d = document.forms[0].MPC.value;
and the JS error I get is: 'document.forms[0].MPC.value' is null or not an object
When I make MPC an Editable field, it appears inline and is (apparently) thus accessible to JS.
Please enlighten me.
Thanks
Reply
Figured out my problem
This wasn't a </form> issue at all but I'll post the result here in case any future JS travelling newbie runs into the same.
I had to add my MPC field to the form via HTML and use type="hidden" because using Notes' hide-paragraph property on the CFD field itself does in fact make it invisible to JS.
e.g., <input name="MPC" type="hidden" value="<Computed Value>">
where <Computed Value> is the name of my CFD field, MPC.
Jake, thank you for the extremely helpful and educational site!
Best to All! Parveez
Reply
how to use ViewSearch to Search multivalue Field
To all,
how to use ViewSearch to Search multivalue Field(Not String Value, is numeric multivalue field).
my code , field = UPTax , field type=numeric
search url: http://www.aa.com.tw/da.nsf/Findall?Searchview&Query=([productID]=PR) and [UPTax]>=3 and [UPTax]<=6&Start=1&Count=15
Reply
Not passing argument when using SSL
As the subject says, I've got this working in a view header subform but when I enable SSL for the DB it stops working, I've found that the query is not being passed to the search form?
Any ideas
Reply
Re: Not passing argument when using SSL
I am having the same issue. Were there any suggestions to this?
Reply
Anyone run into the "Search query is too long" issue? I have my multi-valued field searches running well, and there are 10 of them, plus another 7 or so single value field... all on a big search form. The problem is that the resulting query is too long. If you have, for example, a multi-valued checkbox field called bed_types with and a user selects all 6 options (meaning the User is ok with any of the 6 options), the resulting query is quite long, and just for this one field:
Domino-generated search query:
FIELD bed_types = King OR FIELD bed_types = Single OR FIELD bed_types = Queen OR FIELD bed_types = Twin OR FIELD bed_types = Double OR FIELD bed_types = Non-Standard
... if just 4 or 5 more search fields are selected (with multiple options checked), the "Search query is too long" message is displayed. I believe my only other option is to perform a Lotus Script search (db.search), correct?
Reply