Ask Reuben

fglfind

How can the end user find rows in a list quickly? 

How can I add a toolbar entry to find a row in a list? 

How can I change the built-in find user interface?

How can I make the reduce filter available in a desktop?

When the active dialog is a List Dialog (DISPLAY ARRAY, INPUT ARRAY), there is built-in functionality enabling the user to find particular rows, or move to rows quickly.  The problem is because there is no default visible action, end users and developers are often unaware that the functionality is  there.  Developers are also unaware of just what customisation they can make to this functionality so that it fits the rest of their application.  There are three such areas of functionality, find (fglfind), seek, and filter.


find

The built-in find allows a user to find rows in an array that contain a value.  This was added in 2.40 New Features.

How it works is that there is a built-in action “find” available in DISPLAY ARRAY and INPUT ARRAY.  When this action is triggered, a dialog appears that allows the user to indicate what value they want to look for.  When the user accepts this dialog, the current row will change to the first row that matches this pattern.  There is also a “findnext” action that the user can then use to find the next row that matches the pattern.

What most developers are not aware is that if they look in FGLDIR/lib/default.4ad there is a default action find and findnext with accelerators Control-F and Control-G respectively …


<ActionDefault name="find"     acceleratorName="Control-F" text="Find" image="find" comment="Search"/>
<ActionDefault name="findnext" acceleratorName="Control-G" text="Find Next" image="findnext" comment="Search"/>

Using these action names, they can add a toolbar item or a button to trigger this action.  In their .4ad they can alter the appearance of the text and icon for these actions as well as change the accelerators.  In  a mobile environment, it would be imperative to add an action view such as a toolbar or button to trigger this action, as you can’t press Control-F in a mobile environment.

If the developer also looks in FGLDIR/lib they will find fglfind.42m and fglfind.42f, and that if they look in FGLDIR/src they will find fglfind.4gl and fglfind.per.

If you are unhappy with the default appearance of this find window then you can override this code by putting your own fglfind.42m and fglfind.42f further up FGLLDPATH so that your modules are found before the entries in FGLDIR/lib are found.

(Any 4gl function in FGLDIR/src , FGLDIR/lib can be overridden by having a module with the same .42m name, and the same function with the same signature, that is found by the FGLLDPATH search algorithm before our default in FGLDIR/lib.  Same principal applies for forms only the environment variable is FGLRESOURCEPATH)

Something else interesting if you look in FGLDIR/src/fglfind.per

  • note that the text is localised e.g. TEXT=%"fgl.findDialog.title", so you can customize the text by having your own localization entries.
  • note that the STYLE="dialog4", dialog4 is defined in FGLDIR/lib/default.4st.  Those with their own 4st might not have an entry with “dialog4” and thus the window might not open modal.  So consider adding a dialog4 to your .4st or changing the style in your overridden fglfind.per/fglfind.42f.

The screenshots below using the gwc-demo program show the Find Dialog appearing after you press Control-F, and then entering a value “Lan” to find the first row beginning Lan …

seek

The keyboard seek functionality was also introduced in 2.40.  It allows the user to change the current row of an array by typing some letters and the current row will change to a row that has data that matches what they have typed.

Conditions to work are …

  • DISPLAY ARRAY
  • TABLE, TREE, or SCROLLGRID, not Matrix
  • array rows are in memory
    • not possible with ON FILL BUFFER
    • not possible with collapsed rows of a dynamic tree.
  • front-end has a keyboard
    • not mobile

The runtime will look for a row having

  • a character column with a value that starts with the letters typed
  • numeric columns, date columns, columns with GUI widgets are ignored
  • if the array is sorted, only values in the sorted column are looked at
  • the search is case-insensitive

There is a timer so that keystrokes made within a certain number of milliseconds are treated as one word.  Type NEW quickly and the runtime will look for data beginning “NEW…”.  Type NEW slowly and the runtime will look for data beginning “W…”

There is no way to enable/disable this functionality other than the conditions above.  There is no presentation style to enable or disable.

There is no action available that allows you to produce a visible action view.

If you want to test this functionality quickly, using gwc-demo

  • type N and notice the current row move down one row to the second row that has data value beginning with N (illustrated by screenshots below)
  • notice the difference between typing NEW quickly versus typing NEW slowly.  With NEW quickly, the cursor will end in the row with “New in 4.01”.  Type NEW slowly, and the current row changes 3 times, ending with the row beginning “Widgets” i.e beginning with W
  • using the second table, sort on a column and note how only values in the sort column are inspected by the seek.

filter

The filter functionality is something that first appeared with the Mobile Client in 2.51 and then in 3.10 made its way into the standard products.

The list reduce filter allows the end-user to reduce the number of array rows that are displayed.  The functionality is available when …

  • in a DISPLAY ARRAY
  • Table or Scrollgrid container
  • not using ON FILL BUFFER

When the functionality is available, an icon  appears in the ChromeBar.  The user can click or tap on this icon and they will be able to enter text.  The rows visible in the array will change so that only those rows that match the filter are visible.

The functionality is enabled by default on mobile platform, and disabled by default on desktop platforms.  It can be enabled or disabled by the reduceFilter presentation style available for both Table and Scrollgrid containers.


<Style name="Table">
     <StyleAttribute name="reduceFilter" value="yes" />
</Style>