• backbone todo example


    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
    html,
    body {
      margin: 0;
      padding: 0;
    }
    
    body {
      font: 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
      line-height: 1.4em;
      background: #eeeeee;
      color: #333333;
      width: 520px;
      margin: 0 auto;
      -webkit-font-smoothing: antialiased;
    }
    
    #todoapp {
      background: #fff;
      padding: 20px;
      margin-bottom: 40px;
      -webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
      -moz-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
      -ms-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
      -o-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
      box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
      -webkit-border-radius: 0 0 5px 5px;
      -moz-border-radius: 0 0 5px 5px;
      -ms-border-radius: 0 0 5px 5px;
      -o-border-radius: 0 0 5px 5px;
      border-radius: 0 0 5px 5px;
    }
    
    #todoapp h1 {
      font-size: 36px;
      font-weight: bold;
      text-align: center;
      padding: 0 0 10px 0;
    }
    
    #todoapp input[type="text"] {
      width: 466px;
      font-size: 24px;
      font-family: inherit;
      line-height: 1.4em;
      border: 0;
      outline: none;
      padding: 6px;
      border: 1px solid #999999;
      -webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
      -moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
      -ms-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
      -o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
      box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
    }
    
    #todoapp input::-webkit-input-placeholder {
      font-style: italic;
    }
    
    #main {
      display: none;
    }
    
    #todo-list {
      margin: 10px 0;
      padding: 0;
      list-style: none;
    }
    
    #todo-list li {
      padding: 18px 20px 18px 0;
      position: relative;
      font-size: 24px;
      border-bottom: 1px solid #cccccc;
    }
    
    #todo-list li:last-child {
      border-bottom: none;
    }
    
    #todo-list li.done label {
      color: #777777;
      text-decoration: line-through;
    }
    
    #todo-list .destroy {
      position: absolute;
      right: 5px;
      top: 20px;
      display: none;
      cursor: pointer;
      width: 20px;
      height: 20px;
      background: orange;
      border-radius: 10px;
    }
    
    #todo-list li:hover .destroy {
        display: block;
    }
    
    #todo-list .destroy:hover {
        background-position: 0 -20px;
    }
    
    #todo-list li.editing {
      border-bottom: none;
      margin-top: -1px;
      padding: 0;
    }
    
    #todo-list li.editing:last-child {
      margin-bottom: -1px;
    }
    
    #todo-list li.editing .edit {
      display: block;
      width: 444px;
      padding: 13px 15px 14px 20px;
      margin: 0;
    }
    
    #todo-list li.editing .view {
      display: none;
    }
    
    #todo-list li .view label {
      word-break: break-word;
    }
    
    #todo-list li .edit {
      display: none;
    }
    
    #todoapp footer {
      display: none;
      margin: 0 -20px -20px -20px;
      overflow: hidden;
      color: #555555;
      background: #f4fce8;
      border-top: 1px solid #ededed;
      padding: 0 20px;
      line-height: 37px;
      -webkit-border-radius: 0 0 5px 5px;
      -moz-border-radius: 0 0 5px 5px;
      -ms-border-radius: 0 0 5px 5px;
      -o-border-radius: 0 0 5px 5px;
      border-radius: 0 0 5px 5px;
    }
    
    #clear-completed {
      float: right;
      line-height: 20px;
      text-decoration: none;
      background: rgba(0, 0, 0, 0.1);
      color: #555555;
      font-size: 11px;
      margin-top: 8px;
      margin-bottom: 8px;
      padding: 0 10px 1px;
      cursor: pointer;
      -webkit-border-radius: 12px;
      -moz-border-radius: 12px;
      -ms-border-radius: 12px;
      -o-border-radius: 12px;
      border-radius: 12px;
      -webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
      -moz-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
      -ms-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
      -o-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
      box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
    }
    
    #clear-completed:hover {
      background: rgba(0, 0, 0, 0.15);
      -webkit-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
      -moz-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
      -ms-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
      -o-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
      box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
    }
    
    #clear-completed:active {
      position: relative;
      top: 1px;
    }
    
    #todo-count span {
      font-weight: bold;
    }
    
    #instructions {
      margin: 10px auto;
      color: #777777;
      text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
      text-align: center;
    }
    
    #instructions a {
      color: #336699;
    }
    
    #credits {
      margin: 30px auto;
      color: #999;
      text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
      text-align: center;
    }
    
    #credits a {
      color: #888;
    }
        </style>
    </head>
    <body>
        <div id="todoapp">
    
        <header>
          <h1>Todos</h1>
          <input id="new-todo" type="text" placeholder="What needs to be done?">
        </header>
    
        <section id="main">
          <input id="toggle-all" type="checkbox">
          <label for="toggle-all">Mark all as complete</label>
          <ul id="todo-list"></ul>
        </section>
    
        <footer>
          <a id="clear-completed">Clear completed</a>
          <div id="todo-count"></div>
        </footer>
    
      </div>
    
      <div id="instructions">
        Double-click to edit a todo.
      </div>
    
    <!-- Templates -->
    
      <script type="text/template" id="item-template">
        <div class="view">
          <input class="toggle" type="checkbox" <%= done ? 'checked="checked"' : '' %> />
          <label><%- title %></label>
          <a class="destroy"></a>
        </div>
        <input class="edit" type="text" value="<%- title %>" />
      </script>
    
      <script type="text/template" id="stats-template">
        <% if (done) { %>
          <a id="clear-completed">Clear <%= done %> completed <%= done == 1 ? 'item' : 'items' %></a>
        <% } %>
        <div class="todo-count"><b><%= remaining %></b> <%= remaining == 1 ? 'item' : 'items' %> left</div>
      </script>
    
        
        <script src="lib/json2.js"></script>
        <script src="lib/jquery-latest.js"></script>
        <script src="lib/underscore.js"></script>
        <script src="lib/backbone.js"></script>
        <script src="lib/backbone.localStorage.js"></script>
        <script src="js/demo20.js"></script>
    </body>
    </html>
    $(function(){
      var Todo = Backbone.Model.extend({
        defaults: function() {
          return {
            title: "empty todo...",
            order: Todos.nextOrder(),
            done: false
          };
        },
    
        initialize: function() {
          if (!this.get("title")) {
            this.set({"title": this.defaults().title});
          }
        },
    
        toggle: function() {
          this.save({done: !this.get("done")});
        }
    
      });
    
      var TodoList = Backbone.Collection.extend({
    
        model: Todo,
    
        localStorage: new Backbone.LocalStorage("todos-backbone"),
    
        done: function() {
          return this.filter(function(todo){ return todo.get('done'); });
        },
    
        remaining: function() {
          return this.without.apply(this, this.done());
        },
    
        nextOrder: function() {
          if (!this.length) return 1;
          return this.last().get('order') + 1;
        },
    
        comparator: function(todo) {
          return todo.get('order');
        }
    
      });
    
      var Todos = new TodoList;
    
      var TodoView = Backbone.View.extend({
    
        tagName:  "li",
    
        template: _.template($('#item-template').html()),
    
        events: {
          "click .toggle"   : "toggleDone",
          "dblclick .view"  : "edit",
          "click a.destroy" : "clear",
          "keypress .edit"  : "updateOnEnter",
          "blur .edit"      : "close"
        },
    
        initialize: function() {
          this.listenTo(this.model, 'change', this.render);
          this.listenTo(this.model, 'destroy', this.remove);
        },
    
        render: function() {
          this.$el.html(this.template(this.model.toJSON()));
          this.$el.toggleClass('done', this.model.get('done'));
          this.input = this.$('.edit');
          return this;
        },
    
        toggleDone: function() {
          this.model.toggle();
        },
    
        edit: function() {
          this.$el.addClass("editing");
          this.input.focus();
        },
    
        close: function() {
          var value = this.input.val();
          if (!value) {
            this.clear();
          } else {
            this.model.save({title: value});
            this.$el.removeClass("editing");
          }
        },
    
        updateOnEnter: function(e) {
          if (e.keyCode == 13) this.close();
        },
    
        clear: function() {
          this.model.destroy();
        }
    
      });
    
      var AppView = Backbone.View.extend({
    
        el: $("#todoapp"),
    
        statsTemplate: _.template($('#stats-template').html()),
    
        events: {
          "keypress #new-todo":  "createOnEnter",
          "click #clear-completed": "clearCompleted",
          "click #toggle-all": "toggleAllComplete"
        },
    
        initialize: function() {
    
          this.input = this.$("#new-todo");
          this.allCheckbox = this.$("#toggle-all")[0];
    
          this.listenTo(Todos, 'add', this.addOne);
          this.listenTo(Todos, 'reset', this.addAll);
          this.listenTo(Todos, 'all', this.render);
    
          this.footer = this.$('footer');
          this.main = $('#main');
    
          Todos.fetch();
        },
    
        render: function() {
          var done = Todos.done().length;
          var remaining = Todos.remaining().length;
    
          if (Todos.length) {
            this.main.show();
            this.footer.show();
            this.footer.html(this.statsTemplate({done: done, remaining: remaining}));
          } else {
            this.main.hide();
            this.footer.hide();
          }
    
          this.allCheckbox.checked = !remaining;
        },
    
        addOne: function(todo) {
          var view = new TodoView({model: todo});
          this.$("#todo-list").append(view.render().el);
        },
    
        addAll: function() {
          Todos.each(this.addOne, this);
        },
    
        createOnEnter: function(e) {
          if (e.keyCode != 13) return;
          if (!this.input.val()) return;
    
          Todos.create({title: this.input.val()});
          this.input.val('');
        },
    
        clearCompleted: function() {
          _.invoke(Todos.done(), 'destroy');
          return false;
        },
    
        toggleAllComplete: function () {
          var done = this.allCheckbox.checked;
          Todos.each(function (todo) { todo.save({'done': done}); });
        }
    
      });
    
      var App = new AppView;
    });
  • 相关阅读:
    SQL找出和删除一个表的重复记录
    "The state information is invalid for this page and might be corrupted"错误的一个解决办法
    优雅还不够,简洁才高效!——用NValidator一句话搞定客户端检测
    HTTP 错误 404 文件或目录未找到 HTTP 错误 401.2 未经授权:访问由于服务器配置被拒绝。
    来自微软关于异常处理的17条军规
    SQL回滚Transaction来调试SQL语句
    MyXls初级教程
    SQL常用判断检测语句
    纯CSS实现底部固定漂浮导航
    一个仿PetShop的通用DBHelper类
  • 原文地址:https://www.cnblogs.com/wangwenfei/p/backbone_localstorage_todo_example.html
Copyright © 2020-2023  润新知