define([ 'backbone', 'backbone.validation', 'jquery', 'underscore', 'js/programs/models/course_model', 'js/programs/models/course_run_model', 'js/programs/models/program_model', 'js/programs/views/course_run_view', 'text!templates/programs/course_details.underscore', 'edx-ui-toolkit/js/utils/html-utils', 'gettext', 'js/programs/utils/validation_config' ], function(Backbone, BackboneValidation, $, _, CourseModel, CourseRunModel, ProgramModel, CourseRunView, ListTpl, HtmlUtils) { 'use strict'; return Backbone.View.extend({ parentEl: '.js-course-list', className: 'course-details', events: { 'click .js-remove-course': 'destroy', 'click .js-select-course': 'setCourse', 'click .js-add-course-run': 'addCourseRun' }, tpl: HtmlUtils.template(ListTpl), initialize: function(options) { this.model = new CourseModel(); Backbone.Validation.bind(this); this.$parentEl = $(this.parentEl); // For managing subViews this.courseRunViews = []; this.courseRuns = options.courseRuns; this.programModel = options.programModel; if (options.courseData) { this.model.set(options.courseData); } else { this.model.set({run_modes: []}); } // Need a unique value for field ids so using model cid this.model.set({cid: this.model.cid}); this.model.on('change:run_modes', this.updateRuns, this); this.render(); }, render: function() { HtmlUtils.setHtml(this.$el, this.tpl(this.formatData())); this.$parentEl.append(this.$el); this.postRender(); }, postRender: function() { var runs = this.model.get('run_modes'); if (runs && runs.length > 0) { this.addCourseRuns(); } }, addCourseRun: function(event) { var $runsContainer = this.$el.find('.js-course-runs'), runModel = new CourseRunModel(), runView; event.preventDefault(); runModel.set({course_key: undefined}); runView = new CourseRunView({ model: runModel, courseModel: this.model, courseRuns: this.courseRuns, programStatus: this.programModel.get('status'), $parentEl: $runsContainer }); this.courseRunViews.push(runView); }, addCourseRuns: function() { // Create run views var runs = this.model.get('run_modes'), $runsContainer = this.$el.find('.js-course-runs'); _.each(runs, function(run) { var runModel = new CourseRunModel(), runView; runModel.set(run); runView = new CourseRunView({ model: runModel, courseModel: this.model, courseRuns: this.courseRuns, programStatus: this.programModel.get('status'), $parentEl: $runsContainer }); this.courseRunViews.push(runView); return runView; }.bind(this)); }, addCourseToProgram: function() { var courseCodes = this.programModel.get('course_codes'), courseData = this.model.toJSON(); if (this.programModel.isValid(true)) { // We don't want to save the cid so omit it courseCodes.push(_.omit(courseData, 'cid')); this.programModel.patch({course_codes: courseCodes}); } }, // Delete this view destroy: function() { Backbone.Validation.unbind(this); this.destroyChildren(); this.undelegateEvents(); this.removeCourseFromProgram(); this.remove(); }, destroyChildren: function() { var runs = this.courseRunViews; _.each(runs, function(run) { run.removeRun(); }); }, // Format data to be passed to the template formatData: function() { var data = $.extend({}, {courseRuns: this.courseRuns.models}, _.omit(this.programModel.toJSON(), 'run_modes'), this.model.toJSON() ); return data; }, removeCourseFromProgram: function() { var courseCodes = this.programModel.get('course_codes'), key = this.model.get('key'), name = this.model.get('display_name'), update = []; update = _.reject(courseCodes, function(course) { return course.key === key && course.display_name === name; }); this.programModel.patch({course_codes: update}); }, setCourse: function(event) { var $form = this.$('.js-course-form'), title = $form.find('.display-name').val(), key = $form.find('.course-key').val(); event.preventDefault(); this.model.set({ display_name: title, key: key, organization: this.programModel.get('organizations')[0] }); if (this.model.isValid(true)) { this.addCourseToProgram(); this.updateDOM(); this.addCourseRuns(); } }, updateDOM: function() { HtmlUtils.setHtml(this.$el, this.tpl(this.formatData())); }, updateRuns: function() { var courseCodes = this.programModel.get('course_codes'), key = this.model.get('key'), name = this.model.get('display_name'), index; if (this.programModel.isValid(true)) { index = _.findIndex(courseCodes, function(course) { return course.key === key && course.display_name === name; }); courseCodes[index] = this.model.toJSON(); this.programModel.patch({course_codes: courseCodes}); } } }); } );