• ✓ Rendered into HTML

  • ❏ Rendered into PDF

  • ❏ Rendered into Mail

  • ❏ Rendered into CSV

screenshot dsl filter
Figure 1. Filter applied to a table, from Filter Sample Code 1

Filter DSL is always associated with a Table or a Chart. A bloc cannot contain only a filter.

Code Sample

Filter Sample Code 1
UiFilterSpecifier f = new UiFilterSpecifier()           (1)

f.ui User, {                                            (2)
    section "User", {                                   (3)
        filterField u.username_                         (4)
        filterField u.lastName_
        filterField u.firstName_
        filterField u.manager_, u.manager.username_     (5)
        filterField u.mainSubsidiary_
        filterField u.allowedSubsidiaries_
        filterField u.enabled_
        filterFieldExpressionBool "My Team",            (6)
            new FilterExpression(u.selfObject_,
  1. Create the filter

  2. pass the object class and the closure containing the specifications of the filter via the ui method

  3. Create a section labeled "User"

  4. Add field to the filter, note the underscore at the end of the field name

  5. if the field is an object, pass an array with all steps necessary to target the field you want to filter on

  6. filterFieldExpressionBool allow more complex filter

Filter Sample 2
UiFilterSpecifier f = new UiFilterSpecifier()

CmsImage i = new CmsImage(cmsPage: new CmsPage())

f.ui CmsImage, cmsPage ? [id:] : null, { (1)
    section "Image", {
        filterField i.hide_
        filterField i.filePath_
        filterField i.imageType_
    section "Origin", {
        filterField i.cmsPage_, i.cmsPage.name_
        filterField i.cmsPage_, i.cmsPage.subsidiary_
        filterField i.cmsPage_, i.cmsPage.pageLayout_
        filterField i.cmsPage_, i.cmsPage.pageType_
  1. We can pass optional parameters to the action

DSL Symbols Hierarchy

Figure 2. Symbols hierachy diagram for Filter DSL

DSL Elements


  • ui: one version allows passing additional parameters to the filter action (see Filter Sample 2)


  • filterField: add object field to be transmitted to the filter action

  • filterFieldInverse: filter objects if another object points to it.

  • filterFieldExpressionBool: allows changing where clause in the filter action by using FilterExpression, last parameter is the default value.


  • section: add a graphical filter section


  • ✓ Rendered into HTML

  • ✓ Rendered into PDF

  • ✓ Rendered into CSV

Code Sample

The right part of the preview corresponds to the DSL sample below. The filter is on the left of the image, see DslDescriptions/FilterDSL.html for the corresponding code.

The table has pagination, it is sorted by default against Date Created column, all columns are sortable except Picture and Roles. One column can contain multiple cells. Date Created is empty for old users, and manager cells are also empty for some users.

Table Sample: Header, Rows and a default sorting
new UiTableSpecifier().ui {
    User u = new User(manager: new User(), enabled: true)
    header {                                                (1)
        if (!hasSelect) {
            fieldHeader tr('picture.header.label')          (2)
        column {
            sortableFieldHeader u.username_                 (3)
            sortableFieldHeader u.dateCreated_
        column {
            sortableFieldHeader u.subsidiary_
            sortableFieldHeader u.manager_, u.manager.username_
        column {
            sortableFieldHeader u.lastName_
            sortableFieldHeader u.firstName_
        column {
            fieldHeader tr('default.roles.label')
    boolean canSwitchUser = crewSecurityService.canSwitchUser()

    TaackFilter tf = taackFilterService.getBuilder(User)
            .setSortOrder(TaackFilter.Order.DESC, u.dateCreated_)

    iterate(tf) { User ru ->                                (4)
        row {                                               (5)
            boolean hasActions = crewSecurityService.canEdit(ru)
            if (!hasSelect) {
                rowColumn {
                    rowField attachmentUiService.preview(ru.mainPicture?.id)
            rowColumn {
                rowAction ActionIcon.SHOW * IconStyle.SCALE_DOWN,
                        CrewController.&showUser as MC,
                if (hasSelect)
                    rowAction "Select User",
                        ActionIcon.SELECT * IconStyle.SCALE_DOWN,
              , ru.toString()
                else if (hasActions) {
                    rowAction ActionIcon.EDIT * IconStyle.SCALE_DOWN,
                        CrewController.&editUser as MC,
                    if (canSwitchUser && ru.enabled)
                        rowAction ActionIcon.SHOW * IconStyle.SCALE_DOWN,
                            CrewController.&switchUser as MC,
                    else if (canSwitchUser && !ru.enabled) {
                        rowAction ActionIcon.MERGE * IconStyle.SCALE_DOWN,
                            CrewController.&replaceUser as MC,
                        rowAction ActionIcon.DELETE * IconStyle.SCALE_DOWN,
                            CrewController.&deleteUser as MC,
                rowField ru.username_
                rowField ru.dateCreated_
            rowColumn {
                rowField ru.subsidiary_
                rowField ru.manager?.username
            rowColumn {
                rowField ru.lastName_
                rowField ru.firstName_
            rowColumn {
                if (hasActions && !hasSelect)
                    rowAction ActionIcon.EDIT * IconStyle.SCALE_DOWN,
                        CrewController.&editUserRoles as MC,
                rowField ru.authorities*.authority.join(', ')
  1. Header part of the table specifications

  2. Non-sortable field header

  3. Sortable field header

  4. iterate, specifying sort, paginate and filtering

  5. row DSL

ActionIcon can be modified by ActionIconModifier

Table style is specified by Style an optional parameter on row or rowField element.

DSL Symbols Hierarchy

Figure 3. Symbols hierachy diagram for Table DSL