diff --git a/lms/envs/common.py b/lms/envs/common.py index dc1ec56026..be752beebe 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -1029,8 +1029,10 @@ student_account_js = [ 'js/common_helpers/edx.utils.validate.js', 'js/student_account/models/LoginModel.js', 'js/student_account/models/RegisterModel.js', + 'js/student_account/models/PasswordResetModel.js', 'js/student_account/views/LoginView.js', 'js/student_account/views/RegisterView.js', + 'js/student_account/views/PasswordResetView.js', 'js/student_account/views/AccessView.js', 'js/student_account/accessApp.js', ] diff --git a/lms/static/js/student_account/models/PasswordResetModel.js b/lms/static/js/student_account/models/PasswordResetModel.js new file mode 100644 index 0000000000..79a3191dcc --- /dev/null +++ b/lms/static/js/student_account/models/PasswordResetModel.js @@ -0,0 +1,41 @@ +var edx = edx || {}; + +(function($, _, Backbone, gettext) { + 'use strict'; + + edx.student = edx.student || {}; + edx.student.account = edx.student.account || {}; + + edx.student.account.PasswordResetModel = Backbone.Model.extend({ + + defaults: { + email: '' + }, + + urlRoot: '/resetMe', + + sync: function(method, model) { + var headers = { + 'X-CSRFToken': $.cookie('csrftoken') + }; + + // Is just expecting email address + $.ajax({ + url: model.urlRoot, + type: 'POST', + data: model.attributes, + headers: headers + }) + .done(function() { + var query = window.location.search, + url = '/dashboard'; + + model.trigger('success'); + }) + .fail( function( error ) { + console.log('RegisterModel.save() FAILURE!!!!!'); + model.trigger('error', error); + }); + } + }); +})(jQuery, _, Backbone, gettext); \ No newline at end of file diff --git a/lms/static/js/student_account/views/AccessView.js b/lms/static/js/student_account/views/AccessView.js index 40486b3fc4..363bc9f6f3 100644 --- a/lms/static/js/student_account/views/AccessView.js +++ b/lms/static/js/student_account/views/AccessView.js @@ -15,6 +15,12 @@ var edx = edx || {}; 'change .form-toggle': 'toggleForm' }, + subview: { + login: {}, + register: {}, + passwordHelp: {} + }, + // The form currently loaded activeForm: '', @@ -38,22 +44,38 @@ var edx = edx || {}; postRender: function() { // Load the default form this.loadForm( this.activeForm ); + this.$header = $(this.el).find('.js-login-register-header'); }, loadForm: function( type ) { if ( type === 'login' ) { - console.log('load login'); - return new edx.student.account.LoginView(); - } else if ( type === 'register' ) { - console.log('load register'); - return new edx.student.account.RegisterView(); - } + this.subview.login = new edx.student.account.LoginView(); - // return new app.LoginView({ - // el: $('#' + type + '-form'), - // model: this.getModel( type ), - // tpl: $('#' + type + '-form-tpl').html() - // }); + // Listen for 'password-help' event to toggle sub-views + this.listenTo( this.subview.login, 'password-help', this.resetPassword ); + } else if ( type === 'register' ) { + this.subview.register = new edx.student.account.RegisterView(); + } else if ( type === 'reset' ) { + this.subview.passwordHelp = new edx.student.account.PasswordResetView(); + + // Listen for 'password-reset' event to toggle sub-views + this.listenTo( this.subview.passwordHelp, 'password-reset', this.removePasswordView); + } + }, + + removePasswordView: function() { + this.$header.removeClass('hidden'); + $(this.el).find('.form-type').removeClass('hidden'); + + // User should only have to submit reset once so remove view + this.subview.passwordHelp.remove(); + }, + + resetPassword: function() { + console.log( this.$header ); + this.$header.addClass('hidden'); + $(this.el).find('.form-type').addClass('hidden'); + this.loadForm('reset'); }, toggleForm: function( e ) { diff --git a/lms/static/js/student_account/views/LoginView.js b/lms/static/js/student_account/views/LoginView.js index 1e26bf8727..dda774c9a3 100644 --- a/lms/static/js/student_account/views/LoginView.js +++ b/lms/static/js/student_account/views/LoginView.js @@ -125,7 +125,8 @@ var edx = edx || {}; forgotPassword: function( event ) { event.preventDefault(); - console.log('forgotPassword'); + + this.trigger('password-help'); }, submitForm: function( event ) { diff --git a/lms/static/js/student_account/views/PasswordResetView.js b/lms/static/js/student_account/views/PasswordResetView.js new file mode 100644 index 0000000000..5e387ab5f5 --- /dev/null +++ b/lms/static/js/student_account/views/PasswordResetView.js @@ -0,0 +1,155 @@ +var edx = edx || {}; + +(function($, _, Backbone, gettext) { + 'use strict'; + + edx.student = edx.student || {}; + edx.student.account = edx.student.account || {}; + + edx.student.account.PasswordResetView = Backbone.View.extend({ + tagName: 'form', + + el: '#password-reset-wrapper', + + tpl: $('#password_reset-tpl').html(), + + fieldTpl: $('#form_field-tpl').html(), + + events: { + 'click .js-reset': 'submitForm' + }, + + errors: [], + + mode: {}, + + $form: {}, + + initialize: function( obj ) { + var fields = this.buildForm([{ + label: 'E-mail', + instructions: 'This is the e-mail address you used to register with edX', + name: 'email', + required: true, + type: 'email', + restrictions: [] + }]); +console.log('PasswordResetView INIT'); + this.initModel(); + this.render( fields ); + }, + + // Renders the form. + render: function( html ) { + var fields = html || ''; + + $(this.el).html( _.template( this.tpl, { + fields: fields + })); + + this.postRender(); + + return this; + }, + + postRender: function() { + var $container = $(this.el); + + this.$form = $container.find('form'); + this.$errors = $container.find('.error-msg'); + + this.listenTo( this.model, 'success', this.resetComplete) ; + }, + + initModel: function( url, method ) { + console.log('init the password reset model'); + /*this.model = new edx.student.account.PasswordResetModel(); + + this.listenTo( this.model, 'error', function( error ) { + console.log(error.status, ' error: ', error.responseText); + });*/ + }, + + buildForm: function( data ) { + var html = [], + i, + len = data.length, + fieldTpl = this.fieldTpl; +console.log('buildForm ', data); + for ( i=0; i +

Welcome!

+

Please log in to continue

+ +

checked<% } %> > @@ -13,3 +18,5 @@

+ +
\ No newline at end of file diff --git a/lms/templates/student_account/form_field.underscore b/lms/templates/student_account/form_field.underscore index 13dd53d787..3d6c2b0851 100644 --- a/lms/templates/student_account/form_field.underscore +++ b/lms/templates/student_account/form_field.underscore @@ -11,19 +11,19 @@ <% } %> <% if ( type === 'select' ) { %> - <% _.each(options, function(el) { %> <% }); %> <% } else if ( type === 'textarea' ) { %> - <% } else { %> - minlength="<%= restrictions.min_length %>"<% } %> <% if ( restrictions.max_length ) { %> maxlength="<%= restrictions.max_length %>"<% } %> <% if ( required ) { %> required<% } %> diff --git a/lms/templates/student_account/login_and_register.html b/lms/templates/student_account/login_and_register.html index b4f1a283fd..629d0d1297 100644 --- a/lms/templates/student_account/login_and_register.html +++ b/lms/templates/student_account/login_and_register.html @@ -12,16 +12,13 @@ <%block name="header_extras"> -% for template_name in ["account", "access", "form_field", "login", "register"]: +% for template_name in ["account", "access", "form_field", "login", "register", "password_reset"]: % endfor -

Welcome!

- -

Please log in to continue

## TODO: Use JavaScript to populate this div with ## the actual registration/login forms (loaded asynchronously from the user API) @@ -47,6 +44,7 @@ ## Note that this list may be empty. ##
diff --git a/lms/templates/student_account/password_reset.underscore b/lms/templates/student_account/password_reset.underscore new file mode 100644 index 0000000000..a7c167089c --- /dev/null +++ b/lms/templates/student_account/password_reset.underscore @@ -0,0 +1,21 @@ +
+

Password assistance

+
+ +
+
+

Please enter your email address below and we will send you instructions for setting a new password.

+
+ + + <%= fields %> + + +
+
+
\ No newline at end of file