Menu

Maslosoft Binder Logo Maslosoft Binder Documentation
Knockout JS tracker and binding handlers with coffee and sugar

Edit

Validator

Bootstrap styled
Validates if value will change

Note: Validators used in this example are for demo purpose, not recommended for production environment

Validator binding handler is designed to handle validation to specialized classes, let alone providing only means to perform validation. To use validator annotation, it is required to prepare validation class first.

It is designed to require minimal effort to add new validation classes. Theese should extend from Maslosoft.Binder.BaseValidator, and only required method to implement is isValid(value), which should return true on valid value and false on bogus value. This base class also exposes method addError to provide error message, which can be displayed under form input.

Additionally any property set on validator binding will be passed to instance of validation class. This allows configuring those classes. Validator binding accepts single class configuration or array of configuration to allow multiple validation rules combined.

When class is not found, error message will be shown in console, however validator binding handler will do it's best to continue to work on remaining validator.

Example of configurable regular expression validation class, written in coffescript:

class @Maslosoft.BinderDev.RegExpValidator extends @Maslosoft.Binder.BaseValidator

	pattern: ''

	flags: ''

	allowEmpty: true

	isValid: (value) ->
		if @allowEmpty and not value
			return true
		regexp = new RegExp @pattern, @flags
		valid = regexp.test(value)
		if not valid
			@addError "Should match #{@pattern}"
		return valid

Relevant code used in examples:

<div data-bind="with: binder.model.txt1" class="form-group">
	<label class="control-label" for="txt1">Validate input if it's only a-z:</label>
	<input class="form-control" id="txt1" data-bind="textInput: text, validator: {­_class: Maslosoft.BinderDev.RegExpValidator, pattern: '^[a-z]+$', allowEmpty: false­}" style="width:50%;"/>
	<div class="error-messages"></div>
	<div class="warning-messages"></div>
</div>

<div data-bind="with: binder.model.txt1a" class="form-group">
	<label class="control-label" for="txt1a">Validate input if it's only a-z:</label>
	<input class="form-control" id="txt1a" data-bind="textInput: text, validator: [{­_class: Maslosoft.BinderDev.RequiredValidator­}, {­_class: Maslosoft.BinderDev.EmailValidator­}]" style="width:50%;"/>
	<div class="error-messages"></div>
	<div class="warning-messages"></div>
</div>

<div data-bind="with: binder.model.txt2" class="form-group">
	<label class="control-label" for="txt2">Validate (empty) textarea if it's only a-z:</label>
	<textarea class="form-control" id="txt2" data-bind="textInput: text, validator: {­_class: Maslosoft.BinderDev.RegExpValidator, pattern: '^[a-z]+$', allowEmpty: false­}" style="width:50%;"></textarea>
	<div class="error-messages"></div>
	<div class="warning-messages"></div>
</div>
<div data-bind="with: binder.model.txt3" class="form-group">
	<label class="control-label" for="txt3">Validate contenteditable if it's only a-z, A-Z, 0-9 _:</label>
	<div class="form-control" id="txt3" data-bind="htmlValue: text, validator: [{­_class: Maslosoft.BinderDev.RegExpValidator, pattern: '~^[A-Za-z0-9_]+$~', allowEmpty: false­}]" style="width:50%;"></div>
	<div class="error-messages"></div>
	<div class="warning-messages"></div>
</div>

<div data-bind="with: binder.model.txt3" class="form-group">
	<label class="control-label" for="txt4">Validate contenteditable if it's not empty and valid email:</label>
	<div class="form-control" id="txt4" data-bind="htmlValue: text, validator: [{­_class: Maslosoft.BinderDev.EmailValidator, label: 'E-mail'­}, {­_class: Maslosoft.BinderDev.RequiredValidator, label: 'E-mail'­}]" style="width:50%;"></div>
	<div class="error-messages"></div>
	<div class="warning-messages"></div>
</div>
<div data-bind="with: binder.model.txt3" class="form-group">
	<label class="control-label" for="txt4">Validate contenteditable if it's not empty and valid email (reverse validation order):</label>
	<div class="form-control" id="txt5" data-bind="htmlValue: text, validator: [{­_class: Maslosoft.BinderDev.RequiredValidator, label: 'E-mail'­}, {­_class: Maslosoft.BinderDev.EmailValidator, label: 'E-mail'­}]" style="width:50%;"></div>
	<div class="error-messages"></div>
	<div class="warning-messages"></div>
</div>
<div data-bind="with: binder.model.txt3" class="form-group">
	<label class="control-label" for="txt5">Validate contenteditable - required:</label>
	<div class="form-control" id="txt6" data-bind="htmlValue: text, validator: {­_class: Maslosoft.BinderDev.RequiredValidator, model: $data­}" style="width:50%;"></div>
	<div class="error-messages"></div>
	<div class="warning-messages"></div>
</div>
<div data-bind="with: binder.model.txt6" class="form-group">
	<label class="control-label" for="txt6">This should raise errors in console, but continue to work with any proper validator (required):</label>
	<div class="form-control" id="txt7" data-bind="htmlValue: text, validator: [{­_class: Maslosoft.BinderDev.RequiredValidator, label: 'Address'­}, {­foo:'bar'­}, {­_class:'DoesNotExists'­}, {­_class: Maslosoft.BinderDev.BogusValidator­}]" style="width:50%;"></div>
	<div class="error-messages"></div>
	<div class="warning-messages"></div>
</div>
<script>
	window.onload = (function () {­
		var data1 = {­
			text: 'Some Text value'
		­};
		var data2 = {­
			text: ''
		­};
		var data3 = {­
			text: 'admin@example.com'
		­};

		var data6 = {­
			text: 'Partially bogus validators config'
		­};

		binder.model.txt1 = new Maslosoft.Koe.TextValue(data1);
		binder.model.txt2 = new Maslosoft.Koe.TextValue(data2);
		binder.model.txt3 = new Maslosoft.Koe.TextValue(data3);
		binder.model.txt6 = new Maslosoft.Koe.TextValue(data6);

		ko.applyBindings({­model: binder.model­}, document.getElementById('ko-binder'));
	­});
</script>