diff --git a/lms/static/js/spec/student_account/login_spec.js b/lms/static/js/spec/student_account/login_spec.js index 45004d07ac..428e09d340 100644 --- a/lms/static/js/spec/student_account/login_spec.js +++ b/lms/static/js/spec/student_account/login_spec.js @@ -134,6 +134,9 @@ define([ // Submit the form, with successful validation submitForm(true); + // Form button should be disabled on success. + expect(view.$submitButton).toHaveAttr('disabled'); + // Verify that the client contacts the server with the expected data AjaxHelpers.expectRequest( requests, 'POST', @@ -213,6 +216,8 @@ define([ // Expect auth complete NOT to have been triggered expect(authComplete).toBe(false); + // Form button should be re-enabled when errors occur + expect(view.$submitButton).not.toHaveAttr('disabled'); }); it('displays an error if the server returns an error while logging in', function() { @@ -227,10 +232,15 @@ define([ // Expect that an error is displayed and that auth complete is not triggered expect(view.$errors).not.toHaveClass('hidden'); expect(authComplete).toBe(false); + // Form button should be re-enabled on server failure. + expect(view.$submitButton).not.toHaveAttr('disabled'); // If we try again and succeed, the error should go away submitForm(); + // Form button should be disabled on success. + expect(view.$submitButton).toHaveAttr('disabled'); + // This time, respond with status code 200 AjaxHelpers.respondWithJson(requests, {}); diff --git a/lms/static/js/spec/student_account/register_spec.js b/lms/static/js/spec/student_account/register_spec.js index 07fada7427..cd6d59ea7b 100644 --- a/lms/static/js/spec/student_account/register_spec.js +++ b/lms/static/js/spec/student_account/register_spec.js @@ -242,6 +242,8 @@ define([ // Verify that auth complete is triggered expect(authComplete).toBe(true); + // Form button should be disabled on success. + expect(view.$submitButton).toHaveAttr('disabled'); }); it('sends analytics info containing the enrolled course ID', function() { @@ -295,6 +297,8 @@ define([ // Verify that no submission errors are visible expect(view.$errors).toHaveClass('hidden'); + // Form button should be disabled on success. + expect(view.$submitButton).toHaveAttr('disabled'); }); it('displays registration form validation errors', function() { @@ -308,6 +312,8 @@ define([ // Expect that auth complete is NOT triggered expect(authComplete).toBe(false); + // Form button should be re-enabled on error. + expect(view.$submitButton).not.toHaveAttr('disabled'); }); it('displays an error if the server returns an error while registering', function() { @@ -332,6 +338,8 @@ define([ // Expect that the error is hidden and that auth complete is triggered expect(view.$errors).toHaveClass('hidden'); expect(authComplete).toBe(true); + // Form button should be disabled on success. + expect(view.$submitButton).toHaveAttr('disabled'); }); }); }); diff --git a/lms/static/js/student_account/views/FormView.js b/lms/static/js/student_account/views/FormView.js index 5c65006128..9142eb9284 100644 --- a/lms/static/js/student_account/views/FormView.js +++ b/lms/static/js/student_account/views/FormView.js @@ -28,6 +28,8 @@ var edx = edx || {}; // String to append to required label fields requiredStr: '*', + submitButton: '', + initialize: function( data ) { this.model = data.model; this.preRender( data ); @@ -65,6 +67,7 @@ var edx = edx || {}; this.$form = $container.find('form'); this.$errors = $container.find('.submission-error'); + this.$submitButton = $container.find(this.submitButton); }, buildForm: function( data ) { @@ -178,6 +181,7 @@ var edx = edx || {}; saveError: function( error ) { this.errors = ['
  • ' + error.responseText + '
  • ']; this.setErrors(); + this.toggleDisableButton(false); }, setErrors: function() { @@ -209,6 +213,8 @@ var edx = edx || {}; event.preventDefault(); + this.toggleDisableButton(true); + if ( !_.compact(this.errors).length ) { this.model.set( data ); this.model.save(); @@ -221,11 +227,26 @@ var edx = edx || {}; toggleErrorMsg: function( show ) { if ( show ) { this.setErrors(); + this.toggleDisableButton(false); } else { this.element.hide( this.$errors ); } }, + /** + * If a form button is defined for this form, this will disable the button on + * submit, and re-enable the button if an error occurs. + * + * Args: + * disabled (boolean): If set to TRUE, disable the button. + * + */ + toggleDisableButton: function ( disabled ) { + if (this.$submitButton) { + this.$submitButton.attr('disabled', disabled); + } + }, + validate: function( $el ) { return edx.utils.validate( $el ); } diff --git a/lms/static/js/student_account/views/LoginView.js b/lms/static/js/student_account/views/LoginView.js index 23df7bfdbf..85edd59d3f 100644 --- a/lms/static/js/student_account/views/LoginView.js +++ b/lms/static/js/student_account/views/LoginView.js @@ -21,6 +21,8 @@ var edx = edx || {}; requiredStr: '', + submitButton: '.js-login', + preRender: function( data ) { this.providers = data.thirdPartyAuth.providers || []; this.currentProvider = data.thirdPartyAuth.currentProvider || ''; @@ -54,6 +56,7 @@ var edx = edx || {}; this.$form = this.$container.find('form'); this.$errors = this.$container.find('.submission-error'); this.$authError = this.$container.find('.already-authenticated-msg'); + this.$submitButton = this.$container.find(this.submitButton); /* If we're already authenticated with a third-party * provider, try logging in. The easiest way to do this @@ -101,6 +104,7 @@ var edx = edx || {}; this.element.hide( this.$authError ); this.element.show( this.$errors ); } + this.toggleDisableButton(false); } }); })(jQuery, _, gettext); diff --git a/lms/static/js/student_account/views/PasswordResetView.js b/lms/static/js/student_account/views/PasswordResetView.js index 40af6820a9..3e573fefc9 100644 --- a/lms/static/js/student_account/views/PasswordResetView.js +++ b/lms/static/js/student_account/views/PasswordResetView.js @@ -19,6 +19,8 @@ var edx = edx || {}; requiredStr: '', + submitButton: '.js-reset', + preRender: function( data ) { this.listenTo( this.model, 'sync', this.saveSuccess ); }, @@ -26,6 +28,7 @@ var edx = edx || {}; toggleErrorMsg: function( show ) { if ( show ) { this.setErrors(); + this.toggleDisableButton(false) } else { this.element.hide( this.$errors ); } diff --git a/lms/static/js/student_account/views/RegisterView.js b/lms/static/js/student_account/views/RegisterView.js index 17d5dd3c5f..ef7fc9854d 100644 --- a/lms/static/js/student_account/views/RegisterView.js +++ b/lms/static/js/student_account/views/RegisterView.js @@ -18,6 +18,8 @@ var edx = edx || {}; formType: 'register', + submitButton: '.js-register', + preRender: function( data ) { this.providers = data.thirdPartyAuth.providers || []; this.currentProvider = data.thirdPartyAuth.currentProvider || ''; @@ -57,5 +59,6 @@ var edx = edx || {}; saveSuccess: function() { this.trigger('auth-complete'); } + }); })(jQuery, _, gettext);