187 lines
7.1 KiB
JavaScript
187 lines
7.1 KiB
JavaScript
var edx = edx || {};
|
|
|
|
(function( $, _, _s, gettext ) {
|
|
'use strict';
|
|
|
|
/* Mix non-conflicting functions from underscore.string
|
|
* (all but include, contains, and reverse) into the
|
|
* Underscore namespace. In practice, this mixin is done
|
|
* by the access view, but doing it here helps keep the
|
|
* utility self-contained.
|
|
*/
|
|
_.mixin( _.str.exports() );
|
|
|
|
edx.utils = edx.utils || {};
|
|
|
|
var utils = (function(){
|
|
var _fn = {
|
|
validate: {
|
|
|
|
msg: {
|
|
email: '<li><%- gettext("The email address you\'ve provided isn\'t formatted correctly.") %></li>',
|
|
min: '<li><%- _.sprintf( gettext("%(field)s must have at least %(count)d characters."), context ) %></li>',
|
|
max: '<li><%- _.sprintf( gettext("%(field)s can only contain up to %(count)d characters."), context ) %></li>',
|
|
required: '<li><%- _.sprintf( gettext("Please enter your %(field)s."), context ) %></li>',
|
|
custom: '<li><%= content %></li>'
|
|
},
|
|
|
|
field: function( el ) {
|
|
var $el = $(el),
|
|
required = true,
|
|
min = true,
|
|
max = true,
|
|
email = true,
|
|
response = {},
|
|
isBlank = _fn.validate.isBlank( $el );
|
|
|
|
if ( _fn.validate.isRequired( $el ) ) {
|
|
if ( isBlank ) {
|
|
required = false;
|
|
} else {
|
|
min = _fn.validate.str.minlength( $el );
|
|
max = _fn.validate.str.maxlength( $el );
|
|
email = _fn.validate.email.valid( $el );
|
|
}
|
|
} else if ( !isBlank ) {
|
|
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 ) {
|
|
_fn.validate.removeDefault( $el );
|
|
|
|
response.message = _fn.validate.getMessage( $el, {
|
|
required: required,
|
|
min: min,
|
|
max: max,
|
|
email: email
|
|
});
|
|
}
|
|
|
|
return response;
|
|
},
|
|
|
|
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;
|
|
}
|
|
},
|
|
|
|
isRequired: function( $el ) {
|
|
return $el.attr('required');
|
|
},
|
|
|
|
isBlank: function( $el ) {
|
|
var type = $el.attr('type'),
|
|
isBlank;
|
|
|
|
if ( type === 'checkbox' ) {
|
|
isBlank = !$el.prop('checked');
|
|
} else if ( type === 'select' ) {
|
|
isBlank = ( $el.data('isdefault') === true );
|
|
} else {
|
|
isBlank = !$el.val();
|
|
}
|
|
|
|
return isBlank;
|
|
},
|
|
|
|
email: {
|
|
// This is the same regex used to validate email addresses in Django 1.4
|
|
regex: new RegExp(
|
|
[
|
|
'(^[-!#$%&\'*+/=?^_`{}|~0-9A-Z]+(\\.[-!#$%&\'*+/=?^_`{}|~0-9A-Z]+)*',
|
|
'|^"([\\001-\\010\\013\\014\\016-\\037!#-\\[\\]-\\177]|\\\\[\\001-\\011\\013\\014\\016-\\177])*"',
|
|
')@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\\.)+[A-Z]{2,6}\\.?$)',
|
|
'|\\[(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\]$'
|
|
].join(''), 'i'
|
|
),
|
|
|
|
valid: function( $el ) {
|
|
return $el.attr('type') === 'email' ? _fn.validate.email.format( $el.val() ) : true;
|
|
},
|
|
|
|
format: function( str ) {
|
|
return _fn.validate.email.regex.test( str );
|
|
}
|
|
},
|
|
|
|
getLabel: function( id ) {
|
|
// Extract the field label, remove the asterisk (if it appears) and any extra whitespace
|
|
return $("label[for=" + id + "]").text().split("*")[0].trim();
|
|
},
|
|
|
|
getMessage: function( $el, tests ) {
|
|
var txt = [],
|
|
tpl,
|
|
label,
|
|
obj,
|
|
customMsg;
|
|
|
|
_.each( tests, function( value, key ) {
|
|
if ( !value ) {
|
|
label = _fn.validate.getLabel( $el.attr('id') );
|
|
customMsg = $el.data('errormsg-' + key) || false;
|
|
|
|
// If the field has a custom error msg attached, use it
|
|
if ( customMsg ) {
|
|
tpl = _fn.validate.msg.custom;
|
|
|
|
obj = {
|
|
content: customMsg
|
|
};
|
|
} else {
|
|
tpl = _fn.validate.msg[key];
|
|
|
|
obj = {
|
|
// We pass the context object to the template so that
|
|
// we can perform variable interpolation using sprintf
|
|
context: {
|
|
field: label
|
|
}
|
|
};
|
|
|
|
if ( key === 'min' ) {
|
|
obj.context.count = parseInt( $el.attr('minlength'), 10 );
|
|
} else if ( key === 'max' ) {
|
|
obj.context.count = parseInt( $el.attr('maxlength'), 10 );
|
|
}
|
|
}
|
|
|
|
txt.push( _.template( tpl, obj ) );
|
|
}
|
|
});
|
|
|
|
return txt.join(' ');
|
|
},
|
|
|
|
// Removes the default HTML5 validation pop-up
|
|
removeDefault: function( $el ) {
|
|
if ( $el.setCustomValidity ) {
|
|
$el.setCustomValidity(' ');
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
return {
|
|
validate: _fn.validate.field
|
|
};
|
|
|
|
})();
|
|
|
|
edx.utils.validate = utils.validate;
|
|
|
|
})( jQuery, _, _.str, gettext );
|