ECOM-369 Moved to Base FormView extended by other views.
This commit is contained in:
@@ -9,12 +9,37 @@ var edx = edx || {};
|
||||
var _fn = {
|
||||
validate: {
|
||||
|
||||
field: function( el ) {
|
||||
var $el = $(el);
|
||||
msg: {
|
||||
email: '<p>A properly formatted e-mail is required</p>',
|
||||
min: '<p><%= field %> must be a minimum of <%= length %> characters long',
|
||||
max: '<p><%= field %> must be a maximum of <%= length %> characters long',
|
||||
password: '<p>A valid password is required</p>',
|
||||
required: '<p><%= field %> field is required</p>',
|
||||
terms: '<p>To enroll you must agree to the <a href="#">Terms of Service and Honor Code</a></p>'
|
||||
},
|
||||
|
||||
return _fn.validate.required( $el ) &&
|
||||
_fn.validate.charLength( $el ) &&
|
||||
_fn.validate.email.valid( $el );
|
||||
field: function( el ) {
|
||||
var $el = $(el),
|
||||
required = _fn.validate.required( $el ),
|
||||
// length = _fn.validate.charLength( $el ),
|
||||
min = _fn.validate.str.minlength( $el ),
|
||||
max = _fn.validate.str.maxlength( $el ),
|
||||
email = _fn.validate.email.valid( $el ),
|
||||
response = {
|
||||
isValid: required && min && max && email
|
||||
};
|
||||
|
||||
if ( !response.isValid ) {
|
||||
response.message = _fn.validate.getMessage( $el, {
|
||||
required: required,
|
||||
// length: length,
|
||||
min: min,
|
||||
max: max,
|
||||
email: email
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
},
|
||||
|
||||
charLength: function( $el ) {
|
||||
@@ -39,11 +64,30 @@ var edx = edx || {};
|
||||
return within;
|
||||
},
|
||||
|
||||
required: function( $el ) {
|
||||
if ($el.attr("type") === "checkbox") {
|
||||
return $el.attr('required') ? $el.prop("checked") : true;
|
||||
str: {
|
||||
minlength: function( $el ) {
|
||||
var min = $el.attr('minlength') || 0;
|
||||
|
||||
return min <= $el.val().length;
|
||||
},
|
||||
|
||||
maxlength: function( $el ) {
|
||||
var max = $el.attr('maxlength') || false;
|
||||
|
||||
return ( !!max ) ? max >= $el.val().length : true;
|
||||
},
|
||||
|
||||
capitalizeFirstLetter: function( str ) {
|
||||
str = str.replace('_', ' ');
|
||||
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
}
|
||||
else {
|
||||
},
|
||||
|
||||
required: function( $el ) {
|
||||
if ( $el.attr('type') === 'checkbox' ) {
|
||||
return $el.attr('required') ? $el.prop('checked') : true;
|
||||
} else {
|
||||
return $el.attr('required') ? $el.val() : true;
|
||||
}
|
||||
},
|
||||
@@ -66,6 +110,26 @@ var edx = edx || {};
|
||||
format: function( str ) {
|
||||
return _fn.validate.email.regex.test( str );
|
||||
}
|
||||
},
|
||||
|
||||
getMessage: function( $el, tests ) {
|
||||
var txt = [],
|
||||
tpl,
|
||||
name;
|
||||
|
||||
_.each( tests, function( value, key ) {
|
||||
if ( !value ) {
|
||||
name = $el.attr('name');
|
||||
|
||||
tpl = _fn.validate.msg[key];
|
||||
|
||||
txt.push( _.template( tpl, {
|
||||
field: _fn.validate.str.capitalizeFirstLetter( name )
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
return txt.join(' ');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1030,6 +1030,7 @@ student_account_js = [
|
||||
'js/student_account/models/LoginModel.js',
|
||||
'js/student_account/models/RegisterModel.js',
|
||||
'js/student_account/models/PasswordResetModel.js',
|
||||
'js/student_account/views/FormView.js',
|
||||
'js/student_account/views/LoginView.js',
|
||||
'js/student_account/views/RegisterView.js',
|
||||
'js/student_account/views/PasswordResetView.js',
|
||||
@@ -1549,7 +1550,7 @@ REGISTRATION_EXTRA_FIELDS = {
|
||||
'honor_code': 'required',
|
||||
'terms_of_service': 'hidden',
|
||||
'city': 'hidden',
|
||||
'country': 'required',
|
||||
'country': 'hidden',
|
||||
}
|
||||
|
||||
########################## CERTIFICATE NAME ########################
|
||||
|
||||
@@ -52,18 +52,79 @@ var edx = edx || {};
|
||||
},
|
||||
|
||||
loadForm: function( type ) {
|
||||
if ( type === 'login' ) {
|
||||
this.subview.login = new edx.student.account.LoginView( this.thirdPartyAuth );
|
||||
if ( type === 'reset' ) {
|
||||
this.load.reset( this );
|
||||
} else {
|
||||
this.getFormData( type, this.load[type], this );
|
||||
}
|
||||
},
|
||||
|
||||
load: {
|
||||
login: function( data, context ) {
|
||||
var model = new edx.student.account.LoginModel({
|
||||
url: data.submit_url
|
||||
});
|
||||
|
||||
context.subview.login = new edx.student.account.LoginView({
|
||||
fields: data.fields,
|
||||
model: model,
|
||||
thirdPartyAuth: context.thirdPartyAuth
|
||||
});
|
||||
|
||||
// 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( this.thirdPartyAuth );
|
||||
} else if ( type === 'reset' ) {
|
||||
this.subview.passwordHelp = new edx.student.account.PasswordResetView();
|
||||
context.listenTo( context.subview.login, 'password-help', context.resetPassword );
|
||||
},
|
||||
|
||||
reset: function( context ) {
|
||||
var model = new edx.student.account.PasswordResetModel(),
|
||||
data = [{
|
||||
label: 'E-mail',
|
||||
instructions: 'This is the e-mail address you used to register with edX',
|
||||
name: 'email',
|
||||
required: true,
|
||||
type: 'email',
|
||||
restrictions: [],
|
||||
defaultValue: ''
|
||||
}];
|
||||
|
||||
context.subview.passwordHelp = new edx.student.account.PasswordResetView({
|
||||
fields: data,
|
||||
model: model
|
||||
});
|
||||
},
|
||||
|
||||
register: function( data, context ) {
|
||||
var model = new edx.student.account.RegisterModel({
|
||||
url: data.submit_url
|
||||
});
|
||||
|
||||
context.subview.register = new edx.student.account.RegisterView({
|
||||
fields: data.fields,
|
||||
model: model,
|
||||
thirdPartyAuth: context.thirdPartyAuth
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
getFormData: function( type, callback, context ) {
|
||||
var urls = {
|
||||
login: 'login_session',
|
||||
register: 'registration'
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
url: '/user_api/v1/account/' + urls[type] + '/',
|
||||
success: function( data ) {
|
||||
callback( data, context );
|
||||
},
|
||||
error: function( jqXHR, textStatus, errorThrown ) {
|
||||
console.log('fail ', errorThrown);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
resetPassword: function() {
|
||||
this.$header.addClass('hidden');
|
||||
$(this.el).find('.form-type').addClass('hidden');
|
||||
|
||||
176
lms/static/js/student_account/views/FormView.js
Normal file
176
lms/static/js/student_account/views/FormView.js
Normal file
@@ -0,0 +1,176 @@
|
||||
var edx = edx || {};
|
||||
|
||||
(function($, _, Backbone, gettext) {
|
||||
'use strict';
|
||||
|
||||
edx.student = edx.student || {};
|
||||
edx.student.account = edx.student.account || {};
|
||||
|
||||
edx.student.account.FormView = Backbone.View.extend({
|
||||
tagName: 'form',
|
||||
|
||||
el: '',
|
||||
|
||||
tpl: '',
|
||||
|
||||
fieldTpl: '#form_field-tpl',
|
||||
|
||||
events: {},
|
||||
|
||||
errors: [],
|
||||
|
||||
formType: '',
|
||||
|
||||
$form: {},
|
||||
|
||||
fields: [],
|
||||
|
||||
// String to append to required label fields
|
||||
requiredStr: '*',
|
||||
|
||||
initialize: function( data ) {
|
||||
this.tpl = $(this.tpl).html();
|
||||
this.fieldTpl = $(this.fieldTpl).html();
|
||||
|
||||
this.buildForm( data.fields );
|
||||
this.model = data.model;
|
||||
|
||||
this.listenTo( this.model, 'error', this.modelError );
|
||||
},
|
||||
|
||||
// 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('.submission-error');
|
||||
},
|
||||
|
||||
buildForm: function( data ) {
|
||||
var html = [],
|
||||
i,
|
||||
len = data.length,
|
||||
fieldTpl = this.fieldTpl;
|
||||
|
||||
this.fields = data;
|
||||
|
||||
for ( i=0; i<len; i++ ) {
|
||||
html.push( _.template( fieldTpl, $.extend( data[i], {
|
||||
form: this.formType,
|
||||
requiredStr: this.requiredStr
|
||||
}) ) );
|
||||
}
|
||||
|
||||
this.render( html.join('') );
|
||||
},
|
||||
|
||||
getFormData: function() {
|
||||
|
||||
var obj = {},
|
||||
$form = this.$form,
|
||||
elements = $form[0].elements,
|
||||
i,
|
||||
len = elements.length,
|
||||
$el,
|
||||
$label,
|
||||
key = '',
|
||||
errors = [],
|
||||
// $status = $form.find('.status'),
|
||||
test = {};
|
||||
|
||||
for ( i=0; i<len; i++ ) {
|
||||
|
||||
$el = $( elements[i] );
|
||||
$label = $form.find('label[for=' + $el.attr('id') + ']');
|
||||
key = $el.attr('name') || false;
|
||||
|
||||
if ( key ) {
|
||||
test = this.validate( elements[i], this.formType );
|
||||
|
||||
if ( test.isValid ) {
|
||||
obj[key] = $el.attr('type') === 'checkbox' ? $el.is(':checked') : $el.val();
|
||||
$el.removeClass('error');
|
||||
$label.removeClass('error');
|
||||
} else {
|
||||
errors.push( test.message );
|
||||
$el.addClass('error');
|
||||
$label.addClass('error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.errors = _.uniq( errors );
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
forgotPassword: function( event ) {
|
||||
event.preventDefault();
|
||||
|
||||
this.trigger('password-help');
|
||||
},
|
||||
|
||||
submitForm: function( event ) {
|
||||
var data = this.getFormData();
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if ( !_.compact(this.errors).length ) {
|
||||
this.model.set( data );
|
||||
this.model.save();
|
||||
this.toggleErrorMsg( false );
|
||||
} else {
|
||||
this.toggleErrorMsg( true );
|
||||
}
|
||||
},
|
||||
|
||||
toggleErrorMsg: function( show ) {
|
||||
if ( show ) {
|
||||
this.setErrors();
|
||||
} else {
|
||||
this.$errors
|
||||
.addClass('hidden')
|
||||
.attr('aria-hidden', true);
|
||||
}
|
||||
},
|
||||
|
||||
setErrors: function() {
|
||||
var $msg = this.$errors.find('.message-copy'),
|
||||
html = [],
|
||||
errors = this.errors,
|
||||
i,
|
||||
len = errors.length;
|
||||
|
||||
for ( i=0; i<len; i++ ) {
|
||||
html.push( errors[i] );
|
||||
}
|
||||
|
||||
$msg.html( html.join('') );
|
||||
|
||||
this.$errors
|
||||
.removeClass('hidden')
|
||||
.attr('aria-hidden', false);
|
||||
},
|
||||
|
||||
modelError: function( error ) {
|
||||
console.log('error ', error);
|
||||
},
|
||||
|
||||
validate: function( $el, form ) {
|
||||
return edx.utils.validate( $el, form );
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery, _, Backbone, gettext);
|
||||
@@ -6,36 +6,34 @@ var edx = edx || {};
|
||||
edx.student = edx.student || {};
|
||||
edx.student.account = edx.student.account || {};
|
||||
|
||||
edx.student.account.LoginView = Backbone.View.extend({
|
||||
tagName: 'form',
|
||||
|
||||
edx.student.account.LoginView = edx.student.account.FormView.extend({
|
||||
el: '#login-form',
|
||||
|
||||
tpl: '#login-tpl',
|
||||
|
||||
fieldTpl: '#form_field-tpl',
|
||||
|
||||
events: {
|
||||
'click .js-login': 'submitForm',
|
||||
'click .forgot-password': 'forgotPassword',
|
||||
'click .login-provider': 'thirdPartyAuth'
|
||||
},
|
||||
|
||||
errors: [],
|
||||
formType: 'login',
|
||||
|
||||
$form: {},
|
||||
requiredStr: '',
|
||||
|
||||
initialize: function( thirdPartyAuthInfo ) {
|
||||
initialize: function( data ) {
|
||||
this.tpl = $(this.tpl).html();
|
||||
this.fieldTpl = $(this.fieldTpl).html();
|
||||
|
||||
this.providers = thirdPartyAuthInfo.providers || [];
|
||||
this.currentProvider = thirdPartyAuthInfo.currentProvider || "";
|
||||
this.buildForm( data.fields );
|
||||
this.model = data.model;
|
||||
|
||||
this.getInitialData();
|
||||
this.providers = data.thirdPartyAuth.providers || [];
|
||||
this.currentProvider = data.thirdPartyAuth.currentProvider || '';
|
||||
|
||||
this.listenTo( this.model, 'error', this.saveError );
|
||||
},
|
||||
|
||||
// Renders the form.
|
||||
render: function( html ) {
|
||||
var fields = html || '';
|
||||
|
||||
@@ -52,145 +50,45 @@ var edx = edx || {};
|
||||
|
||||
postRender: function() {
|
||||
var $container = $(this.el);
|
||||
|
||||
this.$form = $container.find('form');
|
||||
this.$errors = $container.find('.error-msg');
|
||||
this.$errors = $container.find('.submission-error');
|
||||
this.$alreadyAuthenticatedMsg = $container.find('.already-authenticated-msg');
|
||||
|
||||
// If we're already authenticated with a third-party
|
||||
// provider, try logging in. The easiest way to do this
|
||||
// is to simply submit the form.
|
||||
/* If we're already authenticated with a third-party
|
||||
* provider, try logging in. The easiest way to do this
|
||||
* is to simply submit the form.
|
||||
*/
|
||||
if (this.currentProvider) {
|
||||
this.model.save();
|
||||
}
|
||||
},
|
||||
|
||||
getInitialData: function() {
|
||||
var that = this;
|
||||
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
url: '/user_api/v1/account/login_session/',
|
||||
success: function( data ) {
|
||||
console.log(data);
|
||||
that.initModel( data.submit_url, data.method );
|
||||
that.buildForm( data.fields );
|
||||
},
|
||||
error: function( jqXHR, textStatus, errorThrown ) {
|
||||
console.log('fail ', errorThrown);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
initModel: function( url ) {
|
||||
this.model = new edx.student.account.LoginModel({
|
||||
url: url
|
||||
});
|
||||
|
||||
this.listenTo( this.model, 'error', this.saveError );
|
||||
},
|
||||
|
||||
buildForm: function( data ) {
|
||||
var html = [],
|
||||
i,
|
||||
len = data.length,
|
||||
fieldTpl = this.fieldTpl;
|
||||
|
||||
for ( i=0; i<len; i++ ) {
|
||||
html.push( _.template( fieldTpl, $.extend( data[i], {
|
||||
form: 'login'
|
||||
}) ) );
|
||||
}
|
||||
|
||||
this.render( html.join('') );
|
||||
},
|
||||
|
||||
getFormData: function() {
|
||||
|
||||
var obj = {},
|
||||
$form = this.$form,
|
||||
elements = $form[0].elements,
|
||||
i,
|
||||
len = elements.length,
|
||||
$el,
|
||||
key = '',
|
||||
errors = [];
|
||||
|
||||
for ( i=0; i<len; i++ ) {
|
||||
|
||||
$el = $( elements[i] );
|
||||
key = $el.attr('name') || false;
|
||||
|
||||
if ( key ) {
|
||||
if ( this.validate( elements[i] ) ) {
|
||||
obj[key] = $el.attr('type') === 'checkbox' ? $el.is(':checked') : $el.val();
|
||||
$el.css('border', '1px solid #ccc');
|
||||
} else {
|
||||
errors.push( key );
|
||||
$el.css('border', '2px solid red');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.errors = errors;
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
forgotPassword: function( event ) {
|
||||
event.preventDefault();
|
||||
|
||||
this.trigger('password-help');
|
||||
},
|
||||
|
||||
submitForm: function( event ) {
|
||||
var data = this.getFormData();
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
// console.log(this.model);
|
||||
|
||||
if ( !this.errors.length ) {
|
||||
console.log('save me');
|
||||
this.model.set( data );
|
||||
this.model.save();
|
||||
this.toggleErrorMsg( false );
|
||||
} else {
|
||||
console.log('here are the errors ', this.errors);
|
||||
this.toggleErrorMsg( true );
|
||||
}
|
||||
},
|
||||
|
||||
thirdPartyAuth: function( event ) {
|
||||
var providerUrl = $(event.target).data("provider-url") || "";
|
||||
var providerUrl = $(event.target).data('provider-url') || '';
|
||||
if (providerUrl) {
|
||||
window.location.href = providerUrl;
|
||||
} else {
|
||||
// TODO -- error handling here
|
||||
console.log("No URL available for third party auth provider");
|
||||
console.log('No URL available for third party auth provider');
|
||||
}
|
||||
},
|
||||
|
||||
toggleErrorMsg: function( show ) {
|
||||
if ( show ) {
|
||||
this.$errors.removeClass('hidden');
|
||||
} else {
|
||||
this.$errors.addClass('hidden');
|
||||
}
|
||||
},
|
||||
|
||||
validate: function( $el ) {
|
||||
return edx.utils.validate( $el );
|
||||
},
|
||||
|
||||
saveError: function( error ) {
|
||||
console.log(error.status, ' error: ', error.responseText);
|
||||
|
||||
// If we've gotten a 401 error, it means that we've successfully
|
||||
// authenticated with a third-party provider, but we haven't
|
||||
// linked the account to an EdX account. In this case,
|
||||
// we need to prompt the user to enter a little more information
|
||||
// to complete the registration process.
|
||||
/* If we've gotten a 401 error, it means that we've successfully
|
||||
* authenticated with a third-party provider, but we haven't
|
||||
* linked the account to an EdX account. In this case,
|
||||
* we need to prompt the user to enter a little more information
|
||||
* to complete the registration process.
|
||||
*/
|
||||
if (error.status === 401 && this.currentProvider) {
|
||||
this.$alreadyAuthenticatedMsg.removeClass("hidden");
|
||||
}
|
||||
@@ -198,6 +96,7 @@ var edx = edx || {};
|
||||
this.$alreadyAuthenticatedMsg.addClass("hidden");
|
||||
// TODO -- display the error
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -6,116 +6,37 @@ var edx = edx || {};
|
||||
edx.student = edx.student || {};
|
||||
edx.student.account = edx.student.account || {};
|
||||
|
||||
edx.student.account.PasswordResetView = Backbone.View.extend({
|
||||
tagName: 'form',
|
||||
|
||||
edx.student.account.PasswordResetView = edx.student.account.FormView.extend({
|
||||
el: '#password-reset-wrapper',
|
||||
|
||||
tpl: '#password_reset-tpl',
|
||||
|
||||
fieldTpl: '#form_field-tpl',
|
||||
|
||||
events: {
|
||||
'click .js-reset': 'submitForm'
|
||||
},
|
||||
|
||||
errors: [],
|
||||
|
||||
mode: {},
|
||||
|
||||
$form: {},
|
||||
|
||||
initialize: function() {
|
||||
this.fieldTpl = $(this.fieldTpl).html();
|
||||
|
||||
var fields = this.buildForm([{
|
||||
name: 'email',
|
||||
label: 'Email',
|
||||
defaultValue: '',
|
||||
type: 'text',
|
||||
required: true,
|
||||
placeholder: 'xsy@edx.org',
|
||||
instructions: 'This is the email address you used to register with edX.',
|
||||
restrictions: {}
|
||||
}]);
|
||||
|
||||
this.tpl = $(this.tpl).html();
|
||||
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;
|
||||
},
|
||||
requiredStr: '',
|
||||
|
||||
postRender: function() {
|
||||
var $container = $(this.el);
|
||||
|
||||
this.$form = $container.find('form');
|
||||
this.$errors = $container.find('.error-msg');
|
||||
|
||||
this.$resetFail = $container.find('.js-reset-fail');
|
||||
this.$errors = $container.find('.submission-error');
|
||||
|
||||
this.listenTo( this.model, 'success', this.resetComplete );
|
||||
this.listenTo( this.model, 'error', this.resetError );
|
||||
},
|
||||
|
||||
initModel: function() {
|
||||
this.model = new edx.student.account.PasswordResetModel();
|
||||
},
|
||||
|
||||
buildForm: function( data ) {
|
||||
var html = [],
|
||||
i,
|
||||
len = data.length,
|
||||
fieldTpl = this.fieldTpl;
|
||||
|
||||
for ( i=0; i<len; i++ ) {
|
||||
html.push( _.template( fieldTpl, $.extend( data[i], {
|
||||
form: 'reset-password'
|
||||
}) ) );
|
||||
toggleErrorMsg: function( show ) {
|
||||
if ( show ) {
|
||||
this.setErrors();
|
||||
} else {
|
||||
this.$errors
|
||||
.addClass('hidden')
|
||||
.attr('aria-hidden', true);
|
||||
}
|
||||
|
||||
return html.join('');
|
||||
},
|
||||
|
||||
getFormData: function() {
|
||||
var obj = {},
|
||||
$form = this.$form,
|
||||
elements = $form[0].elements,
|
||||
i,
|
||||
len = elements.length,
|
||||
$el,
|
||||
key = '',
|
||||
errors = [];
|
||||
|
||||
for ( i=0; i<len; i++ ) {
|
||||
|
||||
$el = $( elements[i] );
|
||||
key = $el.attr('name') || false;
|
||||
|
||||
if ( key ) {
|
||||
if ( this.validate( elements[i] ) ) {
|
||||
obj[key] = $el.attr('type') === 'checkbox' ? $el.is(':checked') : $el.val();
|
||||
$el.css('border', '1px solid #ccc');
|
||||
} else {
|
||||
errors.push( key );
|
||||
$el.css('border', '2px solid red');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.errors = errors;
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
resetComplete: function() {
|
||||
@@ -136,7 +57,7 @@ var edx = edx || {};
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if ( !this.errors.length ) {
|
||||
if ( !_.compact(this.errors).length ) {
|
||||
this.model.set( data );
|
||||
this.model.save();
|
||||
this.toggleErrorMsg( false );
|
||||
@@ -145,14 +66,6 @@ var edx = edx || {};
|
||||
}
|
||||
},
|
||||
|
||||
toggleErrorMsg: function( show ) {
|
||||
if ( show ) {
|
||||
this.$errors.removeClass('hidden');
|
||||
} else {
|
||||
this.$errors.addClass('hidden');
|
||||
}
|
||||
},
|
||||
|
||||
validate: function( $el ) {
|
||||
return edx.utils.validate( $el );
|
||||
}
|
||||
|
||||
@@ -6,34 +6,27 @@ var edx = edx || {};
|
||||
edx.student = edx.student || {};
|
||||
edx.student.account = edx.student.account || {};
|
||||
|
||||
edx.student.account.RegisterView = Backbone.View.extend({
|
||||
tagName: 'form',
|
||||
|
||||
edx.student.account.RegisterView = edx.student.account.FormView.extend({
|
||||
el: '#register-form',
|
||||
|
||||
tpl: '#register-tpl',
|
||||
|
||||
fieldTpl: '#form_field-tpl',
|
||||
|
||||
events: {
|
||||
'click .js-register': 'submitForm',
|
||||
'click .login-provider': 'thirdPartyAuth'
|
||||
},
|
||||
|
||||
errors: [],
|
||||
|
||||
$form: {},
|
||||
|
||||
initialize: function( thirdPartyAuthInfo ) {
|
||||
initialize: function( data ) {
|
||||
this.tpl = $(this.tpl).html();
|
||||
this.fieldTpl = $(this.fieldTpl).html(),
|
||||
this.fieldTpl = $(this.fieldTpl).html();
|
||||
|
||||
this.providers = thirdPartyAuthInfo.providers || [];
|
||||
this.currentProvider = thirdPartyAuthInfo.currentProvider || "";
|
||||
this.getInitialData();
|
||||
this.buildForm( data.fields );
|
||||
this.model = data.model;
|
||||
|
||||
this.providers = data.thirdPartyAuth.providers || [];
|
||||
this.currentProvider = data.thirdPartyAuth.currentProvider || '';
|
||||
},
|
||||
|
||||
// Renders the form.
|
||||
render: function( html ) {
|
||||
var fields = html || '';
|
||||
|
||||
@@ -48,127 +41,14 @@ var edx = edx || {};
|
||||
return this;
|
||||
},
|
||||
|
||||
postRender: function() {
|
||||
var $container = $(this.el);
|
||||
|
||||
this.$form = $container.find('form');
|
||||
this.$errors = $container.find('.error-msg');
|
||||
},
|
||||
|
||||
getInitialData: function() {
|
||||
var that = this;
|
||||
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
url: '/user_api/v1/account/registration/',
|
||||
success: function( data ) {
|
||||
console.log(data);
|
||||
that.buildForm( data.fields );
|
||||
that.initModel( data.submit_url, data.method );
|
||||
},
|
||||
error: function( jqXHR, textStatus, errorThrown ) {
|
||||
console.log('fail ', errorThrown);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
initModel: function( url ) {
|
||||
this.model = new edx.student.account.RegisterModel({
|
||||
url: url
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
for ( i=0; i<len; i++ ) {
|
||||
html.push( _.template( fieldTpl, $.extend( data[i], {
|
||||
form: 'register'
|
||||
}) ) );
|
||||
}
|
||||
|
||||
this.render( html.join('') );
|
||||
},
|
||||
|
||||
getFormData: function() {
|
||||
|
||||
var obj = {},
|
||||
$form = this.$form,
|
||||
elements = $form[0].elements,
|
||||
i,
|
||||
len = elements.length,
|
||||
$el,
|
||||
key = '',
|
||||
errors = [];
|
||||
|
||||
for ( i=0; i<len; i++ ) {
|
||||
|
||||
$el = $( elements[i] );
|
||||
key = $el.attr('name') || false;
|
||||
|
||||
if ( key ) {
|
||||
if ( this.validate( elements[i] ) ) {
|
||||
obj[key] = $el.attr('type') === 'checkbox' ? $el.is(':checked') : $el.val();
|
||||
$el.css('border', '1px solid #ccc');
|
||||
} else {
|
||||
errors.push( key );
|
||||
$el.css('border', '2px solid red');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.errors = errors;
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
submitForm: function( event ) {
|
||||
var data = this.getFormData();
|
||||
|
||||
event.preventDefault();
|
||||
console.log(data);
|
||||
// console.log(this.model);
|
||||
|
||||
if ( !this.errors.length ) {
|
||||
console.log('save me');
|
||||
this.model.set( data );
|
||||
console.log(this.model);
|
||||
this.model.save();
|
||||
this.toggleErrorMsg( false );
|
||||
} else {
|
||||
console.log('here are the errors ', this.errors);
|
||||
this.toggleErrorMsg( true );
|
||||
}
|
||||
},
|
||||
|
||||
thirdPartyAuth: function( event ) {
|
||||
var providerUrl = $(event.target).data("provider-url") || "";
|
||||
var providerUrl = $(event.target).data('provider-url') || '';
|
||||
if (providerUrl) {
|
||||
window.location.href = providerUrl;
|
||||
} else {
|
||||
// TODO -- error handling here
|
||||
console.log("No URL available for third party auth provider");
|
||||
console.log('No URL available for third party auth provider');
|
||||
}
|
||||
},
|
||||
|
||||
toggleErrorMsg: function( show ) {
|
||||
if ( show ) {
|
||||
this.$errors.removeClass('hidden');
|
||||
} else {
|
||||
this.$errors.addClass('hidden');
|
||||
}
|
||||
},
|
||||
|
||||
validate: function( $el ) {
|
||||
return edx.utils.validate( $el );
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
// lms - views - login/register view
|
||||
// ====================
|
||||
|
||||
%heading-4 {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0 !important;
|
||||
color: $m-gray-d2;
|
||||
}
|
||||
|
||||
%body-text {
|
||||
font-size: 15px;
|
||||
margin: 0 0 $baseline 0;
|
||||
color: $base-font-color;
|
||||
line-height: lh(1);
|
||||
}
|
||||
|
||||
.section-bkg-wrapper {
|
||||
background: $m-gray-l4;
|
||||
}
|
||||
@@ -128,6 +144,9 @@
|
||||
display: inline;
|
||||
}
|
||||
|
||||
&.error {
|
||||
color: $red;
|
||||
}
|
||||
}
|
||||
|
||||
.field-link {
|
||||
@@ -199,6 +218,62 @@
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/** Error Container - from _account.scss **/
|
||||
.status {
|
||||
@include box-sizing(border-box);
|
||||
margin: 0 0 $baseline 0;
|
||||
border-bottom: 3px solid shade($yellow, 10%);
|
||||
padding: $baseline $baseline;
|
||||
background: tint($yellow,20%);
|
||||
|
||||
.message-title {
|
||||
@extend %heading-4;
|
||||
margin: 0 0 ($baseline/4) 0;
|
||||
font-size: em(14);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.message-copy {
|
||||
@extend %body-text;
|
||||
margin: 0 !important;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
margin: 0 0 ($baseline/4) 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.submission-error, .system-error {
|
||||
box-shadow: inset 0 -1px 2px 0 tint($red, 85%);
|
||||
border-bottom: 3px solid shade($red, 10%);
|
||||
background: tint($red,95%);
|
||||
|
||||
.message-title {
|
||||
color: shade($red, 10%) !important;
|
||||
}
|
||||
|
||||
.message-copy {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.submission-success {
|
||||
box-shadow: inset 0 -1px 2px 0 tint($green, 85%);
|
||||
border-bottom: 3px solid shade($green, 10%);
|
||||
background: tint($green, 95%);
|
||||
|
||||
.message-title {
|
||||
color: shade($green, 10%) !important;
|
||||
}
|
||||
|
||||
.message-copy {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/** RWD **/
|
||||
@include media( $tablet ) {
|
||||
$grid-columns: 8;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<% if ( type !== 'checkbox' ) { %>
|
||||
<label for="<%= form %>-<%= name %>">
|
||||
<%= label %>
|
||||
<% if ( required ) { %> *</label><% } %>
|
||||
<% if ( required && requiredStr ) { %> <%= requiredStr %></label><% } %>
|
||||
</label>
|
||||
<% } %>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<% if ( type === 'checkbox' ) { %>
|
||||
<label for="<%= form %>-<%= name %>" class="inline">
|
||||
<%= label %>
|
||||
<% if ( required ) { %> *</label><% } %>
|
||||
<% if ( required && requiredStr ) { %> <%= requiredStr %></label><% } %>
|
||||
</label>
|
||||
<% } %>
|
||||
|
||||
|
||||
@@ -1,26 +1,21 @@
|
||||
<form id="login">
|
||||
<div class="error-msg hidden">
|
||||
<h4>We couldn't log you in.</h4>
|
||||
<div class="errors">
|
||||
<div class="status submission-error hidden" aria-hidden="true">
|
||||
<h4 class="message-title">We couldn't log you in.</h4>
|
||||
<div class="message-copy">
|
||||
<p>Email or password is incorrent. <a href="#">Forgot password?</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="already-authenticated-msg hidden">
|
||||
<% if (currentProvider) { %>
|
||||
<p class="instructions">
|
||||
You've successfully logged into <%- currentProvider %>, but you need to link
|
||||
your account. Please click "I am a returning user" to create
|
||||
an EdX account.
|
||||
</p>
|
||||
<p class="instructions">You've successfully logged into <%- currentProvider %>, but you need to link your account. Please click "I am a returning user" to create an EdX account.</p>
|
||||
<% } %>
|
||||
</div>
|
||||
<%= fields %>
|
||||
<button class="action action-primary action-update js-login">Log in</button>
|
||||
</form>
|
||||
<% for (var i=0; i < providers.length; i++) {
|
||||
var provider = providers[i];
|
||||
%>
|
||||
|
||||
<% _.each( providers, function( provider) { %>
|
||||
<button type="submit"class="button button-primary button-<%- provider.name %> login-provider" data-provider-url="<%- provider.loginUrl %>">
|
||||
<span class="icon <%- provider.iconClass %>"></span>Sign in with <%- provider.name %>
|
||||
</button>
|
||||
<% } %>
|
||||
<% }); %>
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
</header>
|
||||
|
||||
<section class="form-type">
|
||||
<p class="action-label">Please enter your email address below and we will send you instructions for setting a new password.</p>
|
||||
<div id="password-reset-form" class="form-wrapper">
|
||||
<form>
|
||||
<div class="error-msg hidden">
|
||||
<h4>An error occured.</h4>
|
||||
<div class="errors">
|
||||
<p>Please enter a valid email address</p>
|
||||
<p class="action-label">Please enter your email address below and we will send you instructions for setting a new password.</p>
|
||||
<form id="password-reset-form">
|
||||
<div class="status submission-error hidden" aria-hidden="true">
|
||||
<h4 class="message-title">An error occurred.</h4>
|
||||
<div class="message-copy">
|
||||
<p>Please provide a valid email.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,9 +19,11 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="js-reset-success hidden">
|
||||
<h2>Password Reset Successful</h2>
|
||||
<p>We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly.</p>
|
||||
<div class="js-reset-success status submission-success hidden" aria-hidden="true">
|
||||
<h4 class="message-title">Password Reset Successful</h4>
|
||||
<div class="message-copy">
|
||||
<p>We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="js-reset-fail hidden">
|
||||
<h2>Password Reset Failed</h2>
|
||||
|
||||
@@ -4,20 +4,18 @@
|
||||
We just need a little more information before you start learning with edX.
|
||||
</p>
|
||||
<% } else {
|
||||
for (var i=0; i < providers.length; i++) {
|
||||
var provider = providers[i];
|
||||
%>
|
||||
<button type="submit"class="button button-primary button-<%- provider.name %> login-provider" data-provider-url="<%- provider.registerUrl %>">
|
||||
<span class="icon <%- provider.iconClass %>"></span>Sign up with <%- provider.name %>
|
||||
</button>
|
||||
<% }
|
||||
_.each( providers, function( provider) { %>
|
||||
<button type="submit"class="button button-primary button-<%- provider.name %> login-provider" data-provider-url="<%- provider.registerUrl %>">
|
||||
<span class="icon <%- provider.iconClass %>"></span>Sign up with <%- provider.name %>
|
||||
</button>
|
||||
<% });
|
||||
} %>
|
||||
|
||||
<form id="register" autocomplete="off">
|
||||
<div class="error-msg hidden">
|
||||
<h4>An error occured in your registration.</h4>
|
||||
<div class="errors">
|
||||
<p>Please enter a valid password</p>
|
||||
<div class="status submission-error hidden" aria-hidden="true">
|
||||
<h4 class="message-title">An error occurred in your registration.</h4>
|
||||
<div class="message-copy">
|
||||
<p>Please provide a valid email.</p>
|
||||
</div>
|
||||
</div>
|
||||
<%= fields %>
|
||||
|
||||
Reference in New Issue
Block a user