Files
edx-platform/lms/static/js/student_account/views/AccessView.js
2015-06-26 13:24:01 -07:00

281 lines
9.3 KiB
JavaScript

var edx = edx || {};
(function($, _, _s, Backbone, History) {
'use strict';
edx.student = edx.student || {};
edx.student.account = edx.student.account || {};
edx.student.account.AccessView = Backbone.View.extend({
el: '#login-and-registration-container',
tpl: '#access-tpl',
events: {
'click .form-toggle': 'toggleForm'
},
subview: {
login: {},
register: {},
passwordHelp: {},
institutionLogin: {},
hintedLogin: {}
},
nextUrl: '/dashboard',
// The form currently loaded
activeForm: '',
initialize: function( obj ) {
/* Mix non-conflicting functions from underscore.string
* (all but include, contains, and reverse) into the
* Underscore namespace
*/
_.mixin( _s.exports() );
this.tpl = $(this.tpl).html();
this.activeForm = obj.mode || 'login';
this.thirdPartyAuth = obj.thirdPartyAuth || {
currentProvider: null,
providers: []
};
this.thirdPartyAuthHint = obj.thirdPartyAuthHint || null;
if (obj.nextUrl) {
// Ensure that the next URL is internal for security reasons
if ( ! window.isExternal( obj.nextUrl ) ) {
this.nextUrl = obj.nextUrl;
}
}
this.formDescriptions = {
login: obj.loginFormDesc,
register: obj.registrationFormDesc,
reset: obj.passwordResetFormDesc,
institution_login: null,
hinted_login: null
};
this.platformName = obj.platformName;
// The login view listens for 'sync' events from the reset model
this.resetModel = new edx.student.account.PasswordResetModel({}, {
method: 'GET',
url: '#'
});
this.render();
// Once the third party error message has been shown once,
// there is no need to show it again, if the user changes mode:
this.thirdPartyAuth.errorMessage = null;
},
render: function() {
$(this.el).html( _.template( this.tpl, {
mode: this.activeForm
}));
this.postRender();
return this;
},
postRender: function() {
//get & check current url hash part & load form accordingly
if (Backbone.history.getHash() === "forgot-password-modal") {
this.resetPassword();
} else {
this.loadForm(this.activeForm);
}
},
loadForm: function( type ) {
var loadFunc = _.bind( this.load[type], this );
loadFunc( this.formDescriptions[type] );
},
load: {
login: function( data ) {
var model = new edx.student.account.LoginModel({}, {
method: data.method,
url: data.submit_url
});
this.subview.login = new edx.student.account.LoginView({
fields: data.fields,
model: model,
resetModel: this.resetModel,
thirdPartyAuth: this.thirdPartyAuth,
platformName: this.platformName
});
// Listen for 'password-help' event to toggle sub-views
this.listenTo( this.subview.login, 'password-help', this.resetPassword );
// Listen for 'auth-complete' event so we can enroll/redirect the user appropriately.
this.listenTo( this.subview.login, 'auth-complete', this.authComplete );
},
reset: function( data ) {
this.resetModel.ajaxType = data.method;
this.resetModel.urlRoot = data.submit_url;
this.subview.passwordHelp = new edx.student.account.PasswordResetView({
fields: data.fields,
model: this.resetModel
});
// Listen for 'password-email-sent' event to toggle sub-views
this.listenTo( this.subview.passwordHelp, 'password-email-sent', this.passwordEmailSent );
// Focus on the form
$('.password-reset-form').focus();
},
register: function( data ) {
var model = new edx.student.account.RegisterModel({}, {
method: data.method,
url: data.submit_url
});
this.subview.register = new edx.student.account.RegisterView({
fields: data.fields,
model: model,
thirdPartyAuth: this.thirdPartyAuth,
platformName: this.platformName
});
// Listen for 'auth-complete' event so we can enroll/redirect the user appropriately.
this.listenTo( this.subview.register, 'auth-complete', this.authComplete );
},
institution_login: function ( unused ) {
this.subview.institutionLogin = new edx.student.account.InstitutionLoginView({
thirdPartyAuth: this.thirdPartyAuth,
platformName: this.platformName,
mode: this.activeForm
});
this.subview.institutionLogin.render();
},
hinted_login: function ( unused ) {
this.subview.hintedLogin = new edx.student.account.HintedLoginView({
thirdPartyAuth: this.thirdPartyAuth,
hintedProvider: this.thirdPartyAuthHint,
platformName: this.platformName
});
this.subview.hintedLogin.render();
}
},
passwordEmailSent: function() {
this.element.hide( $(this.el).find('#password-reset-anchor') );
this.element.show( $('#login-anchor') );
this.element.scrollTop( $('#login-anchor') );
},
resetPassword: function() {
window.analytics.track('edx.bi.password_reset_form.viewed', {
category: 'user-engagement'
});
this.element.hide( $(this.el).find('#login-anchor') );
this.loadForm('reset');
this.element.scrollTop( $('#password-reset-anchor') );
},
toggleForm: function( e ) {
var type = $(e.currentTarget).data('type'),
$form = $('#' + type + '-form'),
$anchor = $('#' + type + '-anchor'),
queryParams = url('?'),
queryStr = queryParams.length > 0 ? '?' + queryParams : '';
e.preventDefault();
window.analytics.track('edx.bi.' + type + '_form.toggled', {
category: 'user-engagement'
});
// Load the form. Institution login is always refreshed since it changes based on the previous form.
if ( !this.form.isLoaded( $form ) || type == "institution_login") {
this.loadForm( type );
}
this.activeForm = type;
this.element.hide( $(this.el).find('.submission-success') );
this.element.hide( $(this.el).find('.form-wrapper') );
this.element.show( $form );
this.element.scrollTop( $anchor );
// Update url without reloading page
if (type != "institution_login") {
History.pushState( null, document.title, '/' + type + queryStr );
}
analytics.page( 'login_and_registration', type );
// Focus on the form
$("#" + type).focus();
},
/**
* Once authentication has completed successfully:
*
* If we're in a third party auth pipeline, we must complete the pipeline.
* Otherwise, redirect to the specified next step.
*
*/
authComplete: function() {
if (this.thirdPartyAuth && this.thirdPartyAuth.finishAuthUrl) {
this.redirect(this.thirdPartyAuth.finishAuthUrl);
// Note: the third party auth URL likely contains another redirect URL embedded inside
} else {
this.redirect(this.nextUrl);
}
},
/**
* Redirect to a URL. Mainly useful for mocking out in tests.
* @param {string} url The URL to redirect to.
*/
redirect: function( url ) {
window.location.replace(url);
},
form: {
isLoaded: function( $form ) {
return $form.html().length > 0;
}
},
/* Helper method to toggle display
* including accessibility considerations
*/
element: {
hide: function( $el ) {
$el.addClass('hidden');
},
scrollTop: function( $el ) {
// Scroll to top of selected element
$('html,body').animate({
scrollTop: $el.offset().top
},'slow');
},
show: function( $el ) {
$el.removeClass('hidden');
}
}
});
})(jQuery, _, _.str, Backbone, History);