Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Status
colourBlue
titleSINCE VERSION 4.0

Table of Contents
minLevel1
maxLevel3
outlinefalse
typelist
printablefalse

What is the Forms Framework?

The PIPEFORCE Forms Framework is a Forms framework which allows you to declaratively create and design data entry and data preview web forms without programming knowledge required.

The form framework works with the MVC pattern (= model, view, controller) which separates data, view and logic parts from each other.

In order to cover this pattern and to create such a form in PIPEFORCE, you need these JSON documents in your app:

  • Model: Form ModelData
    This optional JSON contains the values to initially be displayed in the form and the values which result from the form submit (the data).

  • Model: Form Schema
    This is a JSON Schema and describes the fields (= model) of your form (the data structure).

  • View: Form Config
    This JSON brings together all parts and defines the layout of your form (the look & feel and position of the fields).

...

  • Controller: Pipeline
    Finally, you create a pipeline that listens to the form submit. After such a submit, the pipeline gets called and can handle the form submit. It can further process the submitted data.

The model and view documents are loaded by the form generator implemented in the portal. It will render and show a form to the user based on the input documents:

Drawio
mVer2
zoom1
simple0
zoominComment10
inCommentcustContentId02545909774
pageId2545451358
custContentIdlbox25459097741
diagramDisplayNameUnbenanntes Diagramm-1690349147346.drawiolbox1
contentVer23
revision23
baseUrlhttps://logabit.atlassian.net/wiki
diagramNameUnbenanntes Diagramm-1690349147346.drawio
pCenter0
width819
links
tbstyle
height631.5

After the user has edited the form and clicked the submit button of the form, the form fields and their values will be rendered to a JSON document called the “form output model” (output data). This model is then stored to the output location, which is typically a as property in the property store.

The property store then fires a property.created event. A pipeline can then listen to this property.created event in order to event and handle the form submit controller logic accordingly. For this, also see how to create an event listening pipeline, here: Events .

Let’s have a look to all of these parts step by step below.

The Form Data (Model)

The Form Model Data is a JSON document which provides the data to be displayed in the form.

It is belongs to the central “model” part of the MVC form framework: .

The whole form framework is about loading this model data (A), displaying it in a form (B), validating it, merging copying the data values from the form back to the model fields into the output data (C) and storing the final model to some target sinkoutput data to the property store by default. The structure of the input data and output model JSON document data is always defined by the same Form Schema (D):

Drawio
mVer2
zoom1
simple0
inComment0
custContentId2546040833
pageId2545451358
lbox1
diagramDisplayNameUnbenanntes Diagramm-1690358780619.drawio
contentVer2
revision2
baseUrlhttps://logabit.atlassian.net/wiki
diagramNameUnbenanntes Diagramm-1690358780619.

...

drawio
pCenter0
width661
links
tbstyle
height485

The Input

...

Data (initial form data)

There can be an optional input form modeldata (A), which is the data to be shown initially to a form when it gets loaded. This input data is provided as a JSON document. For example, in case data will must be loaded from a database in order to edit it in the form, then this data from the database will be converted to JSON and will become the input model data to the form. The model input data structure must comply with the Form Schema (D).

Here is an example of such an input data JSON:

Code Block
languagejson
{
  "firstName": "Max",
  "lastName": "Huber",
  "age": 48,
  "cv": {
    "name": "cv-max-huber.pdf",
    "contentLength": 243,
    "contentType": "application/pdf",
    "contentEncoding": "base64",
    "content": "YWRzYXNhc2ZzZCBmc2R.....BkZmRzZmRzIHNzc2Rmcw=="  
  }
}

The input form model data can be provided loaded to the form framework in two different ways:

  • Via the input configuration attribute in the Form Config (see below) which is a custom uri pointing to the data to be loaded and converted to the input form model format. This can be a custom uri which

    points

    can point to a

    property in

    • … property to be loaded from the property store (for . For example:
      "input": "$uri:property:global/app/myapp/data/mydata")

    • a pipeline which will prepare be executed and returns the input form model (for example data. For example:
      "input": "$uri:pipeline:global/app/myapp/pipeline/mypipeline" or a

    • command which will return such a model (for example be executed and returns the input data. For example:
      "input": "$uri:command:my.command").

  • Via HTTP request parameters whereas each request parameter name must have the same name as the form field. For example a request parameter like this ?firstName="Max" will set the value Max on a field with id firstName. Also complex (nested) elements can be set this way in JSON format whereas the this value must be url encoded. In case there exists already a form input modeldata, then a request parameter can overwrite values from this model data afterwards. In case no field with this id iname from request exists, nothing happens.

In case a form has no input model data (which means input config is set to null or doesn't exist and no request parameter was set), then it will be an empty form which can be initially filled with data from the user.

Here is an example of such an input model to a form containing different types of data:

...

.

...

The Output

...

Data

After the user has clicked the submit button of the form (B), the fields of the form will be written back into a JSON document which is then the output form model data (C) which also must comply with the Form Schema (D).

This output form model data finally will be send to the target sink which is configured by the output parameter in the Form Config. This is typically a location in the property store. For example:
"output": "$uri:property:global/app/myapp/data/mymodel".

The JSON format of the output is the same as the format of the input model and complies must comply with the Form Schema.

The Form Schema (Model)

For more details go to: /wiki/spaces/DEV/pages/2482176001

The Form Schema document describes the fields' structure of a Form Model using the JSON Schema specification. For example the type of the field, validation rules, the title and how to display such a field in the form (for example as text field or number picker?).so on.

It belongs to the “model” part of the MVC form framework.

Here is an example of such a Form Schema JSON:

Code Block
languagejson
{
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string",
      "description": "Add our first name here",
      "minLength": 2
    },
    "lastName": {
      "type": "string"
    },
    "age": {
      "type": "integer"
    },
    "cv": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "contentLength": {
          "type": "number"
        },
        "contentType": {
          "type": "string"
        },
        "contentEncoding": {
          "type": "string"
        },
        "content": {
          "type": "string"
        }
      }
    }
  },
  "required": [
    "firstName",
    "lastName",
    "age"
  ]
}

The Form Config (View)

For more details go to: /wiki/spaces/DEV/pages/24821760012482798727

The Form Config

...

The Form Config is the central configuration file of a form.

It belongs to the “view” part of the MVC form framework.

It defines things like:

  • How the fields of a form must be positioned in the view (= the layout).

  • Where to load and write the form model from / to.

  • Where to load the schema of the form from.

  • What to do, after a form has been submitted.

  • Title, description, type and other settings of the form.

For more details go to: /wiki/spaces/DEV/pages/2482798727

In order to define a form in PIPEFORCE, you need a JSON schema and the form configuration.

...

The JSON schema (also called the “object schema”) defines the structure of a dataset and “tells” the form which fields to display that a user can fill-out. Learn more about the JSON Schema in this chapter: Schema & Objects.md).

The input data is used in case an existing dataset needs to be edited. The form is pre-filled with some data, so the user can make changes, and save again.

After a form was submitted, the output is automatically saved into the property store. So, you do not need to care about where the data is stored.

After this, an event is send, depending on what the form did with an object/property:

  • property.created: If a new object was created by submitting the form.

  • property.changed: If an existing object has been changed by submitting the form.

  • property.deleted: If an existing object has been deleted by submitting the form.

Any pipeline can then listen to such events using the command event.listen, and do additional logic afterwards using the submitted data. For example, sending notification emails, doing data integration, or alike. Such a pipeline could look like this:

Code Block
pipeline:
  - event.listen:
      key: "property.created"
  - ...

The glue of all this is the form configuration, which defines how the form should use the schema and display the fields. Additionally, any information about layouting a form’s fields goes into the form configuration.

How to handle the form output

By default, after a submit, the data of a form is automatically stored into the property store under a new property having this key path:

Code Block
global/app/<APP>/object/<NAME>/v1/instance/<UUID>

Where <APP> is the name of your app. <NAME> is the name of the object, the schema of the form belongs to, and <UUID> is a unique identifier for the dataset, created automatically for each new entry.

In the person example above, after a form is submitted with new data, this data could be stored in a new property with a key path which looks like this:

...

Here is an example of such a Form Config:

Code Block
languagejson
{
  "title": "Add person",
  "description": "Add a new person",
  "schema": "$uri:property:global/app/myapp/object/person/v1/schema",
  "input":"$uri:property:global/app/myapp/object/person/v1/instance/133a11f667b07f3c-8011e006-47d34bec-b6eb-1376cca5e6b6

The output of the form, which is the value of this instance property, could look like this:

Code Block
{a790-ef25b9fe97df",
  "output": "global/app/myapp/object/person/v1/instance/${var.property.uuid}",
  "firstNamelayout": "Bart", {
    "lastNameorientation": "Simpsonvertical",
    "ageitems": 12,[
      {
      "genderorientation": "malehorizontal",
  } 

You can easily query existing instances using the command property.list. For example, using the pi tool:

Code Block
pi pipeline uri "property.list?filter=/**/global/app/myApp/object/person/v1/instance/*"

In case you have more than one object type in your app, and you want to list all instances of all objects of your app, you could use this list filter:

Code Block
pi pipeline uri "property.list?filter=/**/global/app/myApp/object/*/v1/instance/*"

Note: Be careful, since in this example it would return the instances from all objects of myApp. Learn more about filtering properties from the property store in this section Property Store.

How to load and edit input data in a form

After a form has been submitted, for each submit, a new instance property is created in the instance path of an object, for example:

Code Block
global/app/myApp/object/person/v1/instance/133a11f6-8011-47d3-b6eb-1376cca5e6b6

In case you want to edit such an instance, first you need to load it into the form using the request parameter input, when calling the form:

Code Block
?input=property.list?filter=global/app/myApp/object/person/1/instance/133a11f6-8011-47d3-b6eb-1376cca5e6b6

Now, form renders initial values from the input, but will still save into new global/app/myApp/object/person/v1/instance/{somenewrandomuid}

To save to the same record, additional form output parameter needs to be added to overwrite default behaviour.

Code Block
...&output=global/app/myApp/object/person/v1/instance/133a11f6-8011-47d3-b6eb-1376cca5e6b6

This all is automatically done for you in case you call a form using a list.

The form configuration

The last step to create and configure a new form is to create a form configuration file. This is a configuration file in JSON format, which defines important attributes of a form like its title or layout information.

Here’s an example how such a file could look like:

Code Block
{
  "title": "Person",
  "description": "The person form.",
  "schema": "property.list?filter=global/app/myApp/object/person/v1/schema",
  "output": "global/app/myApp/object/person/v1/instance/%23%7Bvar.property.uuid%7D"
}

The title defines the title of the form to be displayed in the web ui, for example.

The description is optional and describes the intention of the form.

The schema defines a command which is called to retrieve the JSON schema for this form.

The output defines the path in the property store where to store the data. The part %23%7Bvar.property.uuid%7D is the url encoded version of #{var.property.uuid}, which is a PE to return the uuid of the property to form its path.

Note: In version >= 7.0, it is no longer required to specify the attributes schema and output, since the form will automatically detect these values.

By default, the form configuration is stored inside the form folder as a JSON file:

Code Block
global/app/myApp/form/personForm

After you have created a JSON Schema file and a form configuration, and pushed them to the property store using pi push, the form is listed in the forms section and is ready to be used.

For all schema properties, there is a web input control rendered - filed. By default, all fields are displayed using the default - single column layout i.e. every field in its own row.

To reach custom layout, fields behaviour, file uploads, custom buttons, and more, additional layout attribute of the form configuration file needs to be used. Layout uses different approach to define which fields to show. Only fields referenced in this structure are rendered. For details, see following sections.

Change orientation of form fields

You can change this default by configuring orientation of the layout in the form configuration.

See this section for more details: Form - Orientation

Change appearance of form fields

Besides the orientation (vertical, horizontal) of form fields, the appearance (color, border, icons, aso) can also be changed inside the layout section.

See this section for more details: Form - Look & Feel

Custom buttons

Replacements for the default Submit button can be defined by render attribute of boolean field in the layout section.

See this section for more details:Form - Buttons

File upload

In the layout section, it is also possible to configure the set of schema properties defining form upload.

...

items": [
        {
        "field": "firstName"
        },
        {
        "field": "lastName"
        }]
      },
      {
        "field": "age"
      },
      {
        "field": "cv"
      }
    ]
  }
}

The Pipeline (Controller)

For more details go to: Form Listening Pipeline (Controller)

After the form has been submitted by the user, the output data will be stored in the property store and then a property.created or property.updated event will be fired by the property store.

A pipeline can listen to such an event and then further process the form submit.

The pipeline belongs to the “controller” part of the MVC form framework.