ember install ember-frost-bunsen
Attribute | Type | Required | Description |
---|---|---|---|
model |
Ember.Object or object |
Yes | Value definition |
renderers |
Ember.Object or object |
No | Custom renderer template helper mappings |
value |
Ember.Object or object |
No | Data to render |
view |
Ember.Object or object |
No | View definition |
Attribute | Type | Required | Description |
---|---|---|---|
cancelLabel |
string |
No | Text for cancel button |
inline |
boolean |
No | Whether or not to render form inline |
model |
Ember.Object or object |
Yes | Value definition |
onCancel |
Function |
No | Callback for when form is cancelled |
onChange |
Function |
No | Callback for when form values change |
onSubmit |
Function |
No | Callback for when form is submitted |
onValidation |
Function |
No | Callback for when form is validated |
renderers |
Ember.Object or object |
No | Custom renderer template helper mappings |
submitLabel |
string |
No | Text for submit button |
validators |
Array<Function> |
No | List of custom validation functions |
value |
Ember.Object or object |
No | Value to initialize form with |
view |
Ember.Object or object |
No | View definition |
Note: ALL values, models, and views MUST be valid JSON. Values are simply the data being represented in the UI which usually come directly from an API response. Models must be valid JSON Schema and views must be valid view schema. Below we will provide examples of values, models, and views to give you a better idea of how this stuff works.
Value (Data to Render)
{
"firstName": "John",
"lastName": "Doe"
}
Model
{
"type": "object",
"properties": {
"firstName": {"type": "string"},
"lastName": {"type": "string"}
}
}
View
{
"version": "1.0",
"type": "form",
"rootContainers": {
"label": "Main",
"id": "main"
},
"containers": [
{
"id": "main",
"rows": [
[
{"model": "firstName"},
{"model": "lastName"},
]
]
}
]
}
Value (Data to Render)
{
"name": {
"first": "John",
"last": "Doe"
}
}
Model
{
"type": "object",
"properties": {
"name": {
"type": "object",
"properties": {
"first": {"type": "string"},
"last": {"type": "string"}
}
}
}
}
View
{
"version": "1.0",
"type": "form",
"rootContainers": {
"label": "Main",
"id": "main"
},
"containers": [
{
"id": "main",
"rows": [
[
{"model": "name.first"},
{"model": "name.last"},
]
]
}
]
}
Value (Data to Render)
{
"name": "John Doe",
"age": 35,
"married": true,
"spouse": {
"name": "Jane Doe",
"age": 32
}
}
Model
{
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number"},
"married": {"type": "boolean"},
"spouse": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number"}
}
}
}
}
View
{
"version": "1.0",
"type": "form",
"rootContainers": {
"label": "Main",
"id": "main"
},
"containers": [
{
"id": "main",
"rows": [
[
{"model": "name"},
{"model": "age"},
{"model": "married"},
{
"label": "Spouse's Name",
"model": "spouse.name"
},
{
"label": "Spouse's Age",
"model": "spouse.age"
}
]
]
}
]
}
Note: In the above view you will notice we specify label for the spouse properties to customize the label text rendered in the UI.
Bunsen will automatically validate types of most fields, and will flag missing fields. We can also pass in a list of custom validation functions which let us add additional conditions.
Validators are functions that return a Promise which resolves to a POJO which can have one or more error objects. (This allows async actions like checking an API.) These objects specify both the field path (based on the Bunsen View, in case of nested things) and an error message:
{
value: {
errors: [ // can be empty, or contain multiple items
{
path: '#/vent',
message: 'Vent core must be odd-numbered'
},
{
path: '#/blasttype',
message: 'Blast type must be either "frogs" or "toads"'
}
],
warnings: []
}
}
Value (Data to Render)
{
"palindrome": "tacocat",
}
Model
{
"type": "object",
"properties": {
"palindrome": {"type": "string"}
}
}
View
{
"version": "1.0",
"type": "form",
"rootContainers": {
"label": "Main",
"id": "main"
},
"containers": [
{
"id": "main",
"rows": [
[
{"model": "palindrome"},
]
]
}
]
}
Custom validation functions can access all form values, and may
return multiple error messages (for multiple fields). Bunsen will
invoke each validator in the validators
list you give it with the form's current
values (on each change), and collate all of the errors together before
passing to the action you give it as onValidation
.
function palindromeValidator (values) {
// If missing, a value will be undefined in the values object.
// Bunsen already flags missing required fields.
if (values.palindrome !== undefined) {
const palindrome = (values.palindrome || '').replace(' ', '').toLowerCase()
const reversed = palindrome.split('').reverse().join('')
if (palindrome !== reversed) {
return Promise.resolve({
value: {
errors: [{
path: '#/palindrome',
message: 'Palindrome field does not read the same forwards as backwards'
}],
warnings: []
}
})
}
}
return Promise.resolve({
value: {
errors: [],
warnings: []
}
})
}
export default Ember.Component.extend({
layout: layout,
classNames: ['palindrome-form'],
model: bunsenModel,
view: bunsenView,
valid: false,
hasError: Ember.computed.notEmpty('error'),
validators: [
palindromeValidator
],
actions: {
onValidation (e) {
this.set('valid', e.valid)
}
}
})
When invoking Bunsen, specify the onValidation
and validators
options:
git clone git@github.com:ciena-frost/ember-frost-bunsen.git
cd ember-frost-bunsen
npm install && bower install
A dummy application for development is available under ember-frost-bunsen/tests/dummy
.
To run the server run ember server
(or npm start
) from the root of the repository and
visit the app at http://localhost:4200.
Run npm test
from the root of the project to run linting checks as well as execute the test suite
and output code coverage.