Advanced Sorting

Content Type: Widget
Categories: User Interface

Overview

Reusable widget to encapsulate the math required to manually do sorting. Most useful for:

1. Getting data from an API that allows sorting (e.g. https://cars.com/users?sort_by=year&order=desc)

2. SQL / OQL queries (e.g. SELECT * FROM CAR ORDER BY YEAR DESC)

3. Creating custom grids with the [Xpath module](https://marketplace.mendix.com/link/component/120424)


Tip: Need pagination too? Check out Advanced Pagination. (GitHub) (Mendix Marketplace)

Need selection too? Check out Listview Selection. (GitHub) (Mendix Marketplace)

Documentation

Demo urlhttps://widgettesting105-sandbox.mxapps.io/p/advanced-listview-controls

Advanced Sorting

Reusable widget to encapsulate the math required to manually do sorting. Most useful for:

  1. Getting data from an API that allows sorting (e.g. https://cars.com/users?sort_by=year&order=desc)
  2. SQL / OQL queries (e.g. SELECT * FROM CAR ORDER BY YEAR DESC)
  3. Creating custom grids with the Xpath module

Tip: Need pagination too? Check out Advanced Pagination. (GitHub) (Mendix Marketplace)
Need selection too? Check out Listview Selection. (GitHub) (Mendix Marketplace)

demo

Features

  • Offers Headers and Dropdown sorting methods
  • Drag and drop method of setting sorting attributes
  • Ability to customize the icons displayed
  • Accepts a Sort Attribute string and a Sort Ascending boolean
  • Ability to use any Mendix content for the header
  • Ability to configure your own list of dropdown values

Usage

The following steps will create a list view with sortable headers that look like the image below.
demoBrowser

Create the Pagination Module

I usually make a separate, small module for some of the core functionality. This serves 2 purposes:

  1. The module can easily be exported and imported into other projects
  2. The core logic is stored in a common place if you need to make multiple Custom Grids in your app

Follow these steps to make the Pagination Module:

  1. Download the latest version of the Nanoflow Commons module
  2. Right-click on your app name in Studio Pro, click 'Add module ...', and name the module "Pagination"
  3. In the domain model, create a non-persistent entity called Pagination with Page (default to 1), PageSize, and ResultTotal.
    pagination entity
    Note: The SortAscending and SortAttribute are not used for this example, but you'll need them if you want to use the Advanced Sorting widget. (GitHub) (Mendix Marketplace)
  4. Create a Nanoflow called ACT_Pagination_Refresh with a Pagination parameter. Add a refresh object activity from the Nanoflow Commons module.
    ACT Pagination_Refresh
  5. Create a Nanoflow called ACT_Pagination_Search with a Pagination parameter. Add a change object activity and set the Page attribute to 1. Then call the ACT_Pagination_Refresh Nanoflow.
    ACT Pagination_Refresh
  6. Create a module role called User and grant that module role full access to the Pagination entity and the Microflows from steps 3 and 4.
  7. In your project security settings, grant all user roles the Pagination module's User user role.

What are the two Nanoflows for? ~ ACT_Pagination_Refresh should be used when you just want to refresh the results (e.g. changing pages or sorting). ACT_Pagination_Search should be used when the user may have changed the search criteria (e.g. on-change action for a text box or a search button)

Main Domain Model

Inside the domain model of the entity you need to retrieve, create a non-persistent entity specific to your grid. I usually put this right next to the entity it retrieves in the domain model

  • I use the format Search{ReturnedEntity} (e.g. if my grid is going to return Employee objects, I would name it SearchEmployees). For the rest of the documentation, this entity will be referred to as Search{Entity}
  • Set Search{Entity} to generalize Pagination
  • Add an association to System.Session.
  • Add attributes and associations for any search criteria you want. For me, FuzzySearch is for the text input and the associations are for multi-select popups I want to display.
    searchEmployees

Create a Microflow called DS_Search{Entity} that retrieves the list from $currentSession for an existing Search{Entity} object. If the list is not empty, head the list and return the object. Otherwise, create a new object with the association to System.Session as $currentSession and PageSize as whatever default page size you want.
DS_SearchEmployees

How to set the Attribute Name

If you are using the Xpath module, all of the Attribute Name settings should be the exact database name of the attribute you want to sort. They are case-sensitive. If you want to sort across an association, use the format "{ModuleName}.{AssociationName}/{ModuleName}.{EntityName}/{AttributeName}".

For example, consider the following domain model from the 'TestObjects' module.
general

Sorting MxID Sorting Department Name
general general

Page and Widget Setup

View the following sections based on which Display Type you want to use.

Header

  1. Set up your page similar to below with the widgets above the list view. These should be inside a data view with datasource DS_Search{Entity}.
    page_mendix
  2. In the Advanced Sorting widgets, set Sort Attribute and Sort Ascending to the attributes on your Search{Entity}. Set the Refresh Action to ACT_Pagination_Refresh.
    general header
  3. Set the Attribute Name as the exact database name of the attribute you want to sort. For a specific example, see the How to set the Attribute Name section above.

Static Dropdown

  1. Set up your page similar to below with the widgets above the list view. These should be inside a data view with datasource DS_Search{Entity}.
    page_mendix dropdopwn
  2. In the Advanced Sorting widget, set Sort Attribute and Sort Ascending to the attributes on your Search{Entity}. Set the Refresh Action to ACT_Pagination_Refresh.
    dropdown static
  3. Decide if you want to use Dropdown Sort Type "Data" or "Toggle"
    Data - The Dropdown Value's Sort Ascending setting determines what the sort direction should be.
    Toggle - A toggle button will appear next to the Dropdown that can be used to toggle the sort direction.
  4. Add all of the items you need to the Dropdown Values list.
    dropdown item
    Caption - The text shown in the dropdown.
    Default? - Determines if this value is selected when the widget loads. There should only be 1 item with default set to Yes. If no items have a default, the widget will set the first item on load.
    Attribute Name - Set the exact database name of the attribute you want to sort. For a specific example, see the How to set the Attribute Name section above.
    Sort Ascending - When the user selects this item from the dropdown, should the SortAscending attribute on the Search{Entity} be set to true or false? Ascending = true. Descending = false. This option is only available if Dropdown Sort Type is set to Data.

Dynamic Dropdown

  1. Add the following DropdownValue entity to store the data for each dropdown option.
    dynamic dropdown domain
  2. Create a Microflow/Nanoflow that creates the DropdownValue objects you want to display in the dropdown called DS_DropdownValues.
    DS_DropdownValues
    Caption - The text shown in the dropdown.
    _Default - Determines if this value is selected when the widget loads. There should only be 1 item with default set to Yes. If no items have a default, the widget will set the first item on load.
    AttributeName - Set the exact database name of the attribute you want to sort. For a specific example, see the How to set the Attribute Name section above.
    SortAscending - When the user selects this item from the dropdown, should the SortAscending attribute on the Search{Entity} be set to true or false? Ascending = true. Descending = false. This option is only available if Dropdown Sort Type is set to Data.
  3. Set up your page similar to below with the widgets above the list view. These should be inside a data view with datasource DS_Search{Entity}.
    page_mendix dropdopwn
  4. In the Advanced Sorting widget, set Sort Attribute and Sort Ascending to the attributes on your Search{Entity}. Set the Refresh Action to ACT_Pagination_Refresh.
    dropdown dynamic
  5. Decide if you want to use Dropdown Sort Type "Data" or "Toggle"
    Data - The Dropdown Value's Sort Ascending setting determines what the sort direction should be.
    Toggle - A toggle button will appear next to the Dropdown that can be used to toggle the sort direction. If you use this setting, you do not need the SortAscending attribute on the DropdownValue entity.
  6. Go to the newly added Dynamic Dropdown tab. Select DS_DropdownValues as the Dynamic Data Source. Then select the rest of the options as the matching attribute name.
    dynamic dropdown item

How to Use the Sort Attribute and Sort Ascending

When the user clicks on a header or selects an option from the dropdown, the Search{Entity}'s SortAttribute and SortAscending will be set. You can use these values in your API, SQL, or Xpath. In my use case, I'm using the Xpath module. So, I set the SortMap object based on the values from the Search{Entity} object.
microflow

Customization settings

customization
Show label - Shows the Mendix input label. Use for Dropdowns.
Aria label selector - What the screen reader will say when focused on a header or when Show Label is disabled for dropdowns.
Aria label ascending - What the screen reader will say when focused on the Toggle button and the button is ascending.
Aria label descending - What the screen reader will say when focused on the Toggle button and the button is descending.
Ascending icon - Option to customize the ascending icon.
Descending icon - Option to customize the descending icon.
Toggle alignment - Controls which side of the dropdown the Toggle button is shown.

Common settings

common

Demo project

https://widgettesting105-sandbox.mxapps.io/p/advanced-listview-controls

Issues, suggestions and feature requests

https://github.com/bsgriggs/mendix-advanced-sorting/issues

Development and contribution

Benjamin Griggs

Releases

Version: 2.1.1
Framework Version: 9.18.0
Release Notes: - updated read me to use Nanoflows for ACT_Pagination_Refresh and ACT_Pagination_Search. These are slightly more efficient than Microflows for this use-case.
Version: 2.1.0
Framework Version: 9.18.0
Release Notes: - added studio pro rendering to make it easier to see what the widget is sorting - added a simple text option for header type to make it quicker to set up basic headers - added screen reader aria labels
Version: 2.0.0
Framework Version: 9.18.0
Release Notes: - Added an option for Display Style = Dropdown to have a direction toggle button - Updated the order of the properties to have the required settings shown first - Updated the example in the ReadMe to use the Xpath Module
Version: 1.3.0
Framework Version: 9.6.2
Release Notes: - Added tab index for keyboard navigation - Updated to Mendix 9.6.2
Version: 1.2.0
Framework Version: 9.0.5
Release Notes: - changed Attribute Name to an expression
Version: 1.1.0
Framework Version: 9.0.5
Release Notes: added multi-language support
Version: 1.0.0
Framework Version: 9.0.5
Release Notes: Initial release