<!DOCTYPE html>
<html>

<head>
  <link href="//cdn.jsdelivr.net/picnicss/4.1.1/picnic.min.css" rel="stylesheet">
  <link rel="stylesheet" href="style.css">
  <meta charset="utf-8">
  <title>Mag.JS</title>
</head>

<body>

  <nav>
    <h1>Hello Mag.JS!</h1>
    <a target="_tab" href="https://github.com/magnumjs/mag.js">GitHub</a>
  </nav>

  <article class="card">
    <header>
      <h2>List Things!</h2>
    </header>

    <footer>
      <div id="app">
        <div id="form">
          <form>
            <label>Name</label>
            <input name="name">
            <label>Email</label>
            <input name="email">
            <button class="mainButton">Save</button>
          </form>
        </div>
        <div id="list">
          <ul>
            <li>
              <name></name>
              <email></email>
              <button class="edit">/</button>
              <button class="remove">X</button>
            </li>
          </ul>
        </div>
      </div>
    </footer>
  </article>


  <script src="//rawgit.com/magnumjs/mag.js/master/mag-latest.min.js"></script>
  <script src="//rawgit.com/magnumjs/mag.js/master/dist/mag.addons.0.22.min.js"></script>

  <script src="list.js"></script>
  <script src="form.js"></script>
  <script src="app.js"></script>

</body>

</html>
var app = {}

app.controller = function(props) {

  this.entryList = mag.module('list', lister, props);

  this.entryForm = mag.module('form', former, props);

}

var props = {
  entries: [{
    name: 'Mike',
    email: 'test'
  }, {
    name: 'Sarah',
    email: 'that'
  }]
}

mag.module("app", app, props)
li:empty,
.hide {
  display: none;
}

a {
  display: block;
}

a:after {
  content: " \bb";
}

.mainButton {
  font-size: 1.5em;
}

nav a {
  float: right;
  margin-top: -50px;
}

body {
  background: #fff;
  text-align: left;
  width: 90%;
  max-width: 960px;
  margin: 0 auto;
  padding: 20px 0 0;
}

nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3em;
  padding: 0 .6em;
  background: #fff;
  box-shadow: 0 0 0.2em rgba(17, 17, 17, 0.2);
  z-index: 10000;
  transition: all .3s;
  transform-style: preserve-3d;
}

header {
  font-weight: bold;
  position: relative;
  border-bottom: 1px solid #eee;
  padding: .6em .8em;
}

footer {
  padding: .8em;
}

article {
  top: 100px;
}

.card {
  max-width: 100%;
  display: block;
  position: relative;
  box-shadow: 0;
  border-radius: .2em;
  border: 1px solid #ccc;
  overflow: hidden;
  text-align: left;
  background: #fff;
  margin-bottom: .6em;
  padding: 6px;
  transition: all .3s ease;
}
#Mag.JS

## plunk boilerplate of "Things"

Basic Mag.JS boilerplate to count and create a list of things dynamically.

https://github.com/gilbert/blog-post-examples/blob/gh-pages/mithril-2/
var lister = {}

lister.remove = function(id, entries) {
  entries.splice(id, 1);
}

lister.edit = function(index){
  window.location.hash = "editId=" + index;
}

lister.view = function(state, props) {

  state.ul = props.entries.map(function(item, index) {
    return {
      li: {
        remove: {
          _onClick: lister.remove.bind({}, index, props.entries)
        },
        edit:  {
          _onClick: lister.edit.bind({}, index)
        },
        name: item.name,
        email: item.email
      }
    }
  })

}
var former = {}

former.controller = function(props) {
  window.onhashchange = function(event) {
    if (location.hash.substr(8)) {
      props.editId = location.hash.substr(8);
    }
  }
}

former.view = function(state, props) {

  state.form = {
    name: '',
    email: ''
  };

  if (props.editId !== undefined) {
    state.form = props.entries[props.editId];
    state.button = 'Save change';
  } else {
    state.button = 'Save new';
  }

  state.form._onSubmit = function() {

    if (props.editId !== undefined) {
      props.entries[props.editId] = {
        name: state.name,
        email: state.email
      };

      props.editId = undefined;
      state.name = undefined;
      state.email = undefined;

      window.location.hash = "add";

    } else {
      props.entries.push({
        name: state.name,
        email: state.email
      });
    }

    return false;
  }

}