Omnis Technical Note TNGI0028 November 2011

Creating a dynamic search field

for Omnis Studio 4/5
by Andreas Pfeiffer

Many business applications include lists that display the results of searches. It might be good to add a dynamic search field on your search window to allow users to filter the results in the window as each character entered; this is similar to the Spotlight search field on the Mac.

Let's assume your list is named "ivSearchList". Create an instance variable ivFilter in your results window. Store the filter string that will be used afterwards to filter the results in this instance variable. The filter will take account of all the columns of ivSearchList automatically. Call the method $setFilter when the window is opened; the code for this method is as follows:

; $setFilter method
Do ivSearchList.$smartlist.$assign(kTrue)
For colNumb from 1 to ivSearchList.$colcount() step 1
  Calculate ivFilter as con("|pos(ivSearch",mid($prefs.$separators,3,1),
    "upp($ref.C",colNumb,"))>0",ivFilter)
End For
Calculate ivFilter as mid(ivFilter,2,kFetchAll)

The "ivFilter" variable stores the code automatically for later usage. The search list ivSearchList must be declared as a smartlist (if it is not already a smartlist). Being a smart list it has a method called $filter that you can use for filtering.

We also need an entry field but it will not be linked to a variable in $dataname. The field also needs to have the $keyevents property set to kTrue. The $event method of the field now has the following code:

On evKey
  Process event and continue
  Calculate ivSearch as upp($cfield.$contents)
  Do $cinst.$filter()

The "Process event and continue" command makes sure that the character that has been entered will be in the $contents of the field. In case a backspace was executed it will be respected as any other key.

Now let's look at the $filter method which will take care of the filtering of the list, it has the following code:

Do ivSearchList.$unfilter() ;; sets the old filter back
If len(ivSearch)>0
  Do ivSearchList.$smartlist.$assign(kTrue)
  Do ivSearchList.$filter(eval(ivFilter))
  ; uses the content of iVFilter for filtering
End If
Do $cinst.$redraw()

The eval(ivFilter) function makes sure that the filter included in the variable ivFilter will be executed. To delete the filter you can add a button, with its $event method contains the following code:

On evClick
  Do ivSearchList.$unfilter()
  Calculate ivSearch as #NULL
  Do $cinst.$objs.filter.$contents.$assign(#NULL) ;; Filter clear field
  Do $cinst.$redraw()

If you programmed your search window on the basis of a superclass you will have the advantage that this field will also work in all inherited classes.