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

See GitHub for the formatted ReadMe


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)



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.


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. Right-click on your app name in Studio Pro, click 'Add module ...', and name the module "Pagination"


  2. In the domain model, create a non-persistent entity called Pagination with SortAttribute and SortAscending.



  3. Note: The Page, PageSize, and ResultTotal are not used for this example, but you'll need them if you want to use the Advanced Pagination widget. (GitHub) (Mendix Marketplace)

  4. Create a Microflow called ACT_Pagination_Refresh with a Pagination parameter. Add a change object activity with refresh in client set to Yes.


  5. Create a Microflow 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 Microflow.


  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 Microflows 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.


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.


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.






Sorting MxID

Sorting Department Name





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}.


  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.


  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}.


  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.


  3. Decide if you want to use Dropdown Sort Type "Data" or "Toggle"

  4. Data - The Dropdown Value's Sort Ascending setting determines what the sort direction should be.

  5. Toggle - A toggle button will appear next to the Dropdown that can be used to toggle the sort direction.

  6. Add all of the items you need to the Dropdown Values list.



  7. Caption - The text shown in the dropdown.

  8. 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.

  9. 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.

  10. 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.


  2. Create a Microflow/Nanoflow that creates the DropdownValue objects you want to display in the dropdown called DS_DropdownValues.



  3. Caption - The text shown in the dropdown.

  4. _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.

  5. 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.

  6. 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.

  7. 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}.


  8. 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.


  9. Decide if you want to use Dropdown Sort Type "Data" or "Toggle"

  10. Data - The Dropdown Value's Sort Ascending setting determines what the sort direction should be.

  11. 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.

  12. 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.


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.


Customization settings



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



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.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