<!doctype html>
<html>
  <head>
    <title>Riot Router: Complex example</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="stylesheet" href="style.css">
  </head>

  <body>
    <app></app>

    <!-- riot tags -->
    <script type="riot/tag" src="app.tag"></script>
    <script type="riot/tag" src="detail.tag"></script>

    <!-- scripts we need -->
    <script src="https://rawgit.com/riot/riot/master/riot%2Bcompiler.min.js"></script>
    <script src="https://rawgit.com/riot/route/master/dist/route.min.js"></script>
    <script src="riotcontrol.js"></script>
    <script src="store.js"></script>

    <!-- fire this app -->
    <script src="app.js"></script>

  </body>
</html>
/* RiotControl v0.0.3, @license MIT */
var RiotControl = {
  _stores: [],
  addStore: function(store) {
    this._stores.push(store);
  },
  reset: function() {
    this._stores = [];
  }
};

['on','one','off','trigger'].forEach(function(api){
  RiotControl[api] = function() {
    var args = [].slice.call(arguments);
    this._stores.forEach(function(el){
      el[api].apply(el, args);
    });
  };
});

if (typeof(module) !== 'undefined') module.exports = RiotControl;
/* Styles go here */
body {
  font-family: 'myriad pro', sans-serif;
  font-size: 20px;
  border: 0;
}

a {
  text-decoration: none;
  color: grey;
}

app {
  display: block;
  max-width: 400px;
  margin: 5% auto;
}

form {
  margin-bottom: 1em;
}

input {
  font-size: 100%;
  padding: .6em;
  border: 1px solid #ccc;
  border-radius: 4px;
  float: left;
}

button {
  background-color: #1FADC5;
  border: 1px solid rgba(0,0,0,.2);
  font-size: 100%;
  color: #fff;
  padding: .6em 1.2em;
  border-radius: 3em;
  cursor: pointer;
  margin: 0 .3em;
  outline: none;
}

button[disabled] {
  background-color: #ddd;
  color: #aaa;
}

ul {
  padding: 0;
}

li {
  list-style-type: none;
  padding: .2em 0;
}

.completed {
  text-decoration: line-through;
  color: #ccc;
}

label {
  cursor: pointer;
}
const itemStore = new ItemStore()
RiotControl.addStore(itemStore)

// mount tag
riot.mount('app', {
   title: 'Routing Demo App with RiotControl'
})

// Define router function
const router = (page,id) => {
   if (page == 'add')
        RiotControl.trigger('route_item_add')
   else
        RiotControl.trigger('route_item', id)
}

// Riot router
route(router)
// Execute router function once for rendering the items
route.start(router);
<app>
  <h2>{ opts.title }</h2>
  <div if={ !edit }>
		<span>Search:</span>
		<br/>
		<input ref='input' onkeyup={ search }>
		<form onsubmit={ clear }>
			<button disabled={ !txt }>Clear</button>
		</form>
		<ul>
			<li each={ items }>
				<a href={ '#view/' + id }>{ title }</a>
			</li>
		</ul>

		<detail item={ detail }></detail>
		<div if={ !detail }>
			<span>Choose a product.</span>
		</div>
		<br/>
		<div>
			<button onclick={ add }>Add</button>
		</div>
	</div>
	<div if={ edit }>
		<form onsubmit={ submit }>
			<input ref='title'>
			<button>Submit</button>
		</form>
		<button onclick={ cancel }>Cancel</button>
	</div>

  <script>
	const self = this

	self.items = []
	self.txt = null
	self.detail = null
	self.edit = false	

	search(e) {
		self.txt = e.target.value
		RiotControl.trigger('item_list_search', self.txt)
	}

	clear(e) {
	  e.preventDefault()
		self.txt = ''
		this.refs.input.value = ''
		RiotControl.trigger('item_list_search','')	
	}

	add(e) {
		route('add')
	}

	submit(e) {
	  e.preventDefault()
		RiotControl.trigger('item_detail_add', this.refs.title.value)
		this.refs.title.value = ''
		this.edit = false
		route('view')
	}

	cancel(e) {
	  e.preventDefault()
		this.refs.title.value = ''
		this.edit = false
		route('view')
	}

	self.on('mount', function() {
		RiotControl.trigger('item_list_init')
	})

	RiotControl.on('item_list_changed', (items) => {
		 self.items = items
		 self.update()
	})

	RiotControl.on('item_detail_changed', (item) => {
		 self.edit = false
	   self.detail = item
	   riot.update()
	})

	RiotControl.on('item_detail_create', () => {
		 self.edit = true
		 self.update()
	})
  </script>
</app>
<detail>
	<div if={ opts.item }>
		<h3>Item Details</h3>
		<div><b>ID:</b> { opts.item.id }</div>
		<div><b>Name:</b> { opts.item.title }</div> 
	</div>
</detail>
function ItemStore() {  
  riot.observable(this)

  const self = this

  // Could pull this from a server API.
  self.items = [
    { id: 1, title: 'Foobar' },
    { id: 2, title: 'Foobaz' },
    { id: 3, title: 'Barbar' }
  ]

  // Init our list view.
  self.on('item_list_init', () => {
    self.trigger('item_list_changed', self.items)
  })

  // Search our item collection.
  self.on('item_list_search', (txt) => {
    var list = self.items
    if (txt.length > 0)
      list = self.items.filter((el) => {
        if (el.title.toLowerCase().search(new RegExp(txt.toLowerCase())) == -1)
          return false
        else
          return true
      })

    self.trigger('item_list_changed', list)
  })

  // Add to our item collection.
  // Could push this to a server API.
  self.on('item_detail_add', (title) => {
    self.items.push({ id: self.items.length+1, title: title })
    self.trigger('item_list_changed', self.items)
  })

  // Pull item for URL route. (id)
  self.on('route_item', (id) => {
    console.info(id)
    let item = null
    self.items.forEach((el) => {
      if (el.id == id)
        item = el
    })
    self.trigger('item_detail_changed', item)
  })

  // Emit event for add item route.
  self.on('route_item_add', () => {
    self.trigger('item_detail_create')
  })

}