DEV Community

Pavel Kříž
Pavel Kříž

Posted on • Updated on

Mithril JS + Quasar CSS + mithril stream + UI (pages) -> real app

This is my 9th write up on dev.to site. Example of a real app using Mithril JS, Quasar CSS, mithril stream and UI based on more pages with dynamic switching. Full source code is included as a flems.io link.

My first attempt and example of both Mithril JS and Quasar CSS is described here:
https://dev.to/pablo_74/mithril-js-quasar-css-here-is-the-proof-4e7c, I bring an example of a real app today.

App layout (mobile app)

My example of the app is based on Quasar layout; it consists of three parts. The top one is a header with color background and title, the central one is page content (dynamically switched by user interaction) and the bottom one is a footer with 'buttons' (not real HTML buttons) for switching content.

App's header

The header is a simple component with Quasar's classes and a title.

var header = {
  view: function(vnode){
    return m("header", {class: "q-header q-layout__section--marginal fixed-top", style: {"background-color":"#FF9900", color:"white"}}, 
      [
        m("div", {class: "q-toolbar row no-wrap items-center", role: "toolbar"}, 
          m("div", {class: "q-toolbar__title ellipsis"}, 
            m("div", {class: "text-big absolute-center text-bold"}, 
              vnode.attrs.title
            )
          )
        ), 
        m("div", {class: "q-layout__shadow absolute-full overflow-hidden no-pointer-events"})
      ]
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

App's footer

The footer is the simple component too with Quasar's classes and a row with columns (count depends of number of pages). Each page has a title and this is shown on the footer component. Each of them has an onclick event and assigns name of page to a mithril stream variable named showPage.

var showPage = stream("page1");
Enter fullscreen mode Exit fullscreen mode
var footer = {
  view: function(){
    return m("footer", {class: "q-footer q-layout__section--marginal fixed-bottom q-px-none", style: {"background-color": "#FF9900", color: "black"}}, 
      m("div", {class: "q-toolbar row no-wrap items-center", role: "toolbar"}, 
        m("div", {class: "q-toolbar__title ellipsis"}, 
          m("div", {class: "row q-pa-none"}, 
            pages.map(function(page){
              return m("div", {class: "col center q-pa-none"}, 
                m("div", {class: showPage() == page.name ? "page-active text-center text-bold " : 'text-center text-bold ', onclick: function(){showPage(page.name)}}, 
                  m("span", {}, page.title)
                )
              )
            })
          )
        )
      )
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

App's page content

The most important part of the app. It is a container, the requested page (selected by user in footer) shows it's content inside it.

var pageContent = {
  view: function(){
    return m("div", {class: "q-layout q-layout--standard", tabindex: "-1"}, 
      m("div", {class: "q-page-container q-pa-none", style: {"padding-top":"50px", "padding-bottom": "50px"}}, 
        m("div", {class: "q-pa-md"}, 
          pages.map(function(page){
            if (page.name == showPage()) return m(page.comp)
          }),           
        )
      )
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

The magic part of switching content is here:

pages.map(function(page){
  if (page.name == showPage()) return m(page.comp)
}),
Enter fullscreen mode Exit fullscreen mode

App's pages

Pages are simple components like:

var page4 = {
  view: function(){
    return m("div", [
        m("h4", "This is 'about' page"),
        m("p", "Lorem ipsum dolor sit amet, ...")
    ])
  }
}
Enter fullscreen mode Exit fullscreen mode

It is not all of definitions, we need something more. An array of objects describing each page with name, title, and comp (=component) keys.

var pages = [
  {
    name: "page1",
    title: "theory",
    comp: page1,        // component
  },
  {
    name: "page2",
    title: "exerc.",
    comp: page2,        // component
  },
  {
    name: "page3",
    title: "sett.",
    comp: page3,        // component
  },
  {
    name: "page4",
    title: "about",
    comp: page4,        // component
  },  
]
Enter fullscreen mode Exit fullscreen mode

This array is used by footer component (number of columns and their names) and pageContent component (switching content).

Example of real app

Full source code of CSS and JS (as described above) is on flems.io I hope it inspires you :-)

Top comments (1)

Collapse
 
artydev profile image
artydev

Mithril is one of my favorite library.
Thank you :-)