Enyo Dynamic Tabular Data
An Enyo 2 Control that will regenerate an HTML Table each time data are loaded. Header rows are generated either based on the provided "map" array or (failing that) based on the first object in the data array. Header lines may be turned off with the "noHeader" property of DataTable. The "map" property is an array of object which will each have a "field" and a "header" property. The "field" is the internal name of each column of the table, the "header" is the name which will show on the header row. The order of the array will determine the ordering of the table columns. The "data" property is an array of objects. Each object should have properties named for each column defined in the "map" property. If no "map" was defined, the properties of the first object in the data array will be used to fill the "map" array. Both "data" and "map" may either be set in the kind definition, or by using their setters. Using either setMap() or setData() will immediately call for the table to be regenerated.
by wrexroad
CSS
th, td {
padding:0.4em;
border:1px solid #e0e0e0;
}
th {
color: grey
}
JavaScript
enyo.kind({
name: "DataTable",
published: {
map: [],
data: [],
noHeader: false
},
components: [
{kind: "Repeater", tag:"table", name: "dataRows", onSetupItem:"setupItem",
components: [
{kind: "Control", tag: "tr", name: "row"}
]}
],
create: function(){
this.inherited(arguments);
//rebuild the table with either the map or data are changed
this.mapChanged = this.dataChanged = enyo.bind(this, "buildTable");
//buid the table right now in case there were data set initially
this.buildTable();
},
buildTable: function(){
this.header = null;
//if there is no map set, create one based on
//the first data object's property names
if(this.map.length == 0){this.buildMap();}
//build a header if we need one and add it
//to the front of the data array
if(!this.noHeader){
this.buildHeader();
this.data.unshift(this.header);
}
this.loadData();
},
buildMap: function(){
if(this.map.length == 0){
var newMap = [];
var field_i = 0;
for(var prop in this.data[0]){
newMap[field_i] = {
field: prop,
header: prop
};
field_i++;
}
this.map = newMap;
}
},
buildHeader: function(){
this.header = {};
//create a header based on the map
for(var map_i = 0; map_i < this.map.length; map_i++){
this.header[this.map[map_i].field] = this.map[map_i].header;
}
},
loadData: function(){
//trigger the Repeater to reload the table
this.$.dataRows.setCount(this.data.length);
},
setupItem: function(source, event){
//since the header object was added to the start of the data...