A form builder for the Apostrophe CMS.
To enable this module, just configure it in app.js
.
'apostrophe-forms': {}
Or, optionally add in an email-from field option to the configuration object. To send an email from a service like Postmark, this field needs to be specified, and should be done anyways to make it less spammy.
'apostrophe-forms': {
email: {
from: "First LastName <admin@email.com>"
}
}
Then add aposFormsMenu
to outerLayout:
{{ aposFormsMenu(permissions) }}
New forms are created via the "Forms" dropdown menu.
To insert a form on your site, just include the forms
widget in the controls
list for an area, or use an forms
singleton.
Changing the permitted form fields and other widgets in a form
Set the controls
option when configuring the module. This code recreates the default configuration:
'apostrophe-forms': {
controls: [
'textField', 'integerField', 'textareaField', 'selectField', 'radioField', 'checkboxField', 'checkboxesField', 'dateField', 'timeField',
'style', 'bold', 'italic', 'createLink', 'unlink', 'insertUnorderedList', 'insertTable',
'slideshow', 'video'
]
}
Including non-form-field widgets is a great way to dress up a form with explanatory material.
To add or remove controls
without overriding the entire option, use the addControls and removeControls configuration:
'apostrophe-forms': {
removeControls: ['video'],
addControls: ['customWidgetType']
}
Adding New Widget Types & Validation
Override widgets
or set the addWidgets
option when configuring the module. This code recreates the default configuration for the text field widget:
'apostrophe-forms': {
addWidgets: [
{
name: 'textField',
label: 'Text Field',
css: 'apostrophe-text-field',
schema: [
{
name: 'label',
label: 'Label',
type: 'string',
required: true
},
{
name: 'required',
label: 'Required',
type: 'boolean'
}
]
}
]
}
To add form validation to the new widget type, there are a couple of event emitters in place. To validate the field result value, use the sanitizeFormField
emitter, which is fired before array of results is created. This code recreates the checkbox value validation:
apos.on('sanitizeFormField', function($field, key, result, errors) {
if ($field.attr('type') !== 'checkbox') {
return;
}
if (!_.has(result, key)) {
result[key] = [];
}
if ($field.prop('checked')) {
var val = $field.attr('value');
result[key].push(val);
}
});
After the results array has been created, error validation can be added with the sanitizeForm` emitter. Again, this code recreates validation for the default checkboxes to ensure minimum and maximum conditions have been met:
apos.on('sanitizeForm', function($form, result, errors) {
$form.find('[data-forms-checkboxes]').each(function() {
var $field = $(this);
var min = $field.attr('data-forms-checkbox-min');
var max = $field.attr('data-forms-checkbox-max');
var name = $field.attr('data-forms-field-name');
if(min > 0 || max > 0) {
var checked = 0;
checked = result[name].length;
if((min && (checked < min)) || (max && (checked > max))) {
var message;
if (checked < min) {
message = 'Please select at least ' + min + ' checkboxes.';
} else {
message = 'Please select no more than ' + max + ' checkboxes.';
}
errors.push({
name: name,
message: message
});
}
}
});
});
Adding custom fields
Add or remove fields at the project level by passing in objects to the addFields
or removeFields
options array.
'apostrophe-forms': {
addFields: [
{
name: 'projectField',
label: 'Project Level Field',
type: 'string'
},
{
name: 'thankYouLabel',
label: 'Project-level Thank you Message',
type: 'string'
},
],
removeFields: ['thankYouBody']
}
Passing in a default field to the addFields
array, such as thankYouLabel
will override it at the project level.
Adding helper text to widget field schemas
By default, there is no helpText
schema in each widget field. By configuring help text in app.js:
'apostrophe-forms': {
helpText: true
}
Every widget schema now has an optional help field added to it. For instance, the default textField schema now looks like:
{
name: 'textField',
label: 'Text Field',
css: 'apostrophe-text-field',
schema: [
{
name: 'label',
label: 'Label',
type: 'string',
required: true
},
{
name: 'required',
label: 'Required for User Submission',
type: 'boolean'
},
{
name: 'help',
label: 'Help Text (optional)',
type: 'string'
}
]
}
Adding custom group fields
There are three default field groups: basicsTab, contentTab, thanksTab
. Add custom custom groups by setting the addGroups
option in app.js:
'apostrophe-forms': {
addGroups: [
{
name: 'projectTab',
label: 'Project Content',
fields: [
'projectField'
]
}
]
}
To remove or override the default group fields use the removeGroups
configuration:
'apostrophe-forms': {
removeGroups: ['contentTab']
}
What happens when forms are submitted
When a form is submitted the content is saved to the aposFormSubmissions
collection, and if an email address was entered when creating the form, it is also delivered to that email address.
The long-term goal is to provide a handy interface for exporting past submissions in CSV format. However the module is already quite useful in any context where submission by email is acceptable, you don't mind building your own tools to export from aposFormSubmissions
, or you plan to override as described below.
Running your own code when a form is submitted
Subclass the module and override the afterSubmit
method which is provided for this purpose.
Changelog
0.5.3: fields now have a fieldId
which will improve CSV export (however, not saving yet). The next minor version will be a bc break in the way content is saved in the collection.
The forms widget now shows only the selected form, not all of them!