Create a fully dynamic table in EmberJS
I have defined a model
in EmberJS with the following attributes:
import DS from 'ember-data';
export default DS.Model.extend(
"name": DS.attr('string'),
"status": DS.attr('string'),
"email1": DS.attr('string'),
"account_name": DS.attr('string'),
"phone_work": DS.attr('string'),
"date_entered": DS.attr('string'),
"date_modified": DS.attr('string')
);
I am creating a component
called fields-list
that would render these attributes into a table (headers, body; just like a typical table to list some fields). However, instead of making the table bound to this model
only, I want to make the component
fully dynamic, so that other models with different field names could also reuse this component
to generate their tables as well.
This way, whenever the component
is used, it detects the model
and populates the headers of the table as well as the body according to the fields in that model
.
How do I achieve this? If there is anything that's not clear in the query please do let me know, I've tried my best to explain the issue properly as much as I can. Thanks in advance!
javascript ember.js
add a comment |
I have defined a model
in EmberJS with the following attributes:
import DS from 'ember-data';
export default DS.Model.extend(
"name": DS.attr('string'),
"status": DS.attr('string'),
"email1": DS.attr('string'),
"account_name": DS.attr('string'),
"phone_work": DS.attr('string'),
"date_entered": DS.attr('string'),
"date_modified": DS.attr('string')
);
I am creating a component
called fields-list
that would render these attributes into a table (headers, body; just like a typical table to list some fields). However, instead of making the table bound to this model
only, I want to make the component
fully dynamic, so that other models with different field names could also reuse this component
to generate their tables as well.
This way, whenever the component
is used, it detects the model
and populates the headers of the table as well as the body according to the fields in that model
.
How do I achieve this? If there is anything that's not clear in the query please do let me know, I've tried my best to explain the issue properly as much as I can. Thanks in advance!
javascript ember.js
Did you had a look on existing table implementations? There are a lot ember addons trying to achieve exactly what you want: emberobserver.com/categories/lists-and-tables
– jelhan
Nov 12 at 8:16
what have you tried so far and what is your problem? Have a look at eachAttribute.
– Lux
Nov 12 at 8:47
I have looked at ember contextual table and ember light table . Ember Light Table has better documentation but I do not understand how to add table headers and data from themodel
dynamically.
– noobdev
Nov 12 at 9:30
add a comment |
I have defined a model
in EmberJS with the following attributes:
import DS from 'ember-data';
export default DS.Model.extend(
"name": DS.attr('string'),
"status": DS.attr('string'),
"email1": DS.attr('string'),
"account_name": DS.attr('string'),
"phone_work": DS.attr('string'),
"date_entered": DS.attr('string'),
"date_modified": DS.attr('string')
);
I am creating a component
called fields-list
that would render these attributes into a table (headers, body; just like a typical table to list some fields). However, instead of making the table bound to this model
only, I want to make the component
fully dynamic, so that other models with different field names could also reuse this component
to generate their tables as well.
This way, whenever the component
is used, it detects the model
and populates the headers of the table as well as the body according to the fields in that model
.
How do I achieve this? If there is anything that's not clear in the query please do let me know, I've tried my best to explain the issue properly as much as I can. Thanks in advance!
javascript ember.js
I have defined a model
in EmberJS with the following attributes:
import DS from 'ember-data';
export default DS.Model.extend(
"name": DS.attr('string'),
"status": DS.attr('string'),
"email1": DS.attr('string'),
"account_name": DS.attr('string'),
"phone_work": DS.attr('string'),
"date_entered": DS.attr('string'),
"date_modified": DS.attr('string')
);
I am creating a component
called fields-list
that would render these attributes into a table (headers, body; just like a typical table to list some fields). However, instead of making the table bound to this model
only, I want to make the component
fully dynamic, so that other models with different field names could also reuse this component
to generate their tables as well.
This way, whenever the component
is used, it detects the model
and populates the headers of the table as well as the body according to the fields in that model
.
How do I achieve this? If there is anything that's not clear in the query please do let me know, I've tried my best to explain the issue properly as much as I can. Thanks in advance!
javascript ember.js
javascript ember.js
asked Nov 12 at 8:08
noobdev
506
506
Did you had a look on existing table implementations? There are a lot ember addons trying to achieve exactly what you want: emberobserver.com/categories/lists-and-tables
– jelhan
Nov 12 at 8:16
what have you tried so far and what is your problem? Have a look at eachAttribute.
– Lux
Nov 12 at 8:47
I have looked at ember contextual table and ember light table . Ember Light Table has better documentation but I do not understand how to add table headers and data from themodel
dynamically.
– noobdev
Nov 12 at 9:30
add a comment |
Did you had a look on existing table implementations? There are a lot ember addons trying to achieve exactly what you want: emberobserver.com/categories/lists-and-tables
– jelhan
Nov 12 at 8:16
what have you tried so far and what is your problem? Have a look at eachAttribute.
– Lux
Nov 12 at 8:47
I have looked at ember contextual table and ember light table . Ember Light Table has better documentation but I do not understand how to add table headers and data from themodel
dynamically.
– noobdev
Nov 12 at 9:30
Did you had a look on existing table implementations? There are a lot ember addons trying to achieve exactly what you want: emberobserver.com/categories/lists-and-tables
– jelhan
Nov 12 at 8:16
Did you had a look on existing table implementations? There are a lot ember addons trying to achieve exactly what you want: emberobserver.com/categories/lists-and-tables
– jelhan
Nov 12 at 8:16
what have you tried so far and what is your problem? Have a look at eachAttribute.
– Lux
Nov 12 at 8:47
what have you tried so far and what is your problem? Have a look at eachAttribute.
– Lux
Nov 12 at 8:47
I have looked at ember contextual table and ember light table . Ember Light Table has better documentation but I do not understand how to add table headers and data from the
model
dynamically.– noobdev
Nov 12 at 9:30
I have looked at ember contextual table and ember light table . Ember Light Table has better documentation but I do not understand how to add table headers and data from the
model
dynamically.– noobdev
Nov 12 at 9:30
add a comment |
2 Answers
2
active
oldest
votes
I don't personally use Ember Data, so there might be better ways to do what you're doing, but I got a solution for you available as an ember twiddle or as a gist. This is nothing more than a proof of concept.
Let's break the question down really fast. You want to create a component that can take any model and magically build a table for you. At the highest level, we know that we need to be able to iterate over the data model's definition and create columns of specific types based off of the Ember Data types you've passed as DS.attr
. Thinking further, we know Ember Data must have some sort of ability to do the same: eachAttribute. If it's a private API, recognize this is brittle and version specific (aka write tests).
So, given a model Foo:
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
export default Model.extend(
"name": attr('string'),
"status": attr('string')
);
Let's get the model's definition via the constructor:
var record = this.store.createRecord('foo',
name: "model1",
status: "status1"
);
this.modelClass = record.constructor;
Ember light table takes a columns definition object which we can create dynamically from within our component through the use of eachAttribute
on said model class:
columns: computed('modelClass', function()
let modelClass = this.modelClass;
if(!modelClass) return
let columns = ;
modelClass.eachAttribute(function(key, meta)
columns.push(
label: key,
valuePath: key
);
);
return columns;
)
it's here that you could inspect the meta
parameter of the eachAttribute
function for the specific type of each attribute to set the cellComponent
property within the column definition should you want to render different cell types.
There's a project called Ember Admin that builds up a CRUD interface automagically off of your data model so there's a place of inspiration.
Thanks! the explanation and twiddle really helped with understanding the concept.
– noobdev
Nov 13 at 6:05
add a comment |
Why resort to addons if you can just build this yourself?
app/templates/some-route.hbs
<FieldsList
@resources=users
@columns='id, firstName, lastName, job.title, job.company.name'
@sortBy='firstNameAsc'
@filterBy='firstName, lastName'
/>
app/components/fields-list/component.js
import Component from '@ember/component';
import computed from '@ember/object';
export default Component.extend(
classNames: ['fields-list'],
// Splits the string of keys into an array
columnMap: computed(function()
return this.columns.replace(/ /g, '').split(/,/g);
)
);
app/components/fields-list/template.hbs
<ul>
<li>
column
<span>get resource key</span>
/each
</li>
else
<li>No humans found</li>
/each
</ul>
app/components/fields-list/style.scss
.fields-list
li
display: flex;
span
flex: 1;
Done in ember-cli: 3.5.0
1
Interesting solution, although I think you may have swapped the second and third paths by accident. Nevertheless I understand where you're going with this. Thanks :)
– noobdev
Nov 13 at 6:07
Good spot, resolved :+1:
– Jan Werkhoven
Nov 13 at 11:34
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53258042%2fcreate-a-fully-dynamic-table-in-emberjs%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I don't personally use Ember Data, so there might be better ways to do what you're doing, but I got a solution for you available as an ember twiddle or as a gist. This is nothing more than a proof of concept.
Let's break the question down really fast. You want to create a component that can take any model and magically build a table for you. At the highest level, we know that we need to be able to iterate over the data model's definition and create columns of specific types based off of the Ember Data types you've passed as DS.attr
. Thinking further, we know Ember Data must have some sort of ability to do the same: eachAttribute. If it's a private API, recognize this is brittle and version specific (aka write tests).
So, given a model Foo:
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
export default Model.extend(
"name": attr('string'),
"status": attr('string')
);
Let's get the model's definition via the constructor:
var record = this.store.createRecord('foo',
name: "model1",
status: "status1"
);
this.modelClass = record.constructor;
Ember light table takes a columns definition object which we can create dynamically from within our component through the use of eachAttribute
on said model class:
columns: computed('modelClass', function()
let modelClass = this.modelClass;
if(!modelClass) return
let columns = ;
modelClass.eachAttribute(function(key, meta)
columns.push(
label: key,
valuePath: key
);
);
return columns;
)
it's here that you could inspect the meta
parameter of the eachAttribute
function for the specific type of each attribute to set the cellComponent
property within the column definition should you want to render different cell types.
There's a project called Ember Admin that builds up a CRUD interface automagically off of your data model so there's a place of inspiration.
Thanks! the explanation and twiddle really helped with understanding the concept.
– noobdev
Nov 13 at 6:05
add a comment |
I don't personally use Ember Data, so there might be better ways to do what you're doing, but I got a solution for you available as an ember twiddle or as a gist. This is nothing more than a proof of concept.
Let's break the question down really fast. You want to create a component that can take any model and magically build a table for you. At the highest level, we know that we need to be able to iterate over the data model's definition and create columns of specific types based off of the Ember Data types you've passed as DS.attr
. Thinking further, we know Ember Data must have some sort of ability to do the same: eachAttribute. If it's a private API, recognize this is brittle and version specific (aka write tests).
So, given a model Foo:
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
export default Model.extend(
"name": attr('string'),
"status": attr('string')
);
Let's get the model's definition via the constructor:
var record = this.store.createRecord('foo',
name: "model1",
status: "status1"
);
this.modelClass = record.constructor;
Ember light table takes a columns definition object which we can create dynamically from within our component through the use of eachAttribute
on said model class:
columns: computed('modelClass', function()
let modelClass = this.modelClass;
if(!modelClass) return
let columns = ;
modelClass.eachAttribute(function(key, meta)
columns.push(
label: key,
valuePath: key
);
);
return columns;
)
it's here that you could inspect the meta
parameter of the eachAttribute
function for the specific type of each attribute to set the cellComponent
property within the column definition should you want to render different cell types.
There's a project called Ember Admin that builds up a CRUD interface automagically off of your data model so there's a place of inspiration.
Thanks! the explanation and twiddle really helped with understanding the concept.
– noobdev
Nov 13 at 6:05
add a comment |
I don't personally use Ember Data, so there might be better ways to do what you're doing, but I got a solution for you available as an ember twiddle or as a gist. This is nothing more than a proof of concept.
Let's break the question down really fast. You want to create a component that can take any model and magically build a table for you. At the highest level, we know that we need to be able to iterate over the data model's definition and create columns of specific types based off of the Ember Data types you've passed as DS.attr
. Thinking further, we know Ember Data must have some sort of ability to do the same: eachAttribute. If it's a private API, recognize this is brittle and version specific (aka write tests).
So, given a model Foo:
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
export default Model.extend(
"name": attr('string'),
"status": attr('string')
);
Let's get the model's definition via the constructor:
var record = this.store.createRecord('foo',
name: "model1",
status: "status1"
);
this.modelClass = record.constructor;
Ember light table takes a columns definition object which we can create dynamically from within our component through the use of eachAttribute
on said model class:
columns: computed('modelClass', function()
let modelClass = this.modelClass;
if(!modelClass) return
let columns = ;
modelClass.eachAttribute(function(key, meta)
columns.push(
label: key,
valuePath: key
);
);
return columns;
)
it's here that you could inspect the meta
parameter of the eachAttribute
function for the specific type of each attribute to set the cellComponent
property within the column definition should you want to render different cell types.
There's a project called Ember Admin that builds up a CRUD interface automagically off of your data model so there's a place of inspiration.
I don't personally use Ember Data, so there might be better ways to do what you're doing, but I got a solution for you available as an ember twiddle or as a gist. This is nothing more than a proof of concept.
Let's break the question down really fast. You want to create a component that can take any model and magically build a table for you. At the highest level, we know that we need to be able to iterate over the data model's definition and create columns of specific types based off of the Ember Data types you've passed as DS.attr
. Thinking further, we know Ember Data must have some sort of ability to do the same: eachAttribute. If it's a private API, recognize this is brittle and version specific (aka write tests).
So, given a model Foo:
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
export default Model.extend(
"name": attr('string'),
"status": attr('string')
);
Let's get the model's definition via the constructor:
var record = this.store.createRecord('foo',
name: "model1",
status: "status1"
);
this.modelClass = record.constructor;
Ember light table takes a columns definition object which we can create dynamically from within our component through the use of eachAttribute
on said model class:
columns: computed('modelClass', function()
let modelClass = this.modelClass;
if(!modelClass) return
let columns = ;
modelClass.eachAttribute(function(key, meta)
columns.push(
label: key,
valuePath: key
);
);
return columns;
)
it's here that you could inspect the meta
parameter of the eachAttribute
function for the specific type of each attribute to set the cellComponent
property within the column definition should you want to render different cell types.
There's a project called Ember Admin that builds up a CRUD interface automagically off of your data model so there's a place of inspiration.
answered Nov 12 at 10:52
mistahenry
5,26831829
5,26831829
Thanks! the explanation and twiddle really helped with understanding the concept.
– noobdev
Nov 13 at 6:05
add a comment |
Thanks! the explanation and twiddle really helped with understanding the concept.
– noobdev
Nov 13 at 6:05
Thanks! the explanation and twiddle really helped with understanding the concept.
– noobdev
Nov 13 at 6:05
Thanks! the explanation and twiddle really helped with understanding the concept.
– noobdev
Nov 13 at 6:05
add a comment |
Why resort to addons if you can just build this yourself?
app/templates/some-route.hbs
<FieldsList
@resources=users
@columns='id, firstName, lastName, job.title, job.company.name'
@sortBy='firstNameAsc'
@filterBy='firstName, lastName'
/>
app/components/fields-list/component.js
import Component from '@ember/component';
import computed from '@ember/object';
export default Component.extend(
classNames: ['fields-list'],
// Splits the string of keys into an array
columnMap: computed(function()
return this.columns.replace(/ /g, '').split(/,/g);
)
);
app/components/fields-list/template.hbs
<ul>
<li>
column
<span>get resource key</span>
/each
</li>
else
<li>No humans found</li>
/each
</ul>
app/components/fields-list/style.scss
.fields-list
li
display: flex;
span
flex: 1;
Done in ember-cli: 3.5.0
1
Interesting solution, although I think you may have swapped the second and third paths by accident. Nevertheless I understand where you're going with this. Thanks :)
– noobdev
Nov 13 at 6:07
Good spot, resolved :+1:
– Jan Werkhoven
Nov 13 at 11:34
add a comment |
Why resort to addons if you can just build this yourself?
app/templates/some-route.hbs
<FieldsList
@resources=users
@columns='id, firstName, lastName, job.title, job.company.name'
@sortBy='firstNameAsc'
@filterBy='firstName, lastName'
/>
app/components/fields-list/component.js
import Component from '@ember/component';
import computed from '@ember/object';
export default Component.extend(
classNames: ['fields-list'],
// Splits the string of keys into an array
columnMap: computed(function()
return this.columns.replace(/ /g, '').split(/,/g);
)
);
app/components/fields-list/template.hbs
<ul>
<li>
column
<span>get resource key</span>
/each
</li>
else
<li>No humans found</li>
/each
</ul>
app/components/fields-list/style.scss
.fields-list
li
display: flex;
span
flex: 1;
Done in ember-cli: 3.5.0
1
Interesting solution, although I think you may have swapped the second and third paths by accident. Nevertheless I understand where you're going with this. Thanks :)
– noobdev
Nov 13 at 6:07
Good spot, resolved :+1:
– Jan Werkhoven
Nov 13 at 11:34
add a comment |
Why resort to addons if you can just build this yourself?
app/templates/some-route.hbs
<FieldsList
@resources=users
@columns='id, firstName, lastName, job.title, job.company.name'
@sortBy='firstNameAsc'
@filterBy='firstName, lastName'
/>
app/components/fields-list/component.js
import Component from '@ember/component';
import computed from '@ember/object';
export default Component.extend(
classNames: ['fields-list'],
// Splits the string of keys into an array
columnMap: computed(function()
return this.columns.replace(/ /g, '').split(/,/g);
)
);
app/components/fields-list/template.hbs
<ul>
<li>
column
<span>get resource key</span>
/each
</li>
else
<li>No humans found</li>
/each
</ul>
app/components/fields-list/style.scss
.fields-list
li
display: flex;
span
flex: 1;
Done in ember-cli: 3.5.0
Why resort to addons if you can just build this yourself?
app/templates/some-route.hbs
<FieldsList
@resources=users
@columns='id, firstName, lastName, job.title, job.company.name'
@sortBy='firstNameAsc'
@filterBy='firstName, lastName'
/>
app/components/fields-list/component.js
import Component from '@ember/component';
import computed from '@ember/object';
export default Component.extend(
classNames: ['fields-list'],
// Splits the string of keys into an array
columnMap: computed(function()
return this.columns.replace(/ /g, '').split(/,/g);
)
);
app/components/fields-list/template.hbs
<ul>
<li>
column
<span>get resource key</span>
/each
</li>
else
<li>No humans found</li>
/each
</ul>
app/components/fields-list/style.scss
.fields-list
li
display: flex;
span
flex: 1;
Done in ember-cli: 3.5.0
edited Nov 13 at 11:33
answered Nov 12 at 11:15
Jan Werkhoven
1,5571325
1,5571325
1
Interesting solution, although I think you may have swapped the second and third paths by accident. Nevertheless I understand where you're going with this. Thanks :)
– noobdev
Nov 13 at 6:07
Good spot, resolved :+1:
– Jan Werkhoven
Nov 13 at 11:34
add a comment |
1
Interesting solution, although I think you may have swapped the second and third paths by accident. Nevertheless I understand where you're going with this. Thanks :)
– noobdev
Nov 13 at 6:07
Good spot, resolved :+1:
– Jan Werkhoven
Nov 13 at 11:34
1
1
Interesting solution, although I think you may have swapped the second and third paths by accident. Nevertheless I understand where you're going with this. Thanks :)
– noobdev
Nov 13 at 6:07
Interesting solution, although I think you may have swapped the second and third paths by accident. Nevertheless I understand where you're going with this. Thanks :)
– noobdev
Nov 13 at 6:07
Good spot, resolved :+1:
– Jan Werkhoven
Nov 13 at 11:34
Good spot, resolved :+1:
– Jan Werkhoven
Nov 13 at 11:34
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53258042%2fcreate-a-fully-dynamic-table-in-emberjs%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Did you had a look on existing table implementations? There are a lot ember addons trying to achieve exactly what you want: emberobserver.com/categories/lists-and-tables
– jelhan
Nov 12 at 8:16
what have you tried so far and what is your problem? Have a look at eachAttribute.
– Lux
Nov 12 at 8:47
I have looked at ember contextual table and ember light table . Ember Light Table has better documentation but I do not understand how to add table headers and data from the
model
dynamically.– noobdev
Nov 12 at 9:30