The form is one of the most important building blocks of an Appivo application. You can think of a form as a bridge between the user interface and the database. The form holds data for a specific record in the database, the record may or may not already exist in the database.
The form must be bound to a model so that the system knows what attributes are expected to be filled in and how they should be validated. A form can be loaded with a specific record or it could start out empty if a new one is to be created. When the form is submitted the record is written to the database – a new record will be created and an existing record will be updated.
As mentioned earlier – the form is a bridge and what we just described is the database end of this bridge, the other end is how the form allows widgets to be connected to the individual attributes of the record. For instance, a TextField can be connected to a String-attribute of a form – that TextField will then represent the value of that particular attribute, of the record loaded into the form.
In a similar fashion some widgets can represent a relationship, a set of related records, and thus being able to connect to a relation that the record has, again via the form. Examples of such widgets are the DataGrid and the Chart.
Lets go over an example to illustrate these concepts. We are building an application for handling orders and we have an initial data model that looks like this:
We have just two models – Customer and Order, a Customer can have many Orders and an Order belongs to exactly one Customer. In our simple example here these models just have a very minimal set of attributes. To illustrate how forms can be used we will create two views – one for creating a Customer and one for viewing a Customer and its list of Orders.
Creating or editing a record
It is possible to auto-generate a view for this purpose but we will build it from scratch so that you will understand the inner workings of how the view is connected to forms and widgets.
Start with creating a view with an appropriate name. Choose to use a blank template.
Add a form and connect it to the Customer-model. You will find the forms tab in the right panel of the builder. Here you will see a list of all the forms in the current view. Click the “Add form” button to add our Customer-form.
You will need to name the form and you must pick what model to connect it to. There is a concept of parent and child forms as well, we will discuss that later.
Once you’ve added the form you can go ahead and add some widgets to your view. Our Customer-model has only two attributes – one for the name and one for the customer-number. Drag out a TextField-widget – the widget-editor will open up and it should’ve automatically connected itself to the Name-attribute of the Customer-form.
Place the widget and then do the same with a NumberField – it will auto-connect to the CustomerNumber-attribute. After doing this and perhaps adding some labels your view should look something like this:
Finally we would need a way to submit our form. Lets add a button for that, just drag out a Button-widget:
Change the label to “Submit” and the click on the events tab, we must now declare what should happen if the button is clicked:
Click “Add” on the Click-event to add an event handler. You will get a scripting dailog, looking like this:
Scripts can be declared in a number of ways, the simplest one being using QuickActions. Click the Action-select and pick the “Submit form”-action, this will add some more fields and you will need to select which form to submit, pick your Customer-form. This is it, you have now created a view that can be used for creating, editing and even simply viewing a record.
The model we created earlier has a relationship between Customer and Order, a Customer can have many Orders. What if we wanted to display a list of all the Orders that a customer have placed, could we do that in a simple way ?
The answer is of course yes. Just like some widgets can be connected to model-attributes there are other widgets that can be connected to relationships. The DataGrid-widget is often used to display lists of records and can easily be connected to a relationship. Drag out a DataGrid and drop it on your canvas, it will attempt to connect to a relationship. You should see something like the below screen:
The system will now automatically load and display any related orders when this view is opened.
DataGrids even support inline editing of records (that needs to be enabled on a per column-basis, see the DataGrid documentation).
Navigation and forms
When opening a view or a dialog one may provide three arguments:
- The name of the user interface
- The name of the view
- The ID of a record to open
Here’s a concrete example:
The record-ID is optional, if it is passed it will be interpreted as the ID of a record to be loaded in to the views root-form. The root-form is either the first form declared, or the form that is the parent of the other forms. If you open a view passing in a record ID the form will get populated and all widgets connected to it will display the values of the attributes they are connected to. If the user makes changes to these values they will get persisted once the form is submitted.
In a similar fashion, if one opens a view with a form without passing a record ID no record can be loaded and we will be starting with an empty slate. In this case the widgets will display the default values of the attributes they are connected to, if any. Submitting such a form will result in the creation of a record.
Parent & child forms
Just as the models form a hierarchy derived from their relationships forms can mimic those. For example if we want create a view where we create two related records, say Customer and Order, in one go – we could do so by creating two related forms:
Keep in mind that a form can only every display the contents of a single record – and notice here that our relationship between Customer and Order allows a Customer to have many Orders. So with forms declared as in our diagram above we could represent a specific Customer with one specific Order. If we would want to display a Customer and all his Orders we would need to the relationship Order not to a Form but to a widget capable of display a collection of records, such as the DataGrid.
As you connect widgets to a form the platform will automatically load related records as needed. Sometimes however there are cases where the platform cannot “see” what additional related records you need (it could that you wish to display them using an HTML-widget for instance, or maybe you just need them for a computation). For these cases you can configure the form to forcefully load these required relations, that is done via the form-editor:
Notice that you can traverse relations here forcing an entire hierarchy of records to be loaded. This should be done with care and only if truly needed as it may increase the load time of your view.