1 /**
  2  * Comment form controller and view
  3  *
  4  * @class FormView
  5  * @extends Backbone.View
  6  * @author Bodnar Istvan <istvan@gawker.com>
  7  */
  8 /*global Mustache, CommentView, CommentModel */
  9 var FormView = Backbone.View.extend(
 10 /** @lends FormView.prototype */
 11 	{
 12 		/**
 13 		 * Html tag name of the container element that'll be created when initializing new instance.
 14 		 * This container is then accessible via the this.el (native DOM node) or this.$el (jQuery node)
 15 		 * variables.
 16 		 * @type String
 17 		 */
 18 		tagName: 'div',
 19 	
 20 		/**
 21 		 * CSS class name of the container element
 22 		 * @type String
 23 		 */
 24 		className: 'commentform',
 25 		
 26 		/**
 27 		 * The map of delegated event handlers
 28 		 * @type Object
 29 		 */
 30 		events: {
 31 			'click .submit': 'submit',
 32 			'click .cancel': 'cancel'
 33 		},
 34 		
 35 		/**
 36 		 * View init method, subscribing to model events
 37 		 */
 38 		initialize: function () {
 39 			this.model.on('change', this.updateFields, this);
 40 			this.model.on('destroy', this.remove, this);
 41 		},
 42 		
 43 		/**
 44 		 * Render form element from a template using Mustache
 45 		 * @returns {FormView} Returns the view instance itself, to allow chaining view commands.
 46 		 */
 47 		render: function () {
 48 			var template = $('#form-template').text();
 49 			var template_vars = {
 50 				author: this.model.get('author'),
 51 				text: this.model.get('text')
 52 			};
 53 			this.$el.html(Mustache.to_html(template, template_vars));
 54 			return this;
 55 		},
 56 	
 57 		/**
 58 		 * Submit button click handler
 59 		 * Sets new values from form on model, triggers a success event and cleans up the form
 60 		 * @returns {Boolean} Returns false to stop propagation
 61 		 */
 62 		submit: function () {
 63 			// set values from form on model
 64 			this.model.set({
 65 				author: this.$el.find('.author').val(),
 66 				text: this.$el.find('.text').val()
 67 			});
 68 			
 69 			// set an id if model was a new instance
 70 			// note: this is usually done automatically when items are stored in an API
 71 			if (this.model.isNew()) {
 72 				this.model.id = Math.floor(Math.random() * 1000);
 73 			}
 74 			
 75 			// trigger the 'success' event on form, with the returned model as the only parameter
 76 			this.trigger('success', this.model);
 77 			
 78 			// remove form view from DOM and memory
 79 			this.remove();
 80 			return false;
 81 		},
 82 		
 83 		/**
 84 		* Cancel button click handler
 85 		* Cleans up form view from DOM
 86 		* @returns {Boolean} Returns false to stop propagation
 87 		*/
 88 		cancel: function () {
 89 			// clean up form
 90 			this.remove();
 91 			return false;
 92 		},
 93 		
 94 		/**
 95 		 * Update view if the model changes, helps keep two edit forms for the same model in sync
 96 		 * @returns {Boolean} Returns false to stop propagation
 97 		 */
 98 		updateFields: function () {
 99 			this.$el.find('.author').val(this.model.get('author'));
100 			this.$el.find('.text').val(this.model.get('text'));
101 			return false;
102 		},
103 		
104 		/**
105 		 * Override the default view remove method with custom actions
106 		 */
107 		remove: function () {
108 			// unsubscribe from all model events with this context
109 			this.model.off(null, null, this);
110 			
111 			// delete container form DOM
112 			this.$el.remove();
113 			
114 			// call backbones default view remove method
115 			Backbone.View.prototype.remove.call(this);
116 		}
117 	}
118 );