backbone todos

<!DOCTYPE html>

<html>

<head>

    <meta charset="UTF-8">

    <title></title>

    <style>

        *{

            margin: 0;

            padding: 0;

        }

        body{

            background-color: #eaeaea;

            font: 14px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;

        }

        header,section,footer{

            display: block;

        }

        #todo{

            width: 500px;

            margin: 0 auto;

            background-color: white;

            padding: 20px;

            border-radius: 0 0 8px 8px;

            -webkit-box-shadow: 0px 1px 4px 2px #bababa;

        }

        header>h1{

            text-align: center;

            margin: 10px 0 20px 0;

        }

        header>input{

            /*display: block;*/

            line-height: 28px;

            font-size: 25px;

            font-style: italic;

            padding: 6px;

            margin-bottom: 5px;

            width: 100%;

            box-sizing: border-box;

            outline: none;

        }

        .views{

            display: none;

        }

        .views>p{

            height: 25px;

            line-height: 25px;

            margin-bottom: 10px;

        }

        .views>p>*{

            vertical-align: middle;

        }

        #select-all{

            margin-right: 5px;

        }

        .todoList>li{

            list-style-type: none;

            position: relative;

            padding: 10px 0;

            font-size: 24px;

        }

        .todoList>li>.view>*{

            vertical-align: middle;

            height: 30px;

            line-height: 30px;

        }

        .edit{

            display: none;

            position: absolute;

            top: 0px;

            left: 0px;

            padding: 0 20px;

            width: 460px;

            font-size: 25px;

            height: 50px;

            line-height: 40px;

            outline: none;

        }

        .todoList>li:hover>.view .destroy{

            display: block;

        }

        .todoList>li>.view .destroy{

            float: right;

            width: 16px;

            height: 16px;

            margin-top: 12px;

            line-height: 16px;

            text-align: center;

            border-radius: 10px;

            background-color: #d1d1d1;

            color: white;

            font-size: 12px;

            display: none;

        }

        .todoList>li .destroy:hover{

            cursor: pointer;

            background-color: #b1b1b1;

        }

        .select label{

            text-decoration: line-through;

            color: #a1a1a1;

        }

        footer{

            background-color: #f4fce8;

            margin: 0 -20px;

            margin-bottom: -20px;

            margin-top: 20px;

            padding: 10px 20px 10px 20px;

            display: none;

            border-radius: 0 0 8px 8px;;

        }

        #clear-complete{

            float: right;

            font-size: 12px;

            padding: 2px 10px;

            border-radius: 10px;

            background-color: #d1d1d1;

        }

        #clear-complete:hover{

            cursor: pointer;

            background-color: #a1a1a1;

        }

    </style>

</head>

<body>

<div id="todo">

    <header>

        <h1>Todos</h1>

        <input type="text" id="new-todo" placeholder="What needs to be done?"/>

    </header>

    <section>

        <p><input type="checkbox" id="select-all"/><label for="select-all">Mark all as complete</label></p>

        <ul>

        </ul>

    </section>

    <footer></footer>

</div>



<script src="jquery-1.11.2.min.js"></script>

<script src="handlebars-v3.0.0.js"></script>

<script src="json2.js"></script>

<script src="underscore.js"></script>

<script src="backbone.js"></script>

<script type="text/x-handlebars-template" id="todo-template">

    <div>

        <input type="checkbox"{{#if done}} checked {{else}} '' {{/if}}/>

        <label for="">{{title}}</label>

        <a>X</a>

    </div>

    <input type="text" value="{{title}}"/>

</script>

<script type="text/x-handlebars-template" id="footer-template">

    {{#if done}}

    <a id="clear-complete">

        Clear <b>{{done}}</b> completed

    </a>

    {{/if}}

    <div id="todo-count">

        <strong>{{remaining}}</strong> items left

    </div>

</script>

<script>

    var Todo = Backbone.Model.extend({

        defaults: {

            title: "empty title",

            done: false

        },

        toggle: function(){

            this.set('done', !this.get('done'));

        }

    })

    var TodoS = Backbone.Collection.extend({

        model: Todo,

        done: function(){

            return this.where({done: true}).length;

        },

        initialize: function(){

        },

        remaining: function(){

            return this.where({done: false}).length;

        },

        destroyView: function(model){

            this.remove(model);

        }

    })

    var todoS = new TodoS;

    var TodoView = Backbone.View.extend({

        tagName: 'li',

        template: Handlebars.compile($('#todo-template').html()),

        initialize: function(){

            this.listenTo(this.model, 'change', this.render);

            this.listenTo(this.model, 'remove', this.destroyView);

        },

        events: {

            "click .toggle": "toggleDown",

            "click .destroy": "destroyView",

            "dblclick .view": "edit",

            "blur .edit": "saveEdit",

            "keypress .edit": "saveEdit"

        },

        render: function(){

            this.$el.html(this.template(this.model.toJSON()));

            if(this.model.get('done')){

                this.$el.addClass('select');

            }else{

                this.$el.removeClass('select');

            }

            return this;

        },

        toggleDown: function(){

            this.model.toggle();

        },

        destroyView: function(){

            this.remove();

            todoS.destroyView(this.model);

        },

        edit: function(){

            this.$('.edit').show();

            this.$('.edit').focus();

        },

        saveEdit: function(e){

            if(e.charCode == 13 || !e.charCode){

                this.model.set('title', this.$('.edit').val());

                this.$('.edit').hide();

            }

            if(this.$('.edit').val() == ""){

                todoS.remove(this.model);

            }

        }

    })

    var AppView = Backbone.View.extend({

        el: $('#todo'),

        footerTemplate: Handlebars.compile($('#footer-template').html()),

        initialize: function(){

            this.input = this.$("#new-todo");

            this.listenTo(todoS, 'add', this.addNewView);

            this.listenTo(todoS, 'all', this.render);

            this.footer = this.$('footer');

            this.views = this.$('.views');

            this.toggleAll = this.$('#select-all');

            this.firstRender();

        },

        events: {

            "keypress #new-todo": "createEnter",

            "click #select-all": "toggleAllComplete",

            "click #clear-complete": "removeSelect"

        },

        addNewView: function(model){

            var todoView = new TodoView({model: model});

            this.$('.todoList').append(todoView.render().$el)

        },

        render: function(){

            if(todoS.length){

                this.views.show();

                this.footer.html(this.footerTemplate({done: todoS.done(), remaining: todoS.remaining()}));

                this.footer.show();

            }else{

                this.views.hide();

                this.footer.hide();

            }

            var flag = true;

            todoS.each(function(model){

                if(!model.get('done')){

                    flag = false;

                }

            })

            this.toggleAll[0].checked = flag;

            localStorage.setItem('todoS', JSON.stringify(todoS));

        },

        createEnter: function(e){

            if(e.keyCode != 13) return 1;

            if(this.input.val()==null || this.input.val().match(/^\s*$/)) return 1;

            todoS.add({title: this.input.val()});

            this.input.val('');

        },

        toggleAllComplete: function(){

            var done = this.toggleAll[0].checked;

            todoS.each(function(model){

                model.set('done', done);

            })

        },

        removeSelect: function(){

            var len = todoS.models.length;

            while(len){

                if(todoS.models[len-1].get('done')){

                    todoS.destroyView(todoS.models[len-1]);

                }

                len--;

            }

        },

        firstRender: function(){

            var todoArr = JSON.parse(localStorage.getItem('todoS'));

            todoArr.forEach(function(todo){

                todoS.add(todo);

            })

            if(todoArr >= 1){

                todoArr.each(function(todo){

                    console.log(todo)

                    todoS.add(todo);

                })

            }

            console.log(todoS)

        }

    })

    var appView = new AppView;

</script>

</body>

</html>


转载于:https://my.oschina.net/u/1992917/blog/391433

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值