<!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>
      <h3>Book Shop</h3>
    </header>

    <footer>
      <div id="app">
        <input name="text" placeholder="Filter" autocomplete="off">
        <ul id="store-books">
          <li class="book">
            <span class="name">The Iliad <cost>  <price>12</price></cost>
            </span>
            <button class="right">Add</button>
          </li>
        </ul>
        <hr>
        <h3>Cart</h3>
        <ul id="store-cart">
          <li class="cart">
            <span></span>
            <button class="right">Remove</button>
          </li>
        </ul>
        <strong>Total: </strong>
        <span>$<total></total></span>
      </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-view.js"></script>
  <script src="app.js"></script>

</body>

</html>
var app = {}

app.controller = function(props) {

  // fetch array of book objects from server of form:

  this.books = mag.request({
    method: 'GET',
    url: props.url
  });

  this.cart = mag.prop([]);
  this.text = '';

  this.total = () => {
    return this.cart().reduce(function(prev, next) {
      return prev + next.price;
    }, 0);
  }

  this.shop = () => {
    return this.books.filter((book) => {
      return book.name.toLowerCase()
        .indexOf(this.text.toLowerCase()) > -1 &&
        this.cart().indexOf(book) === -1;
    });
  };


  this.addToCart = (book) => {
    this.cart(this.cart().concat(book));
    instance.draw()
  };

  this.removeFromCart = (book) => {
    this.cart(
      this.cart().filter((item) => item !== book)
    );
    instance.draw()
  }

}

app.view = function(state, props) {

  if (state.books.length) {
    //  state.book = state.books;
    mag.module('store-books', ListView, {
      items: state.shop(),
      action: state.addToCart,
      actionLabel: 'Add'
    });

    mag.module('store-cart', ListView, {
      items: state.cart(),
      action: state.removeFromCart,
      actionLabel: 'Remove'
    });

  } else {
    state.book = {
      span: 'Loading..'
    }
  }

}

var props = {
  url: 'https://api.myjson.com/bins/a7r7p',
  things: []
}

var instance = 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;
}


/** specific styles **/

.right {
  right: -100px;
}
#Mag.JS

## plunk boilerplate of "Things"

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

From: https://mithril-examples.firebaseapp.com/applications
var ListView = {
  view: function(state, props) {

    state.li = props.items ?
      props.items.map(function(book, i) {

        return {
          key: i,
          span: book.name,
          price: '$' + book.price,
          button: {
            _text: props.actionLabel,
            _onclick: function() {
              props.action(book);
            }
          }
        }
      }) : 'Loading...'

  }
};