Really simple model-validation for Ember.JS (ember-cli), by extending a model with extra validation functionality. Put this file in your models directory and read the instruction in the comment
/** | |
* Really simple model-validation | |
* by extending a model with | |
* extra validation functionality | |
* | |
* Here's how it works | |
* /your-app/models/person.js: | |
* import DS from 'ember-data'; | |
* import Validation from 'your-app/models/validation'; | |
* | |
* export default Validation.extend({ | |
* firstName : DS.attr('string'), // required | |
* lastName : DS.attr('string'), // required | |
* age : DS.attr('integer'), // numeric | |
* town : DS.attr('string'), // optional | |
* married : DS.attr('boolean', | |
{defaultValue: false}), // boolean | |
* email : DS.attr('string'), // e-mail | |
* | |
* requiredFields : ['firstName', 'lastName', 'age'], | |
* numericFields : ['age'], | |
* booleanFields : ['married'], | |
* emailFields : ['email'] | |
* }); | |
* | |
* Elsewhere in your code: | |
* var x = this.store.createRecord('person'); | |
* x.firstName = 'Austin'; // is OK | |
* x.lastName = 'Powers'; // is OK | |
* x.town = 'London'; // is OK | |
* x.age = 'thirty'; // fails | |
* x.married = 'not really'; // fails | |
* x.email = 'fax only'; // fails | |
* var ok = x.is_valid(); | |
* if( ok ) { | |
* console.log('OK'); | |
* }else{ | |
* console.log('ERROR'); | |
* console.log('All error-messages:', x.get('errors').get('messages')); | |
* } | |
* | |
* or validate fields specificly: | |
* if( !this.get('model').is_valid_field( 'firstName' ) ) { | |
* console.log('firstName' + ' has error:'); | |
* this.get('model').get('errors').errorsFor( 'firstName' ).forEach(function(err){ | |
* console.log(err.message); | |
* }); | |
* }else{ | |
* console.log('firstName' + ' is all good'); | |
* } | |
* | |
* | |
* Those model-errors are very useful in your templates | |
* where you could either use all error-messages: | |
* model.errors.messages | |
* or field-specific error-messages: | |
* model.errors.age.errors (=array where each error-item has a message) | |
* More info regarding model-errors at: http://emberjs.com/api/data/classes/DS.Errors.html | |
* | |
* Setting the error messages can be done in two ways; | |
* Override the default-messages directly on the model: | |
* export default Validation.extend({ | |
* MESSAGE_REQUIRED : "Just anything..", | |
* MESSAGE_NUMERIC : "All I want is a frickin' number", | |
* MESSAGE_BOOLEAN : "Don't you bool me!", | |
* MESSAGE_EMAIL: "Valid email, please..." | |
* | |
* firstName : "", // required | |
* lastName : "", // required | |
* age : 0, // numeric | |
* town : "", // optional | |
* married : false, // boolean | |
* email : "", // e-mail | |
* | |
* requiredFields : ['firstName', 'lastName', 'age'], | |
* numericFields : ['age'], | |
* booleanFields : ['married'], | |
* emailFields : ['email'] | |
* }); | |
* | |
* or pass your messages when calling the validation methods: | |
* x.is_valid({ | |
* message_required: "Just anything..", | |
* message_numeric: "All I want is a frickin' number", | |
* message_boolean: "Don't you bool me!", | |
* message_email: "Valid email, please..." | |
* }); | |
* x.is_valid_field('firstName', { | |
* message_required: "Just anything..", | |
* message_numeric: "All I want is a frickin' number", | |
* message_boolean: "Don't you bool me!", | |
* message_email: "Valid email, please..." | |
* }); | |
* | |
* | |
* @author sejKo | |
* @version 0.2.1 | |
* | |
*/ | |
import DS from 'ember-data'; | |
export default DS.Model.extend({ | |
/** | |
* Override this field by populating an array | |
* with names of fields which are required | |
*/ | |
requiredFields : [], | |
/** | |
* Override this field by populating an array | |
* with names of fields which must be numeric | |
*/ | |
numericFields : [], | |
/** | |
* Override this field by populating an array | |
* with names of fields which must be booleans | |
*/ | |
booleanFields : [], | |
/** | |
* Override this field by populating an array | |
* with names of fields which must be valid e-mail adresses | |
*/ | |
emailFields : [], | |
/** | |
* Default messages | |
*/ | |
MESSAGE_REQUIRED : 'This field is required', | |
MESSAGE_NUMERIC : 'This field must be numeric', | |
MESSAGE_BOOLEAN : 'This field must be True / False', | |
MESSAGE_EMAIL : 'This field must contain a valid e-mail address', | |
/** | |
* Public method to call to validate a model instance | |
* | |
* How to set field-messages : | |
* myModel.is_valid({ | |
* message_required: "Just anything..", | |
* message_numeric: "All I want is a frickin' number", | |
* message_boolean: "Don't you bool me!", | |
* message_email: "Valid email, please..." | |
* }); | |
* | |
* @param object optional | |
* @return boolean | |
*/ | |
is_valid : function ( messages ) { | |
var msgs = messages || {}; | |
var message_required = msgs.message_required || null; | |
var message_numeric = msgs.message_numeric || null; | |
var message_boolean = msgs.message_boolean || null; | |
var message_email = msgs.message_email || null; | |
this.get('errors').clear(); | |
var ok = true; | |
if( !this._is_valid_required( message_required ) ){ ok = false; } | |
if( !this._is_valid_numeric( message_numeric ) ){ ok = false; } | |
if( !this._is_valid_boolean( message_boolean ) ){ ok = false; } | |
if( !this._is_valid_email( message_email ) ){ ok = false; } | |
return ok; | |
}, | |
/** | |
* Public method to call to validate a model instance | |
* | |
* How to set field-messages : | |
* myModel.is_valid_field('firstName', { | |
* message_required: "Just anything..", | |
* message_numeric: "All I want is a frickin' number", | |
* message_boolean: "Don't you bool me!", | |
* message_email: "Valid email, please..." | |
* }); | |
* | |
* @param string | |
* @param object optional | |
* @return boolean | |
*/ | |
is_valid_field : function (field, messages) { | |
var msgs = messages || {}; | |
var message_required = msgs.message_required || null; | |
var message_numeric = msgs.message_numeric || null; | |
var message_boolean = msgs.message_boolean || null; | |
var message_email = msgs.message_email || null; | |
if( this.get('errors').has( field ) ) { | |
this.get('errors').errorsFor( field ).clear(); | |
} | |
var ok = true; | |
if( this.requiredFields.indexOf(field) >= 0 && !this._is_valid_required_field( field, message_required ) ){ ok = false; } | |
if( this.numericFields.indexOf(field) >= 0 && !this._is_valid_numeric_field( field, message_numeric ) ){ ok = false; } | |
if( this.booleanFields.indexOf(field) >= 0 && !this._is_valid_boolean_field( field, message_boolean ) ){ ok = false; } | |
if( this.emailFields.indexOf(field) >= 0 && !this._is_valid_email_field( field, message_email ) ){ ok = false; } | |
return ok; | |
}, | |
/** | |
* Allows anything that isn't empty | |
* for the this.requiredFields list | |
* | |
* @param string optional | |
* @return boolean | |
*/ | |
_is_valid_required : function ( message ) { | |
var msg = message || this.MESSAGE_REQUIRED; | |
var self = this; | |
var ok = true; | |
this.get('requiredFields').forEach( function(field /*, index*/){ | |
if( !self._is_valid_required_field(field, msg) ) { | |
ok = false; | |
} | |
}); | |
return ok; | |
}, | |
/** | |
* Allows anything that isn't empty | |
* | |
* @param string | |
* @param string optional | |
* @return boolean | |
*/ | |
_is_valid_required_field : function (field, message) { | |
var msg = message || this.MESSAGE_REQUIRED; | |
var check = typeof check === 'string' ? this.get( field ).trim() : this.get( field ); | |
if( check === '' ){ | |
this.get('errors').add(field, msg); | |
return false; | |
} | |
return true; | |
}, | |
/** | |
* Allows numbers as strings and numbers | |
* for the this.numericFields list | |
* | |
* @param string optional | |
* @return boolean | |
*/ | |
_is_valid_numeric : function ( message ) { | |
var msg = message || this.MESSAGE_NUMERIC; | |
var self = this; | |
var ok = true; | |
this.get('numericFields').forEach( function(field /*, index*/){ | |
if( !self._is_valid_numeric_field(field, msg) ) { | |
ok = false; | |
} | |
}); | |
return ok; | |
}, | |
/** | |
* Allows numbers as strings and numbers | |
* | |
* @param string | |
* @param string optional | |
* @return boolean | |
*/ | |
_is_valid_numeric_field : function (field, message) { | |
var msg = message || this.MESSAGE_NUMERIC; | |
var check = typeof check === 'string' ? this.get( field ).trim() : this.get( field ); | |
if( isNaN(parseFloat(check)) || !isFinite(check) ){ | |
this.get('errors').add(field, msg); | |
return false; | |
} | |
return true; | |
}, | |
/** | |
* Allows booleans only | |
* for the this.booleanFields list | |
* | |
* @param string optional | |
* @return boolean | |
*/ | |
_is_valid_boolean : function ( message ) { | |
var msg = message || this.MESSAGE_BOOLEAN; | |
var self = this; | |
var ok = true; | |
this.get('booleanFields').forEach( function(field /*, index*/){ | |
if( !self._is_valid_boolean_field(field, msg) ) { | |
ok = false; | |
} | |
}); | |
return ok; | |
}, | |
/** | |
* Allows booleans only | |
* | |
* @param string | |
* @param string optional | |
* @return boolean | |
*/ | |
_is_valid_boolean_field : function (field, message) { | |
var msg = message || this.MESSAGE_BOOLEAN; | |
var check = this.get( field ); | |
if( typeof check !== 'boolean' || (typeof check === 'object' && typeof check.valueOf() === 'boolean') ){ | |
this.get('errors').add(field, msg); | |
return false; | |
} | |
return true; | |
}, | |
/** | |
* Allows valid e-mail adresses only | |
* for the this.emailFields list | |
* | |
* @param string optional | |
* @return boolean | |
*/ | |
_is_valid_email : function ( message ) { | |
var msg = message || this.MESSAGE_EMAIL; | |
var self = this; | |
var ok = true; | |
this.get('emailFields').forEach( function(field /*, index*/){ | |
if( !self._is_valid_email_field(field, msg) ) { | |
ok = false; | |
} | |
}); | |
return ok; | |
}, | |
/** | |
* Allows valid e-mail adresses only | |
* | |
* @param string | |
* @param string optional | |
* @return boolean | |
*/ | |
_is_valid_email_field : function (field, message) { | |
var msg = message || this.MESSAGE_EMAIL; | |
var check = this.get( field ); | |
var re = /[A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}/igm; | |
if( check !== '' && !re.test( check ) ){ | |
this.get('errors').add(field, msg); | |
return false; | |
} | |
return true; | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment