Last active
January 2, 2016 16:41
-
-
Save planetcrypton/3c5ec44158ef957cbaf2 to your computer and use it in GitHub Desktop.
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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