I'm trying to display a simple dynamic form using ember.js, im pretty new to ember and front-end frameworks in general.
I am using
The JSON payload is the following: some fields are to be generated and some elements have to be enabled.
JSON:
{
"create-fields": [{
"id": 1,
"field": "widgetName",
"label": "Widget Name",
"tooltip": "Widget Name",
"category": "textfield",
"url": "",
"required": true,
"widgetform_id": 1
}, {
"id": 2,
"field": "APIKey",
"label": "API Key",
"tooltip": "API Key",
"category": "textfield",
"url": "",
"required": true,
"widgetform_id": 1
}, {
"id": 3,
"field": "Campaign",
"label": "Select Campaign",
"tooltip": "Select Campaign",
"category": "select",
"url": "campaigns/",
"required": false,
"widgetform_id": 1
}, {
"id": 4,
"field": "checkbox",
"label": "Sample Checkbox",
"tooltip": "Sample Checkbox",
"category": "checkbox",
"url": "",
"required": false,
"widgetform_id": 1
}],
"enable-fields": [{
"id": 1,
"field": "showAdvanced",
"required": false,
"widgetform_id": 1
}, {
"id": 2,
"field": "notification",
"required": false,
"widgetform_id": 1
}, {
"id": 3,
"field": "enableNotif",
"required": false,
"widgetform_id": 1
}, {
"id": 4,
"field": "email",
"required": false,
"widgetform_id": 1
}, {
"id": 5,
"field": "phone",
"required": false,
"widgetform_id": 1
}, {
"id": 6,
"field": "reqType",
"required": false,
"widgetform_id": 1
}, {
"id": 7,
"field": "dataFormat",
"required": false,
"widgetform_id": 1
}, {
"id": 8,
"field": "appendUrlParams",
"required": false,
"widgetform_id": 1
}],
"widgetforms": [{
"id": 1,
"formname": "Edit Widget",
"enable-field_ids": [1, 2, 3, 4, 5, 6, 7, 8],
"create-field_ids": [1, 2, 3, 4]
}]
}
//models
widgetform.js:
import DS from 'ember-data';
export default DS.Model.extend({
formname: DS.attr(),
createFields: DS.hasMany('createFields'),
enableFields: DS.hasMany('enableFields')
});
create-field.js:
import DS from 'ember-data';
export default DS.Model.extend({
field: DS.attr(),
label: DS.attr(),
tooltip: DS.attr(),
category: DS.attr(),
url: DS.attr('string', {defaultValue: ""}),
required: DS.attr('boolean'),
widgetform: DS.belongsTo('widgetform')
});
enable-field.js:
import DS from 'ember-data';
export default DS.Model.extend({
field: DS.attr(),
required: DS.attr('boolean'),
widgetform: DS.belongsTo('widgetform')
});
template
widgetform.hbs: The hbs doesn't have all the fields it is just a mockup.
<div class="container-fluid">
{{#each model as |form|}}
<form class="form-horizontal">
<fieldset>
<header id="header">
<h1>{{form.formname}}</h1>
</header>
<section id="main">
<ul id="field-list">
{{form.createFields}}
{{#each form.createFields as |element|}}
<li>test1 {{element.field}}</li>
{{/each}}
</ul>
</section>
</fieldset>
</form>
{{/each}}
</div>
So far I've been able to see the data in the respective models using ember-inspector in chrome.
However, in the template when using the {{form.createFields}}
I get a <DS.PromiseManyArray>
, and the {{form.createFields.content}}
is a <DS.ManyArray>
object both of which I couldn't iterate through.
The test1
that I put in the template is not printing in the page. The {{form.formname}}
property however is available and is printed in the page.
I've checked many questions like this, and the general suggestion is to add the id list but I've added them in the JSON but I don't see the difference
screenshot of ember-inspector data tab:
What am I doing wrong here? Any ideas?
For some reason the RESTAdapter was not working for this particular data set or environment, so I decided to scrap it and embrace the new JSONAPI 1.0 specs and use the JSONAPIAdapter.
Models:
create-field.js:
import DS from 'ember-data';
export default DS.Model.extend({
field: DS.attr(),
label: DS.attr(),
tooltip: DS.attr(),
category: DS.attr(),
url: DS.attr('string', { defaultValue: ""}),
required: DS.attr('boolean')
});
enable-field.js
import DS from 'ember-data';
export default DS.Model.extend({
field: DS.attr(),
required: DS.attr('boolean')
});
widgetform.js
import DS from 'ember-data';
export default DS.Model.extend({
formname: DS.attr(),
createFields: DS.hasMany('create-field'),
enableFields: DS.hasMany('enable-field')
});
The JSON for the above model is formatted as per the JSONAPI 1.0 spec: http://jsonapi.org/format/
{
"data": [{
"type": "widgetform",
"id": 1,
"attributes": {
"formname": "Edit Widget"
},
"relationships": {
"create-fields": {
"data": [{
"type": "create-fields",
"id": "1"
}, {
"type": "create-fields",
"id": "2"
}]
},
"enable-fields": {
"data": [{
"type": "enable-fields",
"id": "1"
}, {
"type": "enable-fields",
"id": "2"
}]
}
}
}],
"included": [{
"type": "create-fields",
"id": "1",
"attributes": {
"field": "widgetName",
"label": "Widget Name",
"tooltip": "Widget Name",
"category": "textfield",
"required": true
}
}, {
"type": "create-fields",
"id": "2",
"attributes": {
"field": "APIKey",
"label": "API Key",
"tooltip": "API Key",
"category": "textfield",
"required": true
}
}, {
"type": "enable-fields",
"id": "1",
"attributes": {
"field": "showAdvanced",
"required": false
}
}, {
"type": "enable-fields",
"id": "2",
"attributes": {
"field": "notification",
"required": false
}
}]
}
adapter: application.js
import DS from 'ember-data';
export default DS.JSONAPIAdapter.extend({
namespace: 'api'
});
And I was able to access it from the template using the each block as usual
widgetform.hbs
<div class="container-fluid">
{{#each model as |form|}}
<form class="form-horizontal">
<fieldset>
<header id="header">
<h1>{{form.formname}}</h1>
</header>
<section id="main">
<ul id="field-list">
{{#each form.createFields as |element|}}
<li>
<input name="{{element.field}}" type="text">
</li>
{{/each}}
</ul>
</section>
</fieldset>
</form>
{{/each}}
</div>
I hope it helps someone...