2012-11-22 18:22:42 +01:00
|
|
|
// A utility class that we use in FormModel to set up a convention for the default labels for each form input field.
|
2012-11-20 15:27:46 +01:00
|
|
|
var StringUtils = {
|
2012-11-22 18:22:42 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
Assumes that the argument is a camel-case string.
|
2012-11-22 18:26:39 +01:00
|
|
|
It places spaces between each word and capitalizes the first letter. So, a string like "camelCase" becomes "Camel Case".
|
2012-11-22 18:22:42 +01:00
|
|
|
*/
|
2012-11-20 15:27:46 +01:00
|
|
|
humanize: function(string) {
|
|
|
|
return this.capitalize(this.convertCamelToSpaces(string));
|
|
|
|
},
|
|
|
|
|
|
|
|
capitalize: function(string) {
|
|
|
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
|
|
},
|
|
|
|
|
|
|
|
convertCamelToSpaces: function(string) {
|
|
|
|
return string.replace(/([A-Z])/g, function(match) {
|
|
|
|
return ' ' + match;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-22 18:22:42 +01:00
|
|
|
|
|
|
|
// A class that provides all the functionality required to generate a form from a database record.
|
2012-11-22 17:48:31 +01:00
|
|
|
var FormModel = Class.extend({
|
2012-11-20 15:27:46 +01:00
|
|
|
|
2012-11-22 18:22:42 +01:00
|
|
|
/*
|
|
|
|
Class constructor:
|
|
|
|
collection: The MongoDB collection the record will be saved to.
|
|
|
|
data: The record data if generating a form for an already-existing record. This argument is optional.
|
|
|
|
*/
|
|
|
|
init: function(collection, data) {
|
|
|
|
this.collection = collection;
|
|
|
|
|
|
|
|
/*
|
|
|
|
blankSchema is an object that each extending class must provide.
|
|
|
|
It contains all the fields to be saved to the database and their default values.
|
2012-11-22 18:26:39 +01:00
|
|
|
The schema field holds the data to be saved to the database.
|
2012-11-22 18:22:42 +01:00
|
|
|
*/
|
|
|
|
this.schema = this.blankSchema;
|
|
|
|
|
|
|
|
// jsonform options that would override the defaults
|
2012-11-20 15:27:46 +01:00
|
|
|
this.formOptions = {};
|
2012-11-22 18:22:42 +01:00
|
|
|
|
2012-11-20 15:52:27 +01:00
|
|
|
this.load(data)
|
|
|
|
},
|
|
|
|
|
2012-11-22 18:39:46 +01:00
|
|
|
// If data has been provided in the constructor, load it into the current object
|
2012-11-20 15:52:27 +01:00
|
|
|
load: function(data) {
|
|
|
|
if (data) {
|
|
|
|
this._id = data._id;
|
2012-11-20 15:27:46 +01:00
|
|
|
|
|
|
|
for (field in this.schema) {
|
2012-11-20 15:52:27 +01:00
|
|
|
if (data[field]) this.schema[field] = data[field];
|
2012-11-20 15:27:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2012-11-22 18:22:42 +01:00
|
|
|
// Generate a jsonform schema for this object based on the form options given and conventions
|
2012-11-20 15:27:46 +01:00
|
|
|
formSchema: function() {
|
|
|
|
var formSchema = {};
|
|
|
|
|
2012-11-22 18:22:42 +01:00
|
|
|
// Each field stored in the database is represented by a form input
|
2012-11-20 15:27:46 +01:00
|
|
|
for (var field in this.schema) {
|
2012-11-22 18:22:42 +01:00
|
|
|
|
2012-11-20 15:27:46 +01:00
|
|
|
formSchema[field] = {
|
2012-11-22 18:22:42 +01:00
|
|
|
// If type is already given in formOptions, use that, otherwise guess the input type by inspecting the field type
|
2012-11-20 15:27:46 +01:00
|
|
|
type: this.option(field, 'type') || this.schema[field].constructor.name.toLowerCase(),
|
2012-11-22 18:22:42 +01:00
|
|
|
|
|
|
|
// If the label text is already specified in formOptions, use that, otherwise use a humanized version of the field name (see StringUtils)
|
2012-11-20 15:27:46 +01:00
|
|
|
title: this.option(field, 'title') || StringUtils.humanize(field),
|
2012-11-22 18:22:42 +01:00
|
|
|
|
|
|
|
// Use the field name as an ID; jsonform will add a prefix to avoid name conflicts
|
2012-11-20 15:27:46 +01:00
|
|
|
id: field,
|
2012-11-22 18:22:42 +01:00
|
|
|
|
|
|
|
// Display the data in the input
|
2012-11-20 15:27:46 +01:00
|
|
|
default: this.schema[field]
|
|
|
|
}
|
|
|
|
|
2012-11-22 18:22:42 +01:00
|
|
|
// If an 'enum' option is provided in formOptions, turn the input into a select by adding the enum options to the jsonform schema
|
2012-11-20 15:27:46 +01:00
|
|
|
if(this.option(field, 'enum')) formSchema[field]['enum'] = this.option(field, 'enum');
|
|
|
|
}
|
|
|
|
|
|
|
|
return formSchema;
|
|
|
|
},
|
|
|
|
|
|
|
|
option: function(field, optionName) {
|
|
|
|
if (this.formOptions[field]) return this.formOptions[field][optionName];
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
|
2012-11-22 18:22:42 +01:00
|
|
|
// Overwrite the default label for a field by adding a 'title' entry to its form options
|
2012-11-20 15:27:46 +01:00
|
|
|
overwriteTitle: function(field, title) {
|
|
|
|
if (this.formOptions[field]) this.formOptions[field]['title'] = title;
|
|
|
|
else this.formOptions[field] = { 'title': title };
|
|
|
|
},
|
|
|
|
|
2012-11-22 18:22:42 +01:00
|
|
|
// Overwrite the default type for a field by adding a 'type' entry to its form options
|
2012-11-20 15:27:46 +01:00
|
|
|
overwriteType: function(field, type) {
|
|
|
|
if (this.formOptions[field]) this.formOptions[field]['type'] = type;
|
|
|
|
else this.formOptions[field] = { 'type': type };
|
|
|
|
},
|
|
|
|
|
2012-11-22 18:22:42 +01:00
|
|
|
// Make the input type of a string field be a select by editing formOptions appropriately
|
2012-11-20 15:27:46 +01:00
|
|
|
makeSelect: function(field, options) {
|
|
|
|
if (this.formOptions[field]) this.formOptions[field]['enum'] = options;
|
|
|
|
else this.formOptions[field] = { 'enum': options };
|
|
|
|
},
|
2012-11-20 15:52:27 +01:00
|
|
|
|
2012-11-22 18:39:46 +01:00
|
|
|
/*
|
|
|
|
If the record was originally loaded from the database, update it.
|
|
|
|
Otherwise, create a new record with the appropriate data.
|
|
|
|
|
|
|
|
createHandler, updateHandler: Functions to run after the database operations completes (such as displaying a message confirming things were saved properly).
|
|
|
|
These usually come from a DatabaseForm, which in turn gets them from a template helper.
|
|
|
|
*/
|
2012-11-20 15:27:46 +01:00
|
|
|
save: function(createHandler, updateHandler) {
|
|
|
|
if (this._id) {
|
2012-11-22 18:22:42 +01:00
|
|
|
this.collection.update(this._id, {$set: this.schema}, updateHandler);
|
2012-11-20 15:27:46 +01:00
|
|
|
} else {
|
2012-11-22 18:22:42 +01:00
|
|
|
this._id = this.collection.insert(this.schema, createHandler);
|
2012-11-20 15:27:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|