Client-side Filter/Order, and Grouping

Description

List data can be filtered, ordered, and grouped using client-side expressions.

Discussion

A client-side filter, order, or group break can be defined for any List. These client-side expressions are applied after data has been loaded tinto the List control. If you have defined a server-side filter or order, the client-side filter and order will be applied in addition to the server side filter and/or order.

The Client-side Filter/Order, and Grouping properties are used to create filter, order, and/or group break expressions that will be evaluated on the client's device or browser. These properties and how to use them are described in detail below.

Filter

The Filter is a JavaScript expression used to filter the data in the List. The filter expression is applied to each row in the List. The expression must evaluate to true or false.

If the expression is true, the row is shown. If the expression is false, the row is hidden.

The expression can reference fields in the current row using the data variable. You can use the Insert field name link in the filter expression builder to insert fields into the filter expression.

The data variable name and field names are case sensitive.
images/filterExpression.png

For example, in a List that has a 'State' field, the following expression can be used to only show records where the 'State' field is equal to 'MA':

data.State == 'MA'

In the next example, records will only be shown if the 'State' is 'MA' and the first character of the 'Name' field beings with 'A':

data.State == 'MA' && data.Name.substr(0,1) == 'A'

Notice that the JavaScript double equals == are used for equality, single quotes are used for string constants, and && are used for the 'and' operator.

Order

The Order is a field or expression that defines how the List should be ordered (i.e. sorted).

The order expression is defined as a CR-LF delimited list of fields. For example, to order records by 'State' and then by 'Lastname' within each state, you would specify the following expression:

State
Lastname

By default, the data in each column is assumed to be character data. If the data should not be treated as character data, you can specify an optional data type override for a field. For example, the following definition specifies that the 'HireDate' field should be treated as a date:

HireDate|Date:MM-dd-yyyy

If the 'HireDate' contained a time portion, the time portion can be included in the data type override. For example:

HireDate|Date:MM/dd/yyyy 0h:0m:0s A

The following overrides are available:

Override
Description
Number

Field will be treated as numerical data.

Date:dateFormat

Field will be treated as a date with the specified date or date-time format. The format is defined using the same format codes used to o define the Date (and time) formats for the UX Component. See the Date format property to learn more about date formats.

Logical

Field will be treated as boolean (true/false) data.

Character

Field will be treated as character data. This is the default behavior for all fields.

The dateFormat format can be specified as a date value containing the day, month, and year (e.g. MM-dd-yyyy, dd-MM-yyyy) or a date-time value containing both the date and time values. For example, dd-MM-yyyy 0h:0m A.

You can also specify an optional sort direction. By default, all fields are sorted in ascending order.

Lastname|Character|Desc
HireDate|Date:dd-MM-yyyy|Asc

If the field is a character field, you may also specify the number of characters used to sort the field. By default, the sort is performed on all characters in the field. In the example below, the field is ordered on the first character in the 'Lastname' field in descending order:

Lastname|Character|Desc|1

If you omit the parameter for number of characters, or set it to -1, the sort is performed on all characters in the field.

Has client-side group breaks

If checked, the Has client-side group breaks property enables client-side group breaks for the List.

Client-side group breaks are inserted into the List on the after the List has been populated. Client-side group breaks offer several advantages over server-side group breaks. Namely:

  • You can define multiple levels of group breaks. Server-side group breaks only allow for one level of grouping.
  • You can dynamically change the grouping on the List at any time using JavaScript. (There is an action in Action Javascript to help you do this. See List Control Actions - Client-side group breaks for more information).
  • You can apply group breaks regardless of the data source for the List.
  • You can display Group Headers and Group Footers (server-side grouping only shows a header).
  • You have complete control over the HTML that is displayed in the header and footer.
  • You can include any summary data that you want in the header and footer (for example, average value of some column in the group).
Server-side vs. Client-side Group Breaks: One advantage of server-side group breaks over client-side group breaks is when the List data source is based on a SQL query and you have turned on the List pagination option. In this case, summary data shown in a List header will be for all of the data in that group, not just the records that are currently visible in the List.

In the image below, the List has two levels of grouping: Country and City. Notice that a custom style has been defined for the second level group headers (showing the city name in blue, with a left padding of 50px).

images/listgrouping.jpg

Here is the same List, but this time showing some summary data in the top level group header:

images/groupbreaks_client_with_sumamry.jpg

To turn on client-side grouping for a List, check the Has client-side group breaks property for the List as shown in the image below:

images/hasclientsidegroups.jpg

After you have enabled group breaks, you can click the smart field option for the Group breaks definition property (below) to open the Client-side Grouping genie.

Group breaks definition

The Group breaks definition defines the group break(s) for the List. Each group added using the Add Group button is configured using the properties listed below:

  • Sort definition

    The columns in the List on which the data is to be sorted. You can specify multi-level sorts, ascending or descending, and the number of characters in the field on which you want to sort.

    For more information on how to define a Sort definition, see Order above.

  • Group break expression

    A JavaScript expression that can reference fields from the current row in the List. If the value in this expression changes, a new group is started.

    For example, assume the Sort definition for the current group sorts the List data on the 'Lastname' field. To create a new group every time the 'Lastname' changed, you would specify the following expression:

    data.Lastname
  • If you wanted to break only when the first letter of the 'Lastname' field changed, you could specify a JavaScript expression. The following expression will create a new group break every time the first letter of the 'Lastname' field changes:

    data.Lastname.substr(0,1)
  • If the Sort definition includes multiple columns, you can include these columns in the group break expression. For example, suppose a two-level sort was defined on the 'Lastname' and 'Firstname' fields. You might define the following group break expression:

    data.Lastname + ',' + data.Firstname
  • You do not need to include all sort fields in the Group break expression. A group break expression can reference as many or as few sort fields as desired. For example, you might still define the following expression even though the sort definition includes both the 'Firstname' and 'Lastname' fields:

    data.Lastname.substr(0,1)
  • this will start a new group every time the first letter of the 'Lastname' field changes. The rows in the group will be ordered using the defined Sort definition (e.g. Lastname, Firstname).

  • HTML expression (Header)

    A JavaScript expression that returns the HTML to display in the group header. This expression has reference to these fields: group and data. group is the value of the group break expression, and data is an array containing the rows that are shown in this group. Having access to the array of data in the group means you can compute any type of summary value to show in the header or footer.

    For example:

    'Records in state of: ' + group + ' (count: <b>' + data.length + '</b>)'
  • If the list has 10 records for the state of 'CA', the header would display as:

  • Records in the state of: CA (count: 10)

    • Summary Fields

      When you define the HTML for the header or footer, you can click the smart field button to open a genie. This genie has an option that makes it easy to include summary data in the header or footer. For example, in the image below, which shows the editor for the header HTML expression, the user has clicked on the Insert summary field hyperlink, and the Summary Field Genie is displayed.

      images/htmlheaderexpression.jpg
    • When you use the Summary Field genie, the generated JavaScript that is inserted into the expression calls a special helper method of the List object. For example, here is the code to compute the average of the Price column:

      this.groupSummary(data,'Price:N','avg')
      The groupSummary() method ignores NULL values in the data.
    • In the example below, the average is computed and then formatted using a format string:

      Number(this.groupSummary(data,'Price:N','avg')).toFormat('# ##0,00')
    • Note that the method passes the data array as the first argument, the field to summarize as the second argument, and the summary type as the third argument to the this.groupSummary function.

      The groupSummary() method can be used to compute the total, average, count, first, last, min, and max value of any field in the data array.

    • Using Custom JavaScript Functions

      You can also define your own JavaScript functions that can be used to compute the header HTML. The custom JavaScript function must take two parameters, group and data. For example, you might define the HTML header expression as follows:

      myFunction(group,data)
    • The JavaScript function myFunction could be defined as follows to return the HTML for the header:

      function myFunction(group,data) {
          var html = "";
          var numRecords = data.length;
      
          html = numRecords + " total for " + group;
      
          return html;
      }
  • Classname (Header)

    One or more class names to apply to the group header. The default class name for this property is [theme:listBox.base.item.titleClassName]

  • Has footer

    Defines whether or not a Footer should be generated for each group. If checked, the HTML expression and Classname properties will be exposed in the Footer category.

  • HTML expression (Footer)

    A JavaScript expression that returns the HTML to display in the footer. See the HTML expression (header) above for more information on how create the expression.

  • Classname (Footer)

    One or more class names to apply to the group footer. By default, this property is blank.

  • Include group in navigator

    Specified if data from this group are included in the Navigator. For the top level group, this option must always be checked.

    When you have a lot of records in a List, scrolling the List to the bring a section of the List into view can be tedious - especially on mobile devices where there is no vertical scroll bar. The List Navigator makes it easy to scroll a List that has group breaks. In the image below a List is shown with group breaks on the first character of the Contactname field. A List Navigator is shown on the right side of the List.

    See List Navigator to learn more.

    images/listnavigator.jpg
  • Default group names

    By default, the group breaks shown in a List when client-side grouping is turned on, are dynamically computed from the actual data in the List. However, you might want certain groups to appear in the List regardless of whether the List contains any data for that group. You can specify a list of default groups that should always appear in the List using the Default group names property.

    In the image shown below, default groups for the Country group have been defined. These default groups are 'South Africa' and 'Zimbabwe'.

    images/client-side-grouping_defaultgroups1.jpg
    Default group names are only available for the top level group.
  • The image shown below shows how a List that does not have any data for either South Africa or Zimbabwe would be rendered. Notice that the actual HTML shown for these two empty groups is defined by the JavaScript specified in the Javascript for HTML for default group property.

    images/client-side-grouping_defaultgroups2.gif
  • Javascript for HTML default group

    This property can be used to compute the HTML shown for an empty group.

    The JavaScript must return the HTML to display in the empty group. Your code can reference group - the name of the empty group. For example:

    return "There is no data for " + group
  • This will produce the result shown below:

    images/client-side-grouping_defaultgroups2.gif
  • Classname for default groups

    One or more class names to apply to empty groups. By default, this property is blank.

  • Can collapse groups

    If enabled, groups can be collapsed and expanded. The method used to collapse/expand groups is defined by the Collapse mode (below).

  • Collapse mode

    The Collapse mode property specifies how groups are collapsed and expanded. They can either be collapsed/expanded through user interaction -- clicking/tapping the title or an icon -- or programmatically using JavaScript:

    Mode
    Description
    Title

    The user clicks anywhere on the title to collapse/expand the group.

    Indicator

    The user must click an icon to collapse/expnd the group.

    Programmatic

    Groups are only collapsed or expanded using JavaScript -- see the A5.ListBox.setGroupCollapse method.

    This property is only available if Can collapse groups has been enabled.

  • Collapse icon

    The icon shown when the group is collapsed.

    This property is only available if Can collapse groups has been enabled.

  • Expand icon

    The icon shown when the group is expanded.

    This property is only available if Can collapse groups has been enabled.

  • onCollapse function

    Optional JavaScript to execute when a group is collapsed. Your JavaScript can reference the group variable, which contains the group that was collapsed. For example:

    if (group == "Argentina") {
        alert("Argentina has been collapsed.");
    }

    This property is only available if Can collapse groups has been enabled.

  • onExpand function

    Optional JavaScript to execute when a group is expanded. Your JavaScript can reference the group variable, which contains the group that was collapsed. For example:

    if (group == "Argentina") {
        alert("Argentina has been expanded.");
    }

    This property is only available if Can collapse groups has been enabled.

  • Initial display - collapse all

    The Initial display - collapse all, if checked, will render the List with all groups collapsed. Exceptions can be added for groups. See Exceptions - Initially collapsed groups and Exceptions - Initially expanded groups below.

    This property is only available if Can collapse groups has been enabled.

  • Exceptions - Initially collapsed groups

    If Initial display - collapse all is unchecked, the Exceptions - Initially collapsed groups property can be used to specify a set of groups that are collapsed when the List is initially rendered. The collapsed groups are specified as a list of group values. For example, if the List is grouped by COUNTRY, you could specify that the "Spain", "France", and "Germany" groups are collapsed on initial load of the List as follows:

    Spain
    France
    Germany

    This property is only available if Can collapse groups has been enabled and Initial display - collapse all is disabled.

  • Exceptions - Initially expanded groups

    If Initial display - collapse all is checked, the Exceptions - Initially expanded groups property can be used to specify a set of groups that are expanded when the List is initially rendered. The expanded groups are specified as a list of group values. For example, if the List is grouped by COUNTRY, you could specify that the "Brazil" and "Denmark" groups are expanded on initial load of the List as follows:

    Brazil
    Denmark

    This property is only available if Can collapse groups has been enabled and Initial display - collapse all is enabled.

Videos

Client-side Grouping and List Navigator

Group breaks can be inserted into the List control. The group breaks can be 'server-side' group breaks, or 'client-side' group breaks. The advantage of 'client-side' group breaks is that they can be dynamically applied to the data in the List. That means you can easily switch from grouping the data by 'Lastname' to grouping by 'City', etc. You can also display summary values in the group headers and footer.

For lists that have group breaks (regardless of whether the group breaks were computed server-side or client-side), you can also display a List Navigator, which allows the user to easily scroll a long List.

In this video we give an overview of client-side group breaks and the List Navigator. Then, we go into depth on setting up client-side grouping using Action Javascript (to apply the group breaks after the List is initially rendered) and in the List definition itself (so that when the List is initially rendered, the group breaks are shown).

We also show how summary data can be inserted into a List header or footer.

Download Component

Aligning Summary Values with List Columns

The List control allows you to insert client-side group breaks in a List and to display summary values in the group headers and footers. In a columnar List layout you typically want to align these summary values with the appropriate List columns.

The genie in the Header/Footer builder make this easy to do. The genie generates a sample JavaScript function that you can easily modify.

Download Component