Enabling Taack framework

In order to be able to display an object into a form or a filtered table, this class has to be annotated with the @TaackFieldEnum annotation.

When @TaackFieldEnum annotation is specified on a class, additional symbols are generated by the framework. Those symbols terminate with an underscore and are used with the different DSLs.

Regular Classes Case

Enabling a Regular Classe code Sample
@GrailsCompileStatic                                    (1)
@TaackFieldEnum                                         (2)
final class QueryParameter implements Validateable {    (3)
    Currency currency = Currency.EUR
    Short monthStart = 1
    Short monthStop = 12
    Set<Subsidiary> subsidiaries
    String sellerNamePattern
    String productNameOrCodePattern
    String customerNameOrCodePattern
    Value itemValue
    ItemRange range
    Integer yearStart
    Integer yearStop = Calendar.instance.get(Calendar.YEAR)

    static constraints = {                              (4)
        itemValue nullable: true
        range nullable: true
        monthStart min: 1, max: 12
        monthStop min: 1, max: 12, validator: {         (5)
            queryParameter, monthStop ->
            if (monthStop < queryParameter.monthStart)
                return "monthStop.greater.or.equals.to.monthStart"
        }
    }
}
  1. Good practice to add GrailsCompileStatic annotation

  2. The annotation enabling AST Transformation

  3. Class has to implement Validateable to support constraints (not necessary for Domain Classes)

  4. Constraints definition

  5. Validation can be a closure returning a translation key.

This sample code shows a standard class (i.e., not defined into the domain directory) being enabled to be used in the Taack framework. It cannot be saved and retrieve or listed, since it is not a persistent domain class.

It has to implement the Grails Validateable traits.

Domain Classes Case

Enabling a Domain Class code Sample
@GrailsCompileStatic
@TaackFieldEnum
class CmsPage {                             (1)
    Subsidiary subsidiary
    Date dateCreated
    Date lastUpdated

    User userCreated
    User userUpdated

    Boolean published = false

    CmsPageLayout pageLayout = CmsPageLayout.NO_SIDE_COLUMN
    CmsPageType pageType

    String name

    Map<String, String> urlPart
    Map<String, String> title
    Map<String, String> hatContent
    Map<String, String> bodyContent

    CmsImage mainImage
    CmsVideoFile mainVideo

    Set<CmsImage> bodyImages

    static hasMany = [
            bodyImages: CmsImage
    ]

    static mappedBy = [bodyImages: "none"]

    static constraints = {
        name nullable: true
        urlPart nullable: true
        title nullable: true
        hatContent nullable: true
        bodyContent nullable: true, widget: 'textarea'
        mainImage nullable: true
        mainVideo nullable: true
        bodyImages nullable: true
    }

    static mapping = {
        autoTimestamp true
    }
}
  1. No need to implement Validateable in case of domain class

Domain classes are treated as first-class citizens within the Taack framework. They can make use of the advanced functionalities provided by the TaackSaveService.

Object Manipulation for Domain Classes

Listing Objects in Tables

Table DSL add iterate symbol that allows to display objects listing:

TaackFilter tf = taackFilterService.getBuilder(User)        (1)
        .setSortOrder(TaackFilter.Order.DESC, u.dateCreated_)
        .setMaxNumberOfLine(20).addFilter(f).build()

iterate(tf) { User ru ->                                    (2)
    row {                                                   (3)
    }
}
  1. Specify filters, securing lists of objects, along with some display constraints

  2. Iterate over this TaackFilter, with a row closure

  3. Draw the row …​

def objects = taackSimpleFilterService.list(
                ObjectClass, numberOfObjectReturned)
objects.aValue // list of objects queried. Not all objects are returned (see second parameter)
objects.bValue // total number of objects that can be reached by the query

Passing the filter to the list method allows to restrict the query for security purposes.

Saving Objects via Form DSL and show errors

In order to save a new object, or a modified object (we will see security considerations later), just call the following method into the form target action:

taackSaveService.saveThenRedirectOrRenderErrors(User, this.&index)

There are 3 possible scenarios:

  • If the object is valid and the user possesses the required credentials to manipulate it, the browser will be redirected to the action specified in the second parameter.

  • If the object contains invalid fields, the form will be updated to highlight the problematic fields (refer to the image below)

  • Either the user has no credential to process the object, an error is displayed

Here, index is the action to go in case of success, User is the object class.

screenshot form validation
Figure 1. Case the form is not valid, feedback to the user. Note the errors reported are localized.