Skip to content

Latest commit

 

History

History
308 lines (259 loc) · 7.38 KB

todo.md

File metadata and controls

308 lines (259 loc) · 7.38 KB

TO DO Example

app/addtodo.html

<!-- HTML template -->
<template id="todo-add">
    <form class="add-form">
        <h4 class="card-title">What I want to do?</h4>
        <div class="add-items d-flex"> 
            <input type="text" class="form-control todo-list-input todo" placeholder="What I want to do?"> 
            <button class="add btn btn-primary font-weight-bold todo-list-add-btn submit">Add</button> 
        </div>
    </form>
</template>

app/addtodo.js

import {Data, Collection, LazyCollection} from 'lizzi';
import {TodoCard} from './todocard';

import {Loader} from 'lizzi/DOM';
const T = Loader( require('./addtodo.html') );

export class AddTodo extends Data{
    createView(){
        return T.createView('#todo-add', this)
            .preventSubmit('.add-form')
            .input('input.todo', this.ref('todo'))
            .click('.submit', () => {
                this.collection.add( new TodoCard(this) );
                this.todo = '';
            });
    }
    
    constructor(collection){
        super();
        
        this.collection = collection;
        
        this.set({
            todo: ''
        });
    }
};

app/filter.html

<template id="no-todo-cards">
    <li>
        <h6> 
            Nothing TO DO...
        </h6>
    </li>
</template>

<template id="not-found-todo-cards">
    <li>
        <h6> 
            Nothing found...
        </h6>
    </li>
</template>

app/filter.js

import {Data, LazyCollection} from 'lizzi';

import {Loader} from 'lizzi/DOM';
const T = Loader( require('./filter.html') );

class NoTodos extends Data{
    createView(){
        return T.createView('#no-todo-cards', this);
    }
};

class NotFoundTodos extends Data{
    createView(){
        return T.createView('#not-found-todo-cards', this);
    }
};

export class SearchFilter extends LazyCollection{
    filter(values){
        //if empty
        if (values.length === 0){
            return [
                this.noToDos
            ];
        }
        
        values.forEach((v, i) => v.index = i+1);
        
        if (this.searchRef.value){
            let value = this.searchRef.value.toLowerCase();
            values = values.filter(d => d.todo.toLowerCase().indexOf(value) !== -1);
            
            //if not found
            if (values.length === 0){
                return [
                    this.notFoundToDos
                ];
            }
        }
        
        return values;
    }
    
    constructor(collection, searchRef){
        super(collection);
        
        this.searchRef = searchRef;
        this.noToDos = new NoTodos();
        this.notFoundToDos = new NotFoundTodos();
        
        this.searchRef.onSet(this.refresh, this);
    }
};

app/todocard.html

<template id="todo-card">
    <li>
        <div class="form-check"> 
            <label class="form-check-label"> 
                <span class="id"></span> <input class="checkbox" type="checkbox"> <i class="input-helper"></i> <span class="todo"></span>
            </label> 
        </div> 
        <i class="remove mdi mdi-close-circle-outline"></i>
    </li>
</template>

app/todocard.js

import {Data, Collection} from 'lizzi';

import {Loader} from 'lizzi/DOM';
const T = Loader( require('./todocard.html') );

export class TodoList extends Collection{
    constructor(todos){
        super();
        
        this.on('add', function(data){
            data.on('todo:remove', function(){
                this.remove(data);
            }, this);
        }, this);
        
        this.on('remove', function(data){
            data.off(this);
        }, this);
        
        this.add(todos);
    }
};

export class TodoCard extends Data{
    createView(){
        return T.createView('#todo-card', this)
            .text('.id', [this.ref('index'), '.'])
            .click('.remove', () => this.emit('todo:remove') )
            .checkbox('.checkbox', this.ref('done'))
            .class('li', this.ref('doneClass'))
            .text('.todo', this.ref('todo'));
    }
    
    constructor(data){
        super();
        
        this.set({
            todo: data.todo || '',
            done: data.done || false
        });

        this.set({
            index: 0,
            doneClass: ''
        });
        
        this.on('set:done', e => this.doneClass = this.done?'completed':'', this)
            .run();
    
        this.on(['set:todo', 'set:done'], () => this.emit('todo:change'), this);
    }
}

app/todo.html

<template id="todo-card">
    <li>
        <div class="form-check"> 
            <label class="form-check-label"> 
                <span class="id"></span> <input class="checkbox" type="checkbox"> <i class="input-helper"></i> <span class="todo"></span>
            </label> 
        </div> 
        <i class="remove mdi mdi-close-circle-outline"></i>
    </li>
</template>

<template id="todo">
    <div class="page-content page-container" id="page-content">
        <div class="row container d-flex justify-content-center">
            <div class="col-lg-12">
                <div class="card px-3">
                    <div class="card-body">
                        <h1>To do example...</h1>
                        <div class="d-flex"> 
                            <input type="text" class="form-control search" placeholder="Search tasks"> 
                        </div>
                        <div class="list-wrapper">
                            <ul class="d-flex flex-column todo-list"></ul>
                        </div>
                        <div class="add"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

app/todo.js

//import './todo.css';

import {Data, Collection} from 'lizzi';
import {AddTodo} from './addtodo';
import {SearchFilter} from './filter';
import {TodoCard, TodoList} from './todocard';

import {Loader} from 'lizzi/DOM';
const T = Loader( require('./todo.html') );

class TodoApp extends Data{
    createView(){
        return T.createView('#todo', this)
            .collection('.todo-list', this.cards, 'createView')
            .data('.add', this.addCard, 'createView')
            .input('.search', this.ref('search'));
    }
    
    constructor(WCards){
        super({
            search: ''
        });
        
        this.addCard = new AddTodo(WCards);
        
        this.cards = new SearchFilter(WCards, this.ref('search'));
    }
};

const TodoAppView = new TodoApp(new TodoList([
    new TodoCard({todo: 'Make new game', done: true}),
    new TodoCard({todo: 'Get profit'}),
    new TodoCard({todo: 'Figure it out'})
]));

const MyApp = new MainApp({
    title: 'To do App',
    app: TodoAppView.createView()
});

webpack.config.js

const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    context: path.resolve(__dirname, 'src'),
    mode: 'development',
    entry: {
        main: './app/todo.js'
    },
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist')
    },
    optimization: {
        splitChunks:{
            chunks: 'all'
        }
    },
    plugins: [
        new HTMLWebpackPlugin({
            template: './assets/index.html'
        })
    ],
    module:{
        rules: [
            {
                test: /\.html/,
                use: ['html-loader']
            }
        ]
    }
};