This is my 8th write up on dev.to site. I will show you Mithril component creating HTML table populated with data as two dimensional array.
Mithril JS
Mithril JS is an amazing JS framework, small and very effective. It can be used to program web/mobile apps, Single Page Applications (SPA). See the documentation for details.
Mithril component
There are many ways how to write component, one of them is JS object (a.k.a. POJO = Plain Old Javascript Object). Components can also receive and use data you put them.
Component table
We will write table component, so it creates HTML table and renders it into page in a browser.
var table = {
oninit: function(vnode){
/*
this.data = vnode.attrs.data,
this.title = vnode.attrs.title,
this.titleClass = vnode.attrs.titleClass
*/
self = vnode.attrs
},
view: function(vnode){
return m("div", [
m("table",
self.title
? m("tr",
m("td", {colspan: self.data[0].length, class: self.titleClass}, self.title)
)
: null,
self.data.map(function(tr){
return m("tr", tr.map(function(td){
return m("td", {class: "text-center"}, td)
})
)})
)
])
}
}
Let me explain my code. Table component consists of two functions - oninit(vnode) and view(vnode). Component (when used/called) receives one or more arguments (parameters) and both functions have access to them via vnode object.
---> oninit(vnode) function <---
Pay attentions to first one - oninit(vnode) - function. There are three commented lines of code; it is common way how to use parameters. Say, our component table needs data to create populated table's cells (html td tag). So, you write something like this:
oninit: function(vnode){
this.data = vnode.attrs.data
},
Everything looks good and works well, you are satisfied. Then you think about another parameter title. It would be great to have table with caption/title. Therefore you extend oninit(vnode) function and add second parameter:
oninit: function(vnode){
this.data = vnode.attrs.data,
this.title = vnode.attrs.title
},
Looks good, table is pretty and useful. Is there any improvement? Yeah, what about class for title to customise it? And number of parameters grows...
oninit: function(vnode){
this.data = vnode.attrs.data,
this.title = vnode.attrs.title,
this.titleClass = vnode.attrs.titleClass
},
This (common) way means to add another line of code to specify another parameter. But there is even better way: one object, and that is one line of code below three commented lines:
oninit: function(vnode){
self = vnode.attrs
},
This is a little trick. You assign all parameters as one object to another object named self.
You can simply use any of parameters this way:
self.title
instead of (common) way:
this.title
--> view(vnode) function <---
This is a place where all magic happens :-) At the begining div tag is created (useful for horizontal shift when table is too wide), then table tag and optionally one row with one cell with title of table.
Data are iterated by map function, first it creates rows - tr tags - dependeded of y-dimension of data. Inside rows is another iteration by map function walking each piece of data in x-dimension.
Example of two data arrays we use for our table component:
var data1 = [
[-2, -1, 0, 1, 2],
[3, 3, 3, 3, 3],
[-5, -3, 0, 42, 99]
];
var data2 = [
["John", "Marry", "Peter"],
[2003, 2007, 2001],
["student", "writer", "worker"]
];
Our table component simply gets data and creates corresponding rows and cols derived from data array.
use of table component
With the use of data1 and data2 arrays we use table component like this:
m(table, {data: data1, title: "Numbers", titleClass: "text-red text-center text-bold"})
m(table, {data: data2})
Live example is at this flems.io link.
Hope this is useful for you :-)
Top comments (1)
Thank you :-)