Filtering lists based on a Helper entity
--
Mendix apps are great at presenting lists of data in different forms like data grids, template grids or list views. Filtering on these standard solutions can be limited and need additional widgets when more filtering functionality is required. Mendix 9.0. brought improvements like the Datagrid 2.0, but this blog is for those of us who are using older versions, and are attempting an implementation of a helper function to do advanced filtering.
The Standard solution
In a standard solution (like in the workflow module) a user gets the information via a tab container with three options based on Priority and the filtering is done based on an xpath selection that includes the priority. The selection is repeated in each tab with a different xpath selection. This works fine but is inefficient from a maintenance perspective. A data grid can be used with different selection options(simple, multi etc), but these are not available in list views or template grids.
Use Case
A service centre has agents working on requests from different clients based on requests via email, phone calls etc. Each request is logged in an activity and assigned to a queue. Assigning activities to queues is based on subjects selected by the caller and/or location of the caller. Users (aka agents) are assigned to various queues and can handle all requests in the queues they are assigned to.
Activities are assigned to a queue and are prioritized (high, medium, and low) and get a due date/time. Below the domain model as used in this blog:
I introduce an extra entity between user and Queue to be able to add information on the association.
Implementing a helper function base on a helper entity
In this document the implementation of a helper function will be shown and expanded with more functionality.
Target screen with helper function over version 1[1]
Minimum viable product
The base of the functionality is a non-persistent entity (HelperAssignedActivities) with 2 fields: FilterPriority and FilterStatus.
When the page is started the initial version of HelperAssignedActivities is returned by a retrieval microflow (DS_HelperAssignedActivities):
This microflow has only an activity to create the object and set the initial values and return the created helper object.
In the page a grid is added to the data view object of the helper object. The grid is filled with a list returned by the ‘DS_GetActivities’ microflow:
Because the helper object is non-persistent it cannot be used in the retrieve, that is why two variables are created with the values of the priority and status filter fields.
The retrieve is straight forward but should also take care to show all values when empty.
Each button is linked to a microflow that updates the helper object (with a refresh in client) and set the field in the helper object.
Version 1: with counters.
This MVP just shows you the filter mechanism and the results, but does not show any information with number of records of each filter option. A new sub microflow (SUB_HelperCalculateCounters) is introduced, that uses the same microflow as used in the grid and determines the individual number of records related for each option[2] (based on filtering and a list operation (count)). These variables are then stored in the helper object with a ‘refresh in client’. The ‘refresh in client’ is required to make sure that the grid is also refreshed with the correct filtering. The ‘refresh in client’ is done in the new sub flow so the ‘refresh in client’ in the parent flow, which is triggered by the buttons can be removed.
The full microflow of one of the buttons:
Version 2: with queue filter.
When the list gets longer it might be useful to be able to filter on a specific queue. This can be achieved by adding an association to the helper entity. A reference selector can be added to the screen. To force the grid to refresh, a new microflow is started from the ‘on change’ event (ACH_HelperAssignedActivityQueue). In this microflow it is not needed to change the helper object, because it is directly done via the reference selector.
Next to this it is also needed to adjust the microflow that is used by the grid by retrieving the selected queue from the helper function and the reset function.
Version 3: Save selection for future use.
In the above scenarios every time a user must set its filters. It should be great if returning to the page the filters are still the same. This can be achieved by linking the helper entity to the session and in the retrieve microflow first retrieve the helper entity via the current session and create one when not found. So, within the same session the user will keep its settings, although is should be convenient to add a button to the screen to clear the filters.
Another option is to associate the helper function to the user entity and make it persistent. The retrieve microflow first tries to get the helper object via the current user and create one when not found.
Result
The result after version 3 (with a helper associated with the user):
Summary
In this blog a solution for filtering is presented which can be used in many cases. It can also be expanded with more filtering and sorting such as date selections etc. More filtering options will make the queries more complicated, which might be a risk[3]. Although a lot of options are available in a data grid (and datagrid 2) these options are not available in a list view or template grid. The option to remember used filters (see version 3) is not possible in a regular data grid.
[1] The buttons corresponding to the filtering values are shown with a different dynamic class. This functionality is available since version 8 of mendix.
[2] The counters are used in the caption of the buttons.
[3] Another solution might be not too complicate your query but to remove objects after the initial retrieval.
Written by André Luijkx (andre@mendixmagic.com) a seasoned freelance mendix developer.
Read more
From the Publisher -
If you enjoyed this article you can find more like it at our Medium page or at our own Community blog site.
For the makers looking to get started, you can sign up for a free account, and get instant access to learning with our Academy.
Interested in getting more involved with our community? You can join us in our Slack community channel or for those who want to be more involved, look into joining one of our Meet ups.