Developing traditional Domino Web pages, I often used a symple techinque to dynamically change options in a combobox, depending on a key typed in an input box. Through an Ajax call to a Lotus Script agent, I could use HTML code sent back to the browser by the "print" statement to populate my "<select>" options.
Applying the same technique to XPages it's maybe possible, but it looked to me quite tricky and not consistent with the XPages model. Thus, I started playing with events and Server Side JavaScript to find out a different solution.
A combo box in a web page shows by default a list of options from a Notes View.
Typing a word or a sentence into the input box, a user can refine the search and get a subset of the original list shown in the combobox.
What I needed was not Type Ahead. A user must be able to type a word or a sentence and have the system automatically look for documents containing such a word anywhere in a couple of fields.
1. The database must be indexed
2. The input box is binded to a Request Scope "nameToSearch"
3. The "on blur" event for the input box and/or the "on click" event for the button have a simple Action (Server Side JavaScript) coded as follows:
"sessionScope.nameToSearch = requestScope.nameToSearch" and the Server Option put to "Partial update" --> combobox ID
4. Values for combobox are computed (dynamically), through a server side JavaScript
The code has been tested agains about 5.000 documents. Refining the choice list took less than a second.
1. create a new, indexed Database. If the database is not full text indexed, the code will not work
2. create a Notes form "Location". Add 4 text fields: "Name","City","State","CodePV"
3. create a Notes View "(Locations)". Write @SELECT Form="Location" as the Selection Formula. Then add 4 columns: "Name","City","State","CodePV"; the first one indexed.
4. create a Notes View "(FullLocations)". Here, you need just one column using the following formula: Name + " - city: " + City + " - state: " + State
Same selection formula as above.
5. Save several documents using the form you have just created. Fill in all fields for any saved document.
Those are just the elements you need to have the example working. Now, we'll start working on the XPages based code.
6. create a new custom control. Add to it an inputbox, a button and a combobox (call it "comboBox1")
7. select the inputbox, go to "Data" tab, select "Advanced" under "bind data using". In the Advanced box select Use=Scoped Variable, Parameter=Request scope,Variable name=nameToSearch, Compute dinamically.
8. Go to the Events tab, select the "on blur" event and add a Simple Action (Server)
9. In the dialog box, choose Category=Basic, Action=Execute script, Language=JavaScript (Server side)
10. Type a single line of code: sessionScope.nameToSearch=requestScope.nameToSearch
11. Then, go to the "Server Options" box and choose "Partial update". Hit the button "Select element..." and choose the "comboBox1" element.
12. Select the button, Label it "Search", and and add to it the same Action and Server Options as above.
13 Select the combobox element, go to the "Values" panel and hit "Add Formula item..."
14. Choose Language=JavaScript (Server Side), Condition=Compute dynamically, and add following code:
1: var criteria = sessionScope.nameToSearch;
2: var searchKey = "([Name] CONTAINS "+criteria+" OR [City] CONTAINS "+criteria+" OR [CodePV] CONTAINS "+criteria+")";
3:
4: var currDoc:NotesDocument;
5: var myOpt=new Array();
6:
7: if (null != criteria && criteria != ""){
8: var currDb:NotesDatabase = session.getCurrentDatabase();
9: var currView:NotesView = currDb.getView("(Locations)");
10: var viewElem = currView.FTSearch(searchKey);
11: if (viewElem >=1) {
12: for (i=1;i<=viewElem;i++) {
13: currDoc = currView.getNthDocument(i);
14: if (null != currDoc) {
15:
16: myOpt[i-1]=currDoc.getItemValueString("Name")+" - city:
17: "+currDoc.getItemValueString("City")+" - state:
18: "+currDoc.getItemValueString("State");
19: }
20: }
21: myOpt.sort();
22: }
23: else {
24: myOpt = "";
25: }
26: }
27: else {
28: myOpt = @DbLookup(@DbName(),"(FullLocations)",filtro,2);
29: myOpt.splice(0,0,"");
30: }
7. create a new XPage, call it whatever you want. I just called it "test"
8. add the custom control to the XPage
...