1/**
2* Gumby jQuery Validation Plugin
3*/
4!function($) {
5
6	'use strict';
7
8	function Validation($this, req) {
9
10		if(Gumby) {
11			Gumby.debug('Initializing Validation', $this);
12		}
13
14		// input and holder .field
15		this.$this = $this;
16		this.$field = this.$this.parents('.field');
17
18		// supplied validation function with default length check
19		this.req = req || function() {
20			return !!this.$this.val().length;
21		};
22
23		// reference to this class
24		var scope = this;
25
26		// checkboxes and radio buttons use gumby.onChange event to validate
27		if(this.$this.is('[type=checkbox], [type=radio]')) {
28			this.$field = this.$this.parent('label');
29			this.$field.on('gumby.onChange', function() {
30				scope.validate();
31			});
32
33		// selects validate on change
34		} else if(this.$this.is('select')) {
35			this.$field = this.$this.parents('.picker');
36			this.$field.on('change', function() {
37				scope.validate();
38			});
39
40		// others (text input, textarea) use blur
41		} else {
42			this.$this.on('blur', function(e) {
43				// ignore tab
44				if(e.which !== 9) {
45					scope.validate();
46				}
47			});
48		}
49	}
50
51	// validate field
52	Validation.prototype.validate = function() {
53
54		var result = this.req(this.$this);
55
56		// failed
57		if(!result) {
58			this.$field.removeClass('success').addClass('danger');
59
60		// passed
61		} else {
62		//} else if(this.$field.hasClass('danger')) {
63			this.$field.removeClass('danger').addClass('success');
64		}
65
66		return result;
67	};
68
69	// jQuery plugin definition
70	$.fn.validation = function(options) {
71
72		var // extend params with defaults
73			settings = $.extend({
74				submit : false,
75				fail: false,
76				required : []
77			}, options),
78			// store validation objects
79			validations = [];
80
81		// init each form plugin is called on
82		return this.each(function() {
83
84			// no required fields so plugin is pointless
85			if(!settings.required.length) {
86				return false;
87			}
88
89			var $this = $(this),
90				reqLength = settings.required.length,
91				i;
92
93			// loop round each required field and instantiate new validation object
94			for(i = 0; i < reqLength; i++) {
95				validations.push(new Validation(
96					$this.find('[name="'+settings.required[i].name+'"]'),
97					settings.required[i].validate || false
98				));
99			}
100
101			// hijack submit event
102			$this.on('submit', function(e) {
103
104				// reference to whole form pass/fail
105				var failed = false;
106
107				// if no passed attribute found we should halt form submit
108				if(!$this.data('passed')) {
109					e.preventDefault();
110
111					// loop round validation objects and validate each
112					var reqLength = validations.length, i;
113					for(i = 0; i < reqLength; i++) {
114						if(!validations[i].validate()) {
115							failed = true;
116						}
117					}
118
119					// passed
120					if(!failed) {
121						// if submit method present call that otherwise submit form
122						if(settings.submit && typeof settings.submit === 'function') {
123							settings.submit($this.serializeArray());
124							return;
125						}
126
127						// store passed bool and re-submit
128						$this.data('passed', true).submit();
129
130						// failed
131						} else {
132						// call fail method if present
133						if(settings.fail && typeof settings.fail === 'function') {
134							settings.fail();
135							return;
136						}
137					}
138				}
139			});
140		});
141	};
142}(jQuery);
143