UNPKG

todomvc

Version:

> Helping you select an MV\* framework

115 lines (95 loc) 3.12 kB
/*global define*/ define([ 'jquery', 'underscore', 'backbone', 'text!templates/todos.html', 'common' ], function ($, _, Backbone, todosTemplate, Common) { 'use strict'; var TodoView = Backbone.View.extend({ tagName: 'li', template: _.template(todosTemplate), // The DOM events specific to an item. events: { 'click .toggle': 'toggleCompleted', 'dblclick label': 'edit', 'click .destroy': 'clear', 'keypress .edit': 'updateOnEnter', 'keydown .edit': 'revertOnEscape', 'blur .edit': 'close' }, // The TodoView listens for changes to its model, re-rendering. Since there's // a one-to-one correspondence between a **Todo** and a **TodoView** in this // app, we set a direct reference on the model for convenience. initialize: function () { this.listenTo(this.model, 'change', this.render); this.listenTo(this.model, 'destroy', this.remove); this.listenTo(this.model, 'visible', this.toggleVisible); }, // Re-render the titles of the todo item. render: function () { this.$el.html(this.template(this.model.toJSON())); this.$el.toggleClass('completed', this.model.get('completed')); this.toggleVisible(); this.$input = this.$('.edit'); return this; }, toggleVisible: function () { this.$el.toggleClass('hidden', this.isHidden()); }, isHidden: function () { var isCompleted = this.model.get('completed'); return (// hidden cases only (!isCompleted && Common.TodoFilter === 'completed') || (isCompleted && Common.TodoFilter === 'active') ); }, // Toggle the `"completed"` state of the model. toggleCompleted: function () { this.model.toggle(); }, // Switch this view into `"editing"` mode, displaying the input field. edit: function () { this.$el.addClass('editing'); this.$input.focus(); }, // Close the `"editing"` mode, saving changes to the todo. close: function () { var value = this.$input.val(); var trimmedValue = value.trim(); if (trimmedValue) { this.model.save({ title: trimmedValue }); if (value !== trimmedValue) { // Model values changes consisting of whitespaces only are not causing change to be triggered // Therefore we've to compare untrimmed version with a trimmed one to chech whether anything changed // And if yes, we've to trigger change event ourselves this.model.trigger('change'); } } else { this.clear(); } this.$el.removeClass('editing'); }, // If you hit `enter`, we're through editing the item. updateOnEnter: function (e) { if (e.keyCode === Common.ENTER_KEY) { this.close(); } }, // If you're pressing `escape` we revert your change by simply leaving // the `editing` state. revertOnEscape: function (e) { if (e.which === Common.ESCAPE_KEY) { this.$el.removeClass('editing'); // Also reset the hidden input back to the original value. this.$input.val(this.model.get('title')); } }, // Remove the item, destroy the model from *localStorage* and delete its view. clear: function () { this.model.destroy(); } }); return TodoView; });