Updated April 2023; 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 user interface looks like this:
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 five 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=CBX |
• | 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 ten 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 CBX filter is similar to the old Filter=CB but instead of grouping the items by the first one or two characters, it lists them all. CBX is the default filter type. See History below for when CBX was introduced.
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 CBX. |
Note that in the case of a multi-level tree, only the top level is considered.
Filter Button Visibility
The user accesses the filter feature via the buttons in the column headers (see image above), and normally whenever filtering is enabled, the buttons are visible. But in some cases it may make sense to hide them, possibly to minimize clutter or free up space for column header text in narrow columns. The rules and configuration options affecting the visibility of the filter buttons are as follows:
• | When enabled globally (via OPTIONS=XTAUTOFILTER) but not locally (via the XTF2_AUTOFILTER flag), the initial filter button state will be hidden. Otherwise it will be visible for all columns that have either explicit or default filters (i.e. anything but Filter=NONE). |
• | The developer may explicitly set the initial state to hidden via the Advanced Coldef Option FilterInitialState=Disabled. (If specified for the zero column, it affects all columns, otherwise it only affects the column(s) for which it is specified. |
• | The user may toggle the filter button visibility via the context menu options: |
• | If the tree has a TreeID specified, then if the user changes the state of the filter button visibility, the changes will be saved and used as the initial state the next time that tree is displayed. |
Application Filtering
The application can participate in the filtering operation by defining a "filter status" column (one character wide), using cformat 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 calling 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 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 column (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.
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 auto-filter 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. |
See Also
• | XTAUTOFIILTER in System Parameters |
History
2023 April, A-Shell 6.5.1729: Add CBX filter.
2023 January, A-Shell 6.5.1724: Several Auto-Filter refinements:
• | If auto-filtering is enabled globally via the OPTIONS=XTAUTOFILTER directive in the miame.ini, but not set explicitly for the current tree (via the XTF2_AUTOFILTER flag), then the initial state of the filter buttons will be hidden, but can be activated (made visible) via the context menu. This is intended to make it easier to enable auto-filter globally without having to worry about the overcrowding of narrow column headers or general clutter caused by the filter buttons in trees where filtering may not be important. |
• | Add a new Advanced Coldef Option (FilterInitialState=Disable) which can be used to hide the filter button from specific columns (or the entire tree if added to the zero column definition), while still allowing it to be activated via the context menu. |
• | Add a new option to the context menu to toggle the filter button for just the current column. |
• | Vastly improve (10-50X) the speed of filtering operations. |
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.