src/conbo/binding/AttributeBindings.js
function(el, validator)
	{
		var validateFunction;
		
		switch (true)
		{
			case conbo.isFunction(validator):
			{
				validateFunction = validator;
				break;
			}
			
			case conbo.isString(validator):
			{
				validator = new RegExp(validator);
			}
			
			case conbo.isRegExp(validator):
			{
				validateFunction = function(value)
				{
					return validator.test(value);
				};
				
				break;
			}
		}
		
		if (!conbo.isFunction(validateFunction))
		{
			conbo.warn(validator+' cannot be used with cb-validate');
			return;
		}
		
		var ep = __ep(el);
		var form = ep.closest('form');
		
		var getClasses = function(regEx) 
		{
			return function (classes) 
			{
				return classes.split(/\s+/).filter(function(el)
				{
					return regEx.test(el); 
				})
				.join(' ');
			};
		};
		
		var validate = function()
		{
			// Form item
			
			var value = el.value || el.innerHTML
				, result = validateFunction(value) 
				, valid = (result === true)
				, classes = []
				;
			
			classes.push(valid ? 'cb-valid' : 'cb-invalid');
			
			if (conbo.isString(result))
			{
				classes.push('cb-invalid-'+result);
			}
			
			ep.removeClass('cb-valid cb-invalid')
				.removeClass(getClasses(/^cb-invalid-/))
				.addClass(classes.join(' '))
				;
			
			// Form
			
			if (form)
			{
				var fp = __ep(form);
				
				fp.removeClass('cb-valid cb-invalid')
					.removeClass(getClasses(/^cb-invalid-/))
					;
				
				if (valid) 
				{
					valid = !form.querySelector('.cb-invalid');
					
					if (valid)
					{
						conbo.toArray(form.querySelectorAll('[required]')).forEach(function(rEl) 
						{
							if (!String(rEl.value || rEl.innerHTML).trim())
							{
								valid = false;
								return false; 
							}
						});
					}
				}
				
				fp.addClass(valid ? 'cb-valid' : 'cb-invalid');
			}
			
		};
		
		ep.addEventListener('change input blur', validate);
	}
function(el, validator)
	{
		var validateFunction;
		
		switch (true)
		{
			case conbo.isFunction(validator):
			{
				validateFunction = validator;
				break;
			}
			
			case conbo.isString(validator):
			{
				validator = new RegExp(validator);
			}
			
			case conbo.isRegExp(validator):
			{
				validateFunction = function(value)
				{
					return validator.test(value);
				};
				
				break;
			}
		}
		
		if (!conbo.isFunction(validateFunction))
		{
			conbo.warn(validator+' cannot be used with cb-validate');
			return;
		}
		
		var ep = __ep(el);
		var form = ep.closest('form');
		
		var getClasses = function(regEx) 
		{
			return function (classes) 
			{
				return classes.split(/\s+/).filter(function(el)
				{
					return regEx.test(el); 
				})
				.join(' ');
			};
		};
		
		var validate = function()
		{
			// Form item
			
			var value = el.value || el.innerHTML
				, result = validateFunction(value) 
				, valid = (result === true)
				, classes = []
				;
			
			classes.push(valid ? 'cb-valid' : 'cb-invalid');
			
			if (conbo.isString(result))
			{
				classes.push('cb-invalid-'+result);
			}
			
			ep.removeClass('cb-valid cb-invalid')
				.removeClass(getClasses(/^cb-invalid-/))
				.addClass(classes.join(' '))
				;
			
			// Form
			
			if (form)
			{
				var fp = __ep(form);
				
				fp.removeClass('cb-valid cb-invalid')
					.removeClass(getClasses(/^cb-invalid-/))
					;
				
				if (valid) 
				{
					valid = !form.querySelector('.cb-invalid');
					
					if (valid)
					{
						conbo.toArray(form.querySelectorAll('[required]')).forEach(function(rEl) 
						{
							if (!String(rEl.value || rEl.innerHTML).trim())
							{
								valid = false;
								return false; 
							}
						});
					}
				}
				
				fp.addClass(valid ? 'cb-valid' : 'cb-invalid');
			}
			
		};
		
		ep.addEventListener('change input blur', validate);
	}
function ( el , validator ) { var validateFunction ; switch ( true ) { case conbo . isFunction ( validator ) : { validateFunction = validator ; break ; } case conbo . isString ( validator ) : { validator = new RegExp ( validator ) ; } case conbo . isRegExp ( validator ) : { validateFunction = function ( value ) { return validator . test ( value ) ; } ; break ; } } if ( ! conbo . isFunction ( validateFunction ) ) { conbo . warn ( validator + ' cannot be used with cb-validate' ) ; return ; } var ep = __ep ( el ) ; var form = ep . closest ( 'form' ) ; var getClasses = function ( regEx ) { return function ( classes ) { return classes . split ( / \s+ / ) . filter ( function ( el ) { return regEx . test ( el ) ; } ) . join ( ' ' ) ; } ; } ; var validate = function ( ) { // Form item
 var value = el . value || el . innerHTML , result = validateFunction ( value ) , valid = ( result === true ) , classes = [ ] ; classes . push ( valid ? 'cb-valid' : 'cb-invalid' ) ; if ( conbo . isString ( result ) ) { classes . push ( 'cb-invalid-' + result ) ; } ep . removeClass ( 'cb-valid cb-invalid' ) . removeClass ( getClasses ( / ^cb-invalid- / ) ) . addClass ( classes . join ( ' ' ) ) ; // Form
 if ( form ) { var fp = __ep ( form ) ; fp . removeClass ( 'cb-valid cb-invalid' ) . removeClass ( getClasses ( / ^cb-invalid- / ) ) ; if ( valid ) { valid = ! form . querySelector ( '.cb-invalid' ) ; if ( valid ) { conbo . toArray ( form . querySelectorAll ( '[required]' ) ) . forEach ( function ( rEl ) { if ( ! String ( rEl . value || rEl . innerHTML ) . trim ( ) ) { valid = false ; return false ; } } ) ; } } fp . addClass ( valid ? 'cb-valid' : 'cb-invalid' ) ; } } ; ep . addEventListener ( 'change input blur' , validate ) ; }
Use a method or regex to validate a form element and apply a
cb-valid or cb-invalid CSS class based on the outcome

@param 		{HTMLElement}	el - DOM element to which the attribute applies
@param 		{Function} 		validator - The function referenced by the attribute
@returns		{void}

@example
<div cb-validate="functionName"></div>
Use a method or regex to validate a form element and apply a cb - valid or cb - invalid CSS class based on the outcome