mongoose-formulate
v2.0.0
Published
Mongoose plugins to faciliate dynamic form based input based on custom templates
Downloads
3
Readme
Mongoose Formulate
Mongoose Formulate is a package of 2 mongoose plugins that allow you to bake a programmable CMS into your existing applications. It's intended to be used to build a framework that allows dynamic creation of form templates that in turn structure input that is stored in entries.
What is it for?
If you need a system for allowing users of your application to define custom form templates based on common input formats and a flexible way to store data submitted against those templates, Formulate is for you. Think of it as a pluggable CMS. If your looking for a full-blown CMS solution then it's not for you. There is no UI component, everything is powered programmtically and the UIs for the fieldtypes, templates and forms must be implemented by you. This is by design.
How to use it
npm install mongooose-formulate
First you need to setup the template plugin:
// install the template plugin on an existing collection, or create a generic 'templates collection'
var mongoose = require('mongoose');
var formulate = require('mongoose-formulate')
var Schema = mongoose.Schema;
// the plugin only adds additional fields to your schema, so you can add
// specific custom schema fields as you wish. Name would be an obvious one
var schema = {
name: String
};
schema.plugin(formulate.templatePlugin);
var TemplateModel = mongoose.model('template', schema);
Next setup the entry plugin. This is where your form content will be stored. Because this is just a mongoose plugin you add it to any of your exisiting collections (giving your form content 'context') or create a generic entries collection for ultimate flexiblity.
var mongoose = require('mongoose');
var formulate = require('mongoose-formulate')
var Schema = mongoose.Schema;
var myExistingSchema = {
name: String,
created: Date
};
schema.plugin(formulate.entryPlugin);
var MyModel = mongoose.model('my-model', schema);
Once the two plugins are setup, you can start adding custom templates. Here is an example of a Resume template:
There is an explanation of the formGroups, fieldGroups and fields properties below.
TemplateModel.new({
name: Resume Template',
template: {
formGroups: [{
label: 'Personal Information',
description: 'Enter you personal information for your Resume',
// repeatable: 1, will default to 1 when not specified
fieldGroups: [
{
fields: [
{
label: 'First Name',
fieldtype: 'text'
},
{
label: 'Last Name',
fieldtype: 'text'
},
{
label: 'Date of Birth',
fieldtype: 'datetime'
},
{
label: 'Email',
fieldtype: text
}
]
}
]
}, {
label: 'Employment History',
description: 'Specify your 3 previous employers',
repeatable: 3,
fieldGroups: [
{
fields: [
{
label: 'Company',
fieldtype: 'text',
validation: {
required: true
}
},
{
label: 'Start Date',
fieldtype: datetime,
validation: {
required: true
}
},
{
label: 'End Date',
description: 'Leave blank if not applicable',
fieldtype: 'datetime'
},
{
label: 'Company Contact Name / Number',
fieldtype: 'text'
}
]
}
]
}]
}
})
You could then use this resuable template to generate 'entries' via your client applications, e.g. Mobile App or Web App. Your client will need to interpret these templates (this is the part you have to write yourself) so they can display some kind of form to the end user.
The entry mimicks the schema of the template, with the addition of a value property on the fields. An entry document might be created like so:
MyModel.new({
name: 'Custom entry name',
content: {
formGroups: [{
label: 'Personal Information',
description: 'Enter you personal information for your Resume',
repeatable: 1,
fieldGroups: [
{
fields: [
{
label: 'First Name',
fieldtype: 'text',
value: 'Joe'
},
{
label: 'Last Name',
fieldtype: 'text',
value: 'Bloggs'
},
{
label: 'Date of Birth',
fieldtype: 'datetime',
value: 'Fri Apr 24 1987 13:44:48 GMT+1000 (AEST)'
},
{
label: 'Email',
fieldtype: text,
value: '[email protected]'
}
]
}
]
}, {
label: 'Employment History',
description: 'Specify your 3 previous employers',
repeatable: 3,
fieldGroups: [
{
fields: [
{
label: 'Company',
fieldtype: 'text',
validation: {
required: true
},
value: 'IBM'
},
{
label: 'Start Date',
fieldtype: datetime,
validation: {
required: true
},
value: 'Mon Jan 01 2000 00:00:00 GMT+1000 (AEST)'
},
{
label: 'End Date',
description: 'Leave blank if not applicable',
fieldtype: 'datetime',
value: 'Mon Jan 01 2005 00:00:00 GMT+1000 (AEST)'
},
{
label: 'Company Contact Name / Number',
fieldtype: 'text',
value: 'Mary Jones [email protected]'
}
]
},
{
fields: [
{
label: 'Company',
fieldtype: 'text',
validation: {
required: true
},
value: 'Microsoft'
},
{
label: 'Start Date',
fieldtype: datetime,
validation: {
required: true
},
value: 'Mon Jan 01 2005 00:00:00 GMT+1000 (AEST)'
},
{
label: 'End Date',
description: 'Leave blank if not applicable',
fieldtype: 'datetime',
value: 'Mon Jan 01 2010 00:00:00 GMT+1000 (AEST)'
},
{
label: 'Company Contact Name / Number',
fieldtype: 'text',
value: 'Mary Jones [email protected]'
}
]
},
{
fields: [
{
label: 'Company',
fieldtype: 'text',
validation: {
required: true
},
value: Google
},
{
label: 'Start Date',
fieldtype: datetime,
validation: {
required: true
},
value: 'Mon Jan 01 2010 00:00:00 GMT+1000 (AEST)'
},
{
label: 'End Date',
description: 'Leave blank if not applicable',
fieldtype: 'datetime'
},
{
label: 'Company Contact Name / Number',
fieldtype: 'text',
value: 'Mary Jones [email protected]'
}
]
}
]
}]
}
})
As you can see it is a very flexible way to store data based on freeform data (e.g. data you will cannot define a schema for in advance).
Overview
There are 3 components to Formulate: Fieldtypes, Templates and Entries.
Fieldtypes
Fieldtypes are the building blocks of your templates. They are a basic from of common inputs that should be flexible enough to handle most 'form content'.
Currently Formulate has the following fieldtypes:
- Text
- Number
- Datetime
- Select
- Relationship
- Switch
- List
Each of the fields has validation (required, min, max) options which allows customisation of input you store in your entries.
Templates
Templates can be thought of as a Form Builder. Imagine templates as a way to programmatically store your content structures as you would in your CMS – Heads up: Formulate handles only the logic of structuring and storing your content. There is no UI component to this package, that part is up to you!
Entries
Entries are where the data for a submitted template is stored. Entries mimick the schema used for the template they were based on, but there is no definite relationship between the two. E.g. Once an entry is created, it holds a copy of the template it was based on, so existing templates can be safely updated without affecting historical entries.
Template Form Groups, Field Groups and Fields
As you can see form the example above, the schema for templates features the following properties which make up a form template:
- Form Groups
- Field Groups
- Fields
Each is a child of the previous and helps to build a flexible form structure to handle most types of input data. The following illustrates the structure of a form:
Form Groups
The top level array that holds 'sections' of your forms. Imagine form group items as being independant sections of your form. E.g. if you were creating resume input, your formGroups
might be 'Personal Information', 'Work History' and 'Education'.
Field Groups
Field Groups are an array as well, which is important as it allows us to accept repeatable input based on a single template.
Take the resume example again, the work history section would be based on a template (Company, Start, End, Contact) that can be repeated. That is a fieldGroup
. If you don't want the group of fields to be repeated, e.g. for Personal Information you wouldn't want to repeat the input, then you just set the repeatable
property of the formGroup
to 1.
For unlimited inputs, set repeatable
to 0 and for anything else set the number you want to limit by, e.g. 4.
Fields
Fields make up your fieldGroups and represent an individual input for the form. For the resume example, the Personal Information form group would be made up of one fieldGroup
with the fields
First Name, Last Name, DoB, Address, Email etc.
Fields have a fieldtype property which is explained here
Useful things to remember about Formulate
- It's your job to build UIs for your forms/templates. Formulate only handles the programatical side of building templates and validating and storing your entries
- The schema for templates are identical to entries so that both can be edited independantly in the future
- formGroups are like 'sections' of your forms
- fieldGroups hold related fields and can be repeatable to support multiple items
- fields are individual inputs on your forms and are grouped in fieldGroups
- Values are important to entries, but not so much for templates. Although you can use the value property on a template to act as a custom default value