Ractive-Redux Todo

by vikikamath

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.min.js"></script>
<main></main>

<script id="list" type="text/ractive">
	<ul id="todos">
  	{{#kind(type): i}}
    <Todo index="{{i}}" item="{{.}}"/>
   	{{/}}
  </ul>
</script>

<script id="item" type="text/ractive">
	<li class="{{#complete}}complete{{/complete}}" on-click="toggleState:{{index}}">{{text}}<span on-click="remove:{{index}}">x</span></li>
</script>

<script id="in" type="text/ractive">
	<input type="text" placeholder="Enter" value="{{val}}"/> <button on-click="add:{{val}}"> Add </button>
</script>

<script id="filters" type="text/ractive">
	<ul id="filters">
    {{#filters:i}}
    <li class="{{#if current === .}}active{{/if}}" on-click="filterSelected:{{.}}">{{.}}</li>
    {{/filters}}
    </ul>
</script>

CSS

* {
  list-style: none
}

#todos li.complete {
  text-decoration: line-through;
}

#todos li span {
  margin-left: 2rem;
  color: blue;
}


#filters li{
  display: inline-block;
  margin: 1rem;
}

#filters li.active {
  color: blue;
  text-decoration: underline;
}

JavaScript

var Todo = Ractive.extend({
	template: `#item`
  
})

var TodoList = Ractive.extend({
	template: `#list`
  ,components: {
  	Todo
  }
  ,data() {
  	return {
    	items: []
      ,type: 'ALL'
      ,kind: (type) => this.get(type)
    }
  }
  ,computed: {
  	ALL: '${items}'
    ,COMPLETE: () => this.get("items").filter((item) => {
      		return item.complete;
      	})
    ,INCOMPLETE: () => this.get('items').filter((item) =>{
      		return item.complete;
      	})
  }
  ,oninit() {
  	var self = this;
    self.root.on('add', (val) => {
    	self.push('items', {
      	complete: false
        ,text: val
      })
    })
    
    self.on('Todo.toggleState', (_,index) => {
    	self.set('items.' +index+'.complete', !self.get('items.'+index+'.complete'))
      
      console.log(self.get('COMPLETE'))
    })
    
    self.on('Todo.remove', (_, index) => {
    	self.splice('items', index, 1);
    })
    
    self.root.on('filterSelected', (type) =>{
    		self.set('type', type)
    })
  }
})
var Input = Ractive.extend({
	template: `#in`
  ,data() {
  	return {
    	val: ''
    }
  }
  ,oninit() {
  	var self = this;
    self.on('add', (e) =>{
    	console.log(e)
      self.root.fire('add', e.context.val);
    })
  }
})

var FilterList = Ractive.extend({
	template: `#filters`
  ,data() {
  	
    return  {
    	filters: [
      	'ALL'
        ,'COMPLETE'
        ,'INCOMPLETE'
      ]
      ,current: 'ALL'
    }
   
  }
  ,oninit( ) {
  	var self = this
    self.root.fire('filterSelected', self.get('current'));
    self.on('filterSelected', (_, sel) => {
    		self.set('current', sel);
        self.root.fire('filterSelected', sel);
    })
  }
})

var app = new Ractive({
	el: `main`
  ,template: `<Input/><TodoList/><FilterList />`
  ,components: {
  	TodoList
    ,FilterList
    ,Input
  }
})