//LessonContentView define(['jquery', 'underscore', 'backbone', 'libs/jquery.form', 'goatApp/view/ErrorNotificationView'], function( $, _, Backbone, JQueryForm, ErrorNotificationView) { return Backbone.View.extend({ el:'#lesson-content-wrapper', //TODO << get this fixed up in DOM initialize: function(options) { options = options || {}; new ErrorNotificationView(); var self = this; Backbone.on('assignment:navTo', function(assignment){ var page = self.findPage(assignment); if (page != -1) { self.navToPage(page); } }); }, findPage: function(assignment) { for (var i = 0; i < this.$contentPages.length; i++) { var contentPage = this.$contentPages[i]; var form = $('form.attack-form', contentPage); var action = form.attr('action') if (action !== undefined && action.includes(assignment.assignment)) { return i; } } return -1; }, /* initial renering */ render: function() { this.$el.find('.lesson-content').html(this.model.get('content')); this.$el.find('.attack-feedback').hide(); this.$el.find('.attack-output').hide(); this.makeFormsAjax(); //this.ajaxifyAttackHref(); $(window).scrollTop(0); //work-around til we get the scroll down sorted out this.initPagination(); }, initPagination: function() { //get basic pagination info this.currentPage = 0; this.$contentPages = this.$el.find('.lesson-page-wrapper'); this.numPages = this.$contentPages.length; // this.addPaginationControls(); if (this.numPages > 1) { //no animation on init this.$contentPages.hide(); this.$el.find(this.$contentPages[this.currentPage]).show(); this.showNextPageButton(); this.hidePrevPageButton(); } else if (this.numPages === 1) { this.hideNextPageButton(); this.hidePrevPageButton(); } }, setCurrentPage: function (pageNum) { this.currentPage = (_.isNumber(pageNum) && pageNum < this.numPages) ? pageNum : 0; }, getCurrentPage: function () { return this.currentPage; }, makeFormsAjax: function () { this.$form = $('form.attack-form'); // turn off standard submit var self = this; // each submit handled per form this.$form.each( function() { $(this).submit(self.onFormSubmit.bind(self)); }); }, /* form submission handling */ onFormSubmit: function (e) { var curForm = e.currentTarget; // the form from which the var self = this; // TODO custom Data prep for submission var prepareDataFunctionName = $(curForm).attr('prepareData'); var submitData = (typeof webgoat.customjs[prepareDataFunctionName] === 'function') ? webgoat.customjs[prepareDataFunctionName]() : $(curForm).serialize(); // var submitData = this.$form.serialize(); this.curForm = curForm; this.$curFeedback = $(curForm).closest('.attack-container').find('.attack-feedback'); this.$curOutput = $(curForm).closest('.attack-container').find('.attack-output'); var formUrl = $(curForm).attr('action'); var formMethod = $(curForm).attr('method'); var contentType = ($(curForm).attr('contentType')) ? $(curForm).attr('contentType') : 'application/x-www-form-urlencoded; charset=UTF-8'; $.ajax({ //data:submitData, url:formUrl, method:formMethod, contentType:contentType, data: submitData }).then(self.onSuccessResponse.bind(self), self.onErrorResponse.bind(self)); return false; }, onSuccessResponse: function(data) { this.renderFeedback(data.feedback); this.renderOutput(data.output || ""); if (data.assignmentCompleted) { this.markAssignmentComplete(); this.trigger('assignment:complete'); } else { this.markAssignmentIncomplete(); } return false; }, markAssignmentComplete: function () { this.curForm.reset(); $(this.curForm).siblings('.assignment-success').find('i').removeClass('hidden'); }, markAssignmentIncomplete: function () { $(this.curForm).siblings('.assignment-success').find('i').addClass('hidden'); }, onErrorResponse: function (a,b,c) { console.error(a); console.error(b); console.error(c); return false; }, ajaxifyAttackHref: function() { // rewrite any links with hrefs point to relative attack URLs var self = this; // instruct in template to have links returned with the attack-link class $('a.attack-link').submit(function(event){ $.get(this.action, "json").then(self.onSuccessResponse, self.onErrorResponse); }); }, renderFeedback: function(feedback) { this.$curFeedback.html(polyglot.t(feedback) || ""); this.$curFeedback.show(400) }, renderOutput: function(output) { this.$curOutput.html(polyglot.t(output) || ""); this.$curOutput.show(400) }, /* create, show & hide pagination controls */ addPaginationControls: function() { var pagingControlsDiv; //this.$el.html(); //prev var prevPageButton = $('<span>',{class:'glyphicon-class glyphicon glyphicon-circle-arrow-left show-prev-page'}); prevPageButton.unbind().on('click',this.decrementPageView.bind(this)); //next var nextPageButton = $('<span>',{class:'glyphicon-class glyphicon glyphicon-circle-arrow-right show-next-page'}); nextPageButton.unbind().on('click',this.incrementPageView.bind(this)); //add to DOM if (this.$el.find('#lesson-page-controls').length < 1) { pagingControlsDiv = $('<div>',{class:'panel-body', id:'lesson-page-controls'}); pagingControlsDiv.append(prevPageButton); pagingControlsDiv.append(nextPageButton); this.$el.append(pagingControlsDiv); } }, showPrevPageButton: function() { $('span.glyphicon-class.glyphicon.glyphicon-circle-arrow-left.show-prev-page').show(); }, hidePrevPageButton: function() { $('span.glyphicon-class.glyphicon.glyphicon-circle-arrow-left.show-prev-page').hide(); }, showNextPageButton: function() { $('span.glyphicon-class.glyphicon.glyphicon-circle-arrow-right.show-next-page').show(); }, hideNextPageButton: function() { $('span.glyphicon-class.glyphicon.glyphicon-circle-arrow-right.show-next-page').hide(); }, /* increment, decrement & display handlers */ incrementPageView: function() { if (this.currentPage < this.numPages -1) { this.currentPage++; window.location.href = this.model.get('lessonUrl') + '/' + this.currentPage; //this.showCurContentPage(true);Con } if (this.currentPage > 0) { this.showPrevPageButton(); } if (this.currentPage >= this.numPages -1) { this.hideNextPageButton(); this.showPrevPageButton; } }, decrementPageView: function() { if (this.currentPage > 0) { this.currentPage--; window.location.href = this.model.get('lessonUrl') + '/' + this.currentPage; //this.showCurContentPage(false); } if (this.currentPage < this.numPages -1) { this.showNextPageButton(); } if (this.currentPage == 0) { this.hidePrevPageButton(); this.showNextPageButton() } }, showCurContentPage: function(isIncrement) { this.$contentPages.hide(); this.$el.find(this.$contentPages[this.currentPage]).show(); }, findAssigmentEndpointOnPage: function(pageNumber) { var contentPage = this.$contentPages[this.currentPage]; var form = $('form.attack-form', contentPage); var action = form.attr('action') if (action !== undefined) { return action; } }, navToPage: function (pageNum) { this.setCurrentPage(pageNum);//provides validation this.showCurContentPage(this.currentPage); this.hideShowNavButtons(); var assignmentPath = this.findAssigmentEndpointOnPage(pageNum); Backbone.trigger('navigatedToPage',{'pageNumber':pageNum, 'assignmentPath' : assignmentPath}); }, hideShowNavButtons: function () { //one page only if (this.numPages === 1) { this.hidePrevPageButton(); this.hideNextPageButton(); } //first page if (this.currentPage === 0) { this.hidePrevPageButton(); if (this.numPages > 1) { this.showNextPageButton(); } return; } // > first page, but not last if (this.currentPage > 0 && this.currentPage < this.numPages -1) { this.showNextPageButton(); this.showPrevPageButton(); return; } // last page and more than one page if (this.currentPage === this.numPages -1 && this.numPages > 1) { this.hideNextPageButton(); this.showPrevPageButton(); return; } }, /* for testing */ showTestParam: function (param) { this.$el.find('.lesson-content').html('test:' + param); } }); });