define(["js/views/baseview", "underscore"], function(BaseView, _) { var AbstractEditor = BaseView.extend({ // Model is MetadataModel initialize : function() { var self = this; var templateName = _.result(this, 'templateName'); // Backbone model cid is only unique within the collection. this.uniqueId = _.uniqueId(templateName + "_"); this.template = this.loadTemplate(templateName); this.$el.html(this.template({model: this.model, uniqueId: this.uniqueId})); this.listenTo(this.model, 'change', this.render); this.render(); }, /** * The ID/name of the template. Subclasses must override this. */ templateName: '', /** * Returns the value currently displayed in the editor/view. Subclasses should implement this method. */ getValueFromEditor : function () {}, /** * Sets the value currently displayed in the editor/view. Subclasses should implement this method. */ setValueInEditor : function (value) {}, /** * Sets the value in the model, using the value currently displayed in the view. */ updateModel: function () { this.model.setValue(this.getValueFromEditor()); }, /** * Clears the value currently set in the model (reverting to the default). */ clear: function () { this.model.clear(); }, /** * Shows the clear button, if it is not already showing. */ showClearButton: function() { if (!this.$el.hasClass('is-set')) { this.$el.addClass('is-set'); this.getClearButton().removeClass('inactive'); this.getClearButton().addClass('active'); } }, /** * Returns the clear button. */ getClearButton: function () { return this.$el.find('.setting-clear'); }, /** * Renders the editor, updating the value displayed in the view, as well as the state of * the clear button. */ render: function () { if (!this.template) return; this.setValueInEditor(this.model.getDisplayValue()); if (this.model.isExplicitlySet()) { this.showClearButton(); } else { this.$el.removeClass('is-set'); this.getClearButton().addClass('inactive'); this.getClearButton().removeClass('active'); } return this; }, /** * Loads the named template from the page, or logs an error if it fails. * @param name The name of the template. * @returns The loaded template. */ loadTemplate: function(name) { var templateSelector = "#" + name, templateText = $(templateSelector).text(); if (!templateText) { console.error("Failed to load " + name + " template"); } return _.template(templateText); } }); return AbstractEditor; });