Formify Language

This chapter gives an overview of formify’s language.

Application

The App is the root of every formify file. It can contain a Data Model and a View Model. It also has a unique name. The most simple form of an app with a data model and a view model looks like this:

app MyApp {
    model {}
    view {}
}

Data Model

The data model contains all the entities and custom data types of your app. A data model with a single Entity looks like this:

Entity

TBD

model {
    entity Person {}
}

Property

Each Entity can contain a list of properties. A property declaration starts with the optional keyword prop, a unique name, followed by a colon and a Type. The code generator uses this data type to decide which kind of control to generate. The most basic property declaration looks like this:

entity Person {
    prop firstname : string
}

Constraints

There is also the option to add constraints to a Property. This information is used by the generator to add specific form validation to the controls. The following shows an example with some predefined constraints:

entity Person {
    firstname : string required
    email : string email required
    age : number min(18)
}

The list of available constraints depends on the Type. Currently, the following constraints are built in:

string

  • required() : marks this field as required

  • lowercase() : only allows strings written in lowercase

  • uppercase() : only allows strings written in uppercase

  • min(limit : number) : defines the minimum length of the string

  • max(limit : number) : defines the maximum length of the string

  • length(length : number) : defines the exact length of the string

  • email() : built-in regular expression check for email

  • url() : built-in regular expression check for urls

number

  • min(limit : number) : defines the minimum value of the number

  • max(limit : number) : defines the maximum value of the number

  • positive() : only allows positive numbers

  • negative() : only allows negative numbers

  • lessThan(max : number) : only allow values that are less than the specificed value

  • moreThan(max : number) : only allow values that are more than the specificed value

date

  • min(limit : number) : defines the minimum value of the date

  • max(limit : number) : defines the maximum value of the date

array

  • min(limit : number) : defines the minimum length of the array

  • max(limit : number) : defines the maximum length of the array

  • length(length : number) : defines the exact length of the array

Type

formify’s type system provides to following primitive types:

  • string

  • number

  • boolean

  • date

  • time

  • image

  • color

Those types can be used as property types, like this:

 entity Pet {
     prop name : string
 }

 entity Person {
     prop firstname : string
     prop age: number
     prop adult : boolean
     prop birthday : date
     prop photo : image
     prop favColor : color
     prop pets : array<Pet>
}

Relationships

Entities may have relationships to other entities. A one-to-one relationship can be specified by using an Entity as a type within a property declaration like shown in this example:

entity Person {
    address : Address
}

entity Address {
    street : string
    city : string
}

Many-to-One relationships can be specified with the use of an array:

entity Student {
    courses : array<Course>
}

entity Course {
    name : string
}

Inheritence

Formify supports inheritance with the extends keyword. Entity can extend other entities to reuse fields. Multi-inheritence is also possible.

entity Person {
    firstname : string
    lastname : string
}

entity Student extends Person {
    studentId : number
}

entity Professor extends Person {
    professorId : number
}

Enumeration

You can add Enumerations with the enum keyword like this:

enum Gender {MALE, FEMALE}
entity Person {
    gender : Gender
    firstname : string
    lastname : string
    }

View Model

Formify provides a view model that you can use to define different view components. Currently supported types are Form, Composite, Tabs, Wizard, Collection and Master - Detail.

A simple application with a view model that contains a Form looks like this:

Open in Formify

app PersonManagement {
    model {
        entity Person {
            firstname : string
            lastname  : string
        }
    }
    view {
        @Root
        form PersonDetails {
            entity Person
        }
    }
}
simple form

Note

The Form is annotated with the @Root annotation. This is used by formify as a pointer to the root component of the application. If no view component is annotated with @Root you will get a rendering error. If multiple components are annotated with @Root, they will be added to the application bar.

Form

The most simple form declaration only consists of a reference to the underlying Entity. If no form fields are defined, this is simply a shortcut that implicitly uses all Property of the Entity.

form PersonDetails {
    entity Person
}

If you do not want to display all the entities properties or want to fine-tune the form controls, you can explicitly define the form fields with the field keyword like shown in this example:

Open in Formify

app PersonManagement {
    model {
        entity Person {
            firstname : string
            lastname  : string
            secretKey : string
        }
    }
    view {
        @Root
        form PersonDetails {
            entity Person
            field FirstName : firstname
            field LastName : lastname
        }
    }
}

Note

You can navigate the Relationships with the . - operator: For example, if an Entity Person has a one-to-one Relationships to another Entity Address, you can reference the city in the form field with address.city:

Open in Formify

app PersonManagement {
    model {
        entity Person {
            address : Address
        }
        entity Address {
            city : string
        }
    }
    view {
        form AddressDetails {
            entity Person
            field city : address.city
        }
    }
}
_images/lang-view-model-form.png

Composite

Components are a great concept to split up a Form into different, reusable parts. Imagine having an Entity with a lot of properties, it might make sense to group some properties into a single Form. With Composites, you can group these Forms together to one composite form like this:

Open in Formify

app PersonManagement {

    model {
        entity Person {
            firstname : string required
            lastname : string
            city: string
            address : string
        }
    }
    view {
        @Root
        composite CompositePerson {
            entity Person
            parts
                PersonDetail,
                AddressDetails
        }

        form AddressDetails {
            entity Person
            field City : city
            field Address : address
        }

        form PersonDetail {
            entity Person
            field FirstName : firstname
            field LastName : lastname
        }
    }
}
_images/lang-view-model-composite-1.png

Composites also play together nicely with one-to-one Relationships. Like shown in this example, you can pass a reference to the AddressDetails part using the value keyword:

Open in Formify

app PersonManagement {

    model {
        entity Person {
            firstname : string required
            address : Address
        }
        entity Address {
            city : string
            street : string
        }
    }
    view {
        @Root
        composite CompositePerson {
            entity Person
            parts
                PersonDetails,
                AddressDetails value address
        }

        form AddressDetails {
            entity Address
        }

        form PersonDetails {
            entity Person
        }
    }
}
_images/lang-view-model-composite-3.png

Tabs

Tabs are a special kind of Composite. Each part is displayed in a seperate Tab.

Open in Formify

app PersonManagement {

    model {
        entity Person {
            firstname : string required
            lastname : string
            city: string
            address : string
        }
    }
    view {
        @Root
        tab-composite CompositePerson {
            entity Person
            parts
                PersonDetail,
                AddressDetails
        }

        form AddressDetails {
            entity Person
            field City : city
            field Address : address
        }

        form PersonDetail {
            entity Person
            field FirstName : firstname
            field LastName : lastname
        }
    }
}
_images/lang-view-model-tabs-1.png

Wizard

A Wizard is also a special kind of Composite. Each part is displayed as a seperate step in a multi step wizard.

Open in Formify

app PersonManagement {

    model {
        entity Person {
            firstname : string required
            lastname : string
            city: string
            address : string
        }
    }
    view {
        @Root
        wizard CompositePerson {
            entity Person
            parts
                PersonDetail,
                AddressDetails
        }

        form AddressDetails {
            entity Person
            field City : city
            field Address : address
        }

        form PersonDetail {
            entity Person
            field FirstName : firstname
            field LastName : lastname
        }
    }
}
_images/lang-view-model-wizard-1.png

Collection

A collection shows a list of entities.

Open in Formify

app PersonManagement {

    model {
        entity Person {
            firstname : string
            lastname : string
            city: string
            address : string
        }
    }
    view {
        @Root
        collection PersonCollection {
            entity Person
            field name : firstname
            field lastname : lastname
        }
    }
}
_images/lang-view-model-collection.png

Grid

A Grid is a special type of collection. A Grid shows a collection of entities with different columns. The Grid can be configured with @Pagesize and @Sortable Annotations

Open in Formify

app PersonManagement {

    model {
        entity Person {
            firstname : string
            lastname : string
            city: string
            address : string
        }
    }
    view {
        @Root
        @Pagesize(pageSize = 5)
        @Sortable
        grid PersonCollection {
            entity Person
            field name : firstname
            field lastname : lastname
            field city : city
        }
    }
}
_images/lang-view-model-grid.png

Master - Detail

A maaster detail is a combination of a Collection for the master part and a form for the detail part.

Open in Formify

app PersonManagement {

    model {
        entity Person {
            firstname : string
            lastname : string
            city: string
            address : string
        }
    }
    view {
        @Root
        @Alignment(Align.Horizontal)
        master-detail Application {
            entity Person
            master PersonCollection
            detail PersonDetails
        }

        collection PersonCollection {
            entity Person
            field name : firstname
        }

        form PersonDetails {
            entity Person
            field name : lastname
            field lastname : lastname
            field city : city
        }
    }
}
_images/lang-view-model-master-detail.png