Auto-Filtering

Updated February 2022; see History

Auto-filtering is a mechanism, similar to that available in Windows Explorer or Excel, by which the user can click on a special button in the column header to access an automatically-generated dialog of filtering options, which can then be used to temporarily remove (hide) some of the items from the tree.

The feature is enabled by setting the XTF2_AUTOFILTER (&h00800000) bit in the FLAGS2 member of the FLAGS structure/parameter. It also may be turned on for all XTREE calls with the setting OPTIONS=XTAUTOFILTER in miame.ini. Auto-filter currently is limited to array-based trees.

At the simplest level, the filtering is entirely a client-side affair, auto-configured by XTREE and controlled by the user, invisible to the application, and lasting only for the life of the tree. Items remaining in the tree retain their original physical record/row numbers so that selecting or editing a specific item appears the same the application regardless how many other items had been filtered out.

Filter Types

There are four different types of filters, including none, which are automatically selected based on the column attributes, or which can be manually select by means of these Advance Coldef Options:

•   Filter=CB

•   Filter=RANGE

•   Filter=PATTERN

•   Filter=NONE

The CB (checkbox) filter is the most automatic of the filter types. Each time you bring it up, it analyzes the data currently in the column and reduces it down to a set of up to 10 checkbox options which are either complete values (e.g. Red, Green, Blue), starting characters (e.g. R, G, B), or ranges of starting characters (e.g A-D, E-G, H-Q, R-). The user can select one or more of the options to filter out all the others. There is also a "select all" option to bring the previously filtered items back.

The RANGE filter prompts for from/to values and works for numbers and dates/times. In the case of dates/times, the from/to values can be in any of the formats supported by the sort logic. See History note below, specifically A-Shell 1649.0.1.

The PATTERN filter is essentially just a string character match, case insensitive, and position independent. The pattern "oo" will match "Oolong Tea", "COOKIES", "foo", etc. Currently the emphasis is on simplicity; wildcards or regex expressions are not supported but may be added later depending on feedback.

The NONE option prevents any filter from being assigned. Otherwise, if no Filter type is specified, XTREE will choose one—or none—based on the column attributes.

Defaults

If you have auto-filtering enabled—either via OPTIONS=XTAUTOFILTER or by explicitly specifying the XTF2_AUTOFILTER bit in flags2—but have not specified an explicit FILTER option, XTREE will choose a filter type according to the following rules:

•   If the column type is string and: a) the width is greater than 30; or b) supports embedded CRLF; or c) otherwise allows multiple lines (cformat M or m), the default filter type is PATTERN.

•   If the column type is numeric and width > 1, the default is RANGE

•   If the column type is string but the column data contains only numeric characters (including comma, period, space, and a leading minus sign), the default is RANGE.

•   Otherwise, the default is CB.

Note that in the case of a multi-level tree, only the top level is considered.

Comments

•   Columns with a filter option other than NONE will have a check-mark button at the right edge of the column header. So filtering requires that the headers be visible. Columns with active filter criteria applied will display a strange symbol to the left of the column title meant to represent filtering. This symbol takes the place of the old up/down sort indicators, which have been moved to the top edge of the column header.

•   When multiple columns have filter specifications, they are combined with the "AND" operation. For example, if you filter the name column to include just the names starting with A and F, and also the price column to include just the range from $9.99 to $39.99, then only those rows which meet both criteria will remain visible. You can remove the filter from one column: for a checkbox filter, click "Select All"; for the other types, enter an empty pattern or range. Or you can remove the filters from all the columns by clicking on the "clear" button in any column's filter dialog.

•   On multi-level trees, filtering only applies to the top level, and all the dependents are filtered along with the top-level parent.

•   Filter=None may be associated with the zero column to disable auto-filtering for the entire tree. This may be useful if you've enabled autofilter globally (in miame.ini) but want to disable it for a particular tree. Previously, to accomplish this you would have had to add the Filter=None option to each column.

•   The filter buttons in the header can also be toggled on/off as a group via the Context menu.  See History below.

Application Filtering

The application can participate in the filtering operation by defining a "filter status" column (1 character wide), using cformat code "0" (zero). Typically you would want to hide such a column by also specifying the "H" code. Once defined, the application can pre-filter (i.e. hide) rows, prior to call XTREE to load them into the tree, by setting the column to "1". A space or "0" is treated as visible.

Note that this is similar to the LoadOptions=NoRowIf# capability—see 6.5.1627.0—except that rows filtered by a "0" column can be unfiltered by the user, whereas rows filtered out by the NoRowIf# cannot.

The application can also be notified of the visibility state of each row on exit from the tree, by adding the cformat code "U" to the column. In this case the field must also appear in the answer array and will be set by XTREE to "0" for visible and "1" for filtered out (invisible). On re-entry into the tree in XTROP_RESELECT mode, any changes made by the application to the filter state column in the answer array will be applied to the tree (i.e. hiding or unhiding rows). Note that except in the XTF2_ANSEQDATA case—where the answer and data arrays have the same format, or are actually the same—the filter state column is positioned with the checkboxes, i.e. after the drag-drop and multi-select fields, but before any editable text fields.

For the XTROP_REPLACE operation, rows are first loaded from the data array and are then updated based on the answer array. In the case where there is an updatable filter status col (0U) and rows had been filtered out during the previous editing session, this will result in all of the rows being first added—because the data array is not updated by the filtering operation—and then the filtered-out rows will be removed during the answer array load. There is nothing wrong with this two-step approach other than inefficiency; if you have very large trees, it would be more efficient to transfer the updated filter status indicators from the answer array back to the data array before reloading the tree with XTROP_REPLACE.

The sample program XTRA5.BP in EXLIB:[908,21] been updated to illustrate various auto-filter features. You need to enter '1' to the auto-filter prompt when running it.

History

2021 December, A-Shell 6.5.1709:  Specifying Filter=NONE on a zero-width column now sets the default for subsequent real columns.

2021 March, A-Shell 6.5.1701:  Minor refinements to filter dialogs, including text localization (SBRMSG.xxx 026,###).

2021 February, A-Shell 6.5.1699:  Added a "Toggle All Filter Buttons" option automatically to the context menu when XTF2_AUTOFILTER is enabled. The option toggles the visibility of the filter button in the column headers of any column not actively being filtered. The point is mainly to free up header space when the columns are tight. Note that even without the filter buttons, you can still use the context menu to filter a column to the clicked-on cell value.

2020 October, A-Shell 6.5.1690:  The CB and Pattern filter types now treat blank cells as normal. Previously, there was no way to filter out the non-blank cells using the CB filter because it didn't present a checkbox option for blank. And in the case of the pattern filter, a blank pattern was matching everything.

2020 June, A-Shell 6.5.1682:  Filter=none may now be associated with the zero column to disable auto-filtering for the entire tree.

2018 October, A-Shell 6.5.1649.6.2, further development / refinement:  (1) Columns with cformat "s" or "l" now eligible for Auto-Filtering. Previously required S or # as well. (2) Disable the context menu filter-to-value option for child items. Filtering only applies to the top level; child items are filtered along with their parents.

2018 October, A-Shell 6.5.1649.0.2, further development / refinement:  the context menu now contains smart options to clear the current column filter or all column filters when applicable. It also contains a new option to filter the column by the value of the clicked-on cell.

2018 October, A-Shell 6.5.1649.0.1, further development / refinement:  the Range filter type has been split into two variations: Filter=RangeStr and Filter=RangeNum. In the case of Filter=Range, it will decide for itself which kind of range makes the most sense. The string version (RangeStr) uses the ASCII collating sequence for the range selection, while the numeric version (RangeNum) now removes any non-numeric formatting characters from each cell and then uses the value to compare against the from/to range limits.

2018 July, A-Shell 6.5.1640:  Added feature to A-Shell.