| Version | Date | Notes | By |
|---|---|---|---|
| 0.1 | 2017-02-22 | Initial release | JFM |
The document assumes that you already know what is a View-ViewModel and what is a repository
Aurelia forms are the quickest way to get your forms working since it automatically draws the form based on a simple configuration.
A form interface normally needs 4 files:
The model file will contain a simple class that will represent our form. This is done by having a property for each field in the form
So lets create the model file.
In the root directory of the module you are currently working, create a file inside the models folder (create it if it doesent exists alredy). The file name should cleary represent what the form is representing.
For this example lets assume we are creating a form to register types of actions, so we are naming the file action-type.js
First we need to import ao BaseModel class since every model needs to extend its functionalities.
import { BaseModel } from "wemake-modules/core/models/base-model"
Next create the model class and define the form fields as properties
export class ActionType extends BaseModel {
acronym = null;
name = null;
status_id = null;
}
You can add default values to the fields by atributing values to the properties, although this is highly discourage, because if you need to reuse the model elsewhere, you'll be stuck with this pre-defined values. There is a best way to do this on the form file as we will see later.
Example:
export class ActionType extends BaseModel {
acronym = 'ABC';
name = 'Default Name';
status_id = 1;
}
The form file will contain the form setting, things like the field type, size, label, etc..
First we need to import our model file
import { ActionType } from "../../models/action-type";
Next create a class named FormSchema ana add an atribute named modelDefaults The modelDefaults property is an object where you can add default values fo the model. This will reflect on the respective form field.
export default class FormSchema {
/**
* Model default values
*
* @type {{}}
*/
modelDefaults = {
status_id: 1
};
}
In this example the status_id will have a default of 1
Next create a method named model This method must instanciate the model, assign the default values and return it.
export default class FormSchema {
/**
* Returns a new instance of the model
*
* @returns {ActionType}
*/
model() {
let model = new ActionType();
model.assign(this.modelDefaults);
return model;
}
}
Create a method name schema and configure each field that will be available on the form. This method must receive the voewModel object from our ViewModel file (we will create this later)
Lets start just by configuring the acronym field.
export default class FormSchema {
schema(viewModel) {
this.acronym = {
type: 'text',
key: 'acronym',
label: 'form.field.acronym',
size: 2
};
}
| Part | Description |
|---|---|
| type | The type of the form field |
| key | The id and name of the field |
| label | The field label. Must be a translation slug |
| size | The column size (bootstrap size) of the field. |
Now let add the remaining fields
export default class FormSchema {
schema(viewModel) {
this.acronym = {
type: 'text',
key: 'acronym',
label: 'form.field.acronym',
size: 2
};
this.name = {
type: 'text',
key: 'name',
label: 'form.field.name',
size: 10
};
this.status_id = {
type: 'select2',
key: 'status_id',
label: 'form.field.status',
size: 4,
remoteRepository: viewModel.repository,
remoteSource: 'activeBooleanStatuses'
};
}
The name field is fairly straight forward to understand but the status fields, because it's a select2 (combo) we must add the remoteRepository and the remoteSource property setting. The remoteRepository is just the repository class that has all the methods that interacts with the backend. The remoteSource is the method that needs to be called to get the data needed to populate de select2 field.
After the fields are defined we need to add the actions buttons (Back, Reset and Submit) Since we are creating a standard form we just need to add a buttons object with two properties, type and viewModel
export default class FormSchema {
schema(viewModel) {
this.buttons = {
type: 'buttons',
viewModel: viewModel
};
}
The type just indicated that these are buttons, and we need to pass the viewModel so we can use it on the aurelia-forms implementation. This is the straight forward way to define our buttons, but this is only because we don't to have a different buttons configuration. If we need to add new buttons or only show some of the standard buttons or chnage it's configurations we have to change the buttons object configurations (we are going to discuss this later).
Now that everything is defined we just need to return an multidimentional array with all the fields and buttons. This array will control the order and placement of the fields accordingly to it's position on the array.
export default class FormSchema {
schema(viewModel) {
return [
[this.acronym, this.name],
[this.status_id],
[this.buttons]
];
}
This will draw a form with the acronym field on the first row, first column, the name field on the first row, second column. The status_id field on the second row, and the buttons on the last row.
The final file will look like this:
import { ActionType } from "../../models/action-type";
export default class FormSchema {
/**
* Model default values
*
* @type {{}}
*/
modelDefaults = {
status_id: 1
};
/**
* Returns a new instance of the model
*
* @returns {ActionType}
*/
model() {
let model = new ActionType();
model.assign(this.modelDefaults);
return model;
}
/**
* Returns form schema
*
* @param viewModel
*
* @returns {*[]}
*/
schema(viewModel) {
this.acronym = {
type: 'text',
key: 'acronym',
label: 'form.field.acronym',
size: 2
};
this.name = {
type: 'text',
key: 'name',
label: 'form.field.name',
size: 10
};
this.status_id = {
type: 'select2',
key: 'status_id',
label: 'form.field.status',
size: 4,
remoteRepository: viewModel.repository,
remoteSource: 'activeBooleanStatuses'
};
this.buttons = {
type: 'buttons',
viewModel: viewModel
};
return [
[this.acronym, this.name],
[this.status_id],
[this.buttons]
];
}
}
The ViewModel file is where the application logic (of this interface) is programmed
Since this is a standard form interface, we are using the default view file for the form as indicated on the ViewModel file section.
The file looks like this
<template>
<panel-group header-title.bind="headerTitle">
<schema-form alert.bind="alert" form-id.bind="formId" schema.bind="schema" model.bind="model" containerless></schema-form>
</panel-group>
<new-record if.bind="newRecordRoute" route.bind="newRecordRoute"></new-record>
</template>