Schema file
This is the main file that defines a model. It represents the schema, i.e the list of fields (and its types) that the model will have.
Mongoose types
Route Injector supports the following Mongoose types:
String
name: {type: String},
otherWay: String
Number
number: {type: Number},
otherWay: Number
Date
date: {type: Date},
otherWay: Date
Array
myArray:[String],
otherWay: [{type: String}]
Mixed
mixedType: {type: mongoose.Schema.Types.Mixed}
As well as embedded types, for example:
var schema = new Schema({
name:
{
displayName: {type: String, class: 'col-md-4'},
firstName:{type: String, class: 'col-md-4'},
lastName: {type: String, class: 'col-md-4'}
},
location:
{
address: { type: String, class: 'col-md-12'},
zip: { type: String, class: 'col-md-3'},
town:{ type: String, class: 'col-md-3'},
state: { type: String, class: 'col-md-3'},
country: { type: String, class: 'col-md-3'}
}
});
You can also define specific subschemas that can be reusable.
var stepSchema = new Schema({
description: {type: String, format: 'textarea', rows: 5},
cookTime: {type: Number, title: "Cook Time (in seconds)"}
},
{ id: false, _id: false }
);
var groupSchema = new Schema({
name: {type: String},
steps: [stepSchema]
},
{ id: false, _id: false }
);
var schema = new Schema({
title: {type: String},
groups: [groupSchema]
}
Other Types
Route Injector also provides a few additional types not included in Mongoose.
RImage
image: injector.types.RImage
Attributes
The behaviour of this types can be modified by using additional attributes. For adding attributes you should use the extended type field declaration as shown in the next example:
text: {type:String, <attribute>}
The available attributes are:
Attribute | Description | Applies to types |
---|---|---|
title | Title for the field (if not present uses a humanized version of field name) | All |
description | Additional description for the field | All |
required | If the field is mandatory or not | All |
readonly | If the field is read only or not | All |
editOnCreate | When true, field is writable when creating element but readonly when editing. | All |
unique | If the field value must be unique in the collection or not | All |
default | Default value of the field | All |
format | Specifies a format for the type, for example HTML or Textarea | String, Number |
class | CSS style for the container of the field | All |
fieldClass | CSS style fot the field | All |
minValue | Minimal value of the field | Number |
maxValue | Maximum value of the field | Number |
min | Minimal value of the field | Number |
max | Maximum value of the field | Number |
enum | Allowed values | String, Number |
enumUrl | Allowed values obtained from a HTTP GET | String, Number |
separator | When using enum selector, character that separates group from text | String, Number |
map | Allowed values and their representable names | String, Number |
rows | Number of rows in the textarea | String (Textarea) |
limitToOptions | If the values in the enum are recommended or mandatory | Boolean, Number (Enum) |
ref | Specifies which other model this field references | All |
denormalize | Specifies how to denormalize the field (copy values from the referenced one) | Mixed |
propagate | Specifies if changes in referenced fields must be propagated to this field. | Mixed |
dependsOn | Specifies how to udate the field when a related field is modified | All |
prefix | When using format:url specifies the initial part of the URL |
String (url) |
TODO What's the correct max or maxValue ???
class
This attribute specifies an additional CSS style for the the container of the field.
rank: {type: String, class: "hidden", readonly: true}
This example adds a rank field of type string that will not be shown, and as a safety measure is also readonly.
phone: {type: Number, class: 'col-md-6'}
The second example is a field of type number that uses the Bootstrap class col-md-6 for nice formatting of the backoffice.
fieldClass
This attribute specifies an additional CSS style for the the field.
TODO: Example
format
The format attributes allow to specify specific visualizations for general types like string or number. The allowed values (without any additional plugin) are: url, html, textarea, rating, time-seconds and button.
name: {type: String, format: <Attribute>}
url
This format allows to render a string field as an URL link on the backoffice list. The prefix is added to the string to generate the URL, if the string value is my-post
and the prefix
is /
the URL of the link will be /my-post
.
name: {type: String, format: 'url', prefix: '/'}
html
This format allows to render a string field as an small HTML editor on the backoffice.
name: {type: String, format: 'html'}
textarea
name: {type: String, format: 'textarea', rows: 5}
rating
name: {type: Number, format: 'rating', minValue:1, maxValue: 3}
time-seconds
name: {type: Number, format: 'time-seconds'}
button
action1: {type: String, format: 'button', action:'api', method:'GET', url:'/my/url', title: 'Call api function'}
action2: {type: String, format: 'button', action:'function', func: 'insideFunction'}
enum
Allows to choose among a fixed set of options.
region: {
type: String,
required: true,
enum: ['Spain','France','UK']
}
It can also be get from an external file:
region: {
type: String,
required: true,
enum: require("./../elements/regions.js"),
}
In this case the enum values can be fixed but computed.
// regions can be computed in the javascript file
var regions = [
'REG1',
'REG2'];
module.exports = regions;
separator
Enables selector grouping by choosing the character that separates group from name. See this example.
enumUrl
tags: [
{
type: String,
separator: '/',
limitToOptions: false,
enumUrl: "https://{{region}}.myserver.com/tags?type=raw"
}
]
This example shows how to get the enum values from the specified URL. Angular substitutions can be used, and enum values can be limited or no to these results. In this example, also a separator is used for nicer formating the selector.
The returned file from the HTTP GET method should have the following format.
["Group 1/Tag 1","Group 1/Tag 2","Group 1/Tag 3", "Group 2/Tag 4", "Group 3/Tag 5"]
Notice that each string is composed of a group plus a text separated by '/'. This groups the different options in the selector. The grouping is enabled by selecting the separator character with the separator option.
map
Map is similar to enum but allows to specify the both the shown value in the backoffice and also the stored value in the database.
unit: {
type: String,
class: "col-md-2",
map: require("../elements/units.json"),
}
The json stores the database values as keys and the shown values in the name
field. It is also possible to specify a group
field to group the different
{
"": {"name": "No Unit", "group": "Units"},
"u": {"name": "Units (u)", "group":"Units"},
"gr": {"name": "Grams (gr)", "group": "Units"},
"l": {"name": "Litres (l)", "group": "Units"},
"ml": {"name": "Mililitres (ml)", "group": "Units"},
"tbsp": {"name": "Table spoon (tbsp)", "group": "Units"},
"tsp": {"name": "Tea spoon (tsp)", "group": "Units"},
"cp": {"name": "Cup (cp)", "group": "Units"},
"mc": {"name": "Measure cup (mc)", "group": "Units"},
"coy": {"name": "Cup of yogurt (coy)", "group": "Units"},
"pch": {"name": "Pinch (pch)", "group": "Units"},
"drp": {"name": "Drops (drp)", "group": "Units"},
"scht": {"name": "Sachet (scht", "group": "Units"},
"pkt": {"name": "Packets (pkt)", "group":"Units"},
"gra": {"name": "Grains (gra)", "group": "Other Units"},
"clv": {"name": "Cloves (clv)", "group": "Other Units"},
"stk": {"name": "Sticks (stk)", "group": "Other Units"},
"bch": {"name": "Bunch(s) (bch)", "group": "Other Units"},
"brch": {"name": "Branches (brch)", "group": "Other Units"},
"lea": {"name": "Leaf(ves) (lea)", "group": "Other Units"},
"slc": {"name": "Slices (slc)", "group": "Other Units"},
"tur": {"name": "Tours (tur)", "group": "Other Units"}
}
Modifiers
readonly
If true, the backoffice does not allow to modify this field, see also editOnCreate.
unique
If true, unique notifies Mongo that this index should contain unique, i.e non repeated values.
TODO
DynEnum
Document dynEnum / dynMap difference with enumUrl ???
Seems that dynEnum shows a classic selector instead of select2
code: {type: String, dynEnum: "/api/get-url-codes"},
The format of /api/get-url-codes is:
[
"home",
"staticPage",
"post",
"blogCategory",
"blog",
"privacyPolicy",
"404"
]
Format map with selectors
widget | when it is selected |
---|---|
select2 | when exists ref |
simple-select2 | when exists map or dynEnum or dynMap |
multiselect | when type is array and items.type is string and exists items.enum or items.map or items.enumUrl |
select (angularschemaform) | when type is string and exists enum (1) |
(1) Seems that types can be forced https://github.com/json-schema-form/angular-schema-form/blob/master/docs/index.md#overriding-field-types-and-order