/* global jQuery, _, Backbone, gettext */ /** * Base view for defining steps in the payment/verification flow. * * Step subclasses are responsible for defining a template * and installing custom event handlers (including buttons * to move to the next step). * */ var edx = edx || {}; (function($, _, Backbone, gettext) { 'use strict'; edx.verify_student = edx.verify_student || {}; edx.verify_student.StepView = Backbone.View.extend({ initialize: function(obj) { _.extend(this, obj); /* Mix non-conflicting functions from underscore.string * (all but include, contains, and reverse) into the * Underscore namespace. */ _.mixin(_.str.exports()); }, render: function() { var templateHtml = $('#' + this.templateName + '-tpl').html(); // Allow subclasses to add additional information // to the template context, perhaps asynchronously. this.updateContext(this.templateContext()).done( function(templateContext) { // Render the template into the DOM edx.HtmlUtils.setHtml($(this.el), edx.HtmlUtils.template(templateHtml)(templateContext)); // Allow subclasses to install custom event handlers this.postRender(); } ).fail(_.bind(this.handleError, this)); return this; }, handleError: function(errorTitle, errorMsg) { this.errorModel.set({ errorTitle: errorTitle || gettext('Error'), errorMsg: errorMsg || gettext('An error has occurred. Please try reloading the page.'), shown: true }); }, templateContext: function() { var context = { nextStepTitle: this.nextStepTitle }; return _.extend(context, this.defaultContext(), this.stepData); }, /** * Provide default values for the template context. * Subclasses can use this to fill in values that * the underscore templates expect to be defined. * This is especially useful for testing, so that the * tests can pass in only the values relevant * to the test. */ defaultContext: function() { return {}; }, /** * Subclasses can override this to add information to * the template context. This returns an asynchronous * Promise, so the subclass can fill in the template * after completing an AJAX request. * The default implementation is a no-op. */ updateContext: function(templateContext) { var view = this; return $.Deferred( function(defer) { defer.resolveWith(view, [templateContext]); } ).promise(); }, postRender: function() { // Sub-classes can override this method // to install custom event handlers. }, nextStep: function() { this.trigger('next-step'); }, goToStep: function(stepName) { this.trigger('go-to-step', stepName); } }); })(jQuery, _, Backbone, gettext);