
/*--------------------------------------------------------------------------------
	
	Individual field events:
	------------------------------------
	
	This script checks all forms on the page. For each form that has a module name
	specified in the form's action (i.e. ?module=registrants) it checks if the 
	form has any validation files, these are located in
	/assets/modules/[module]/validation/[form.id]/
	
	Each file is named after the event that will call it.
	For example:
	/assets/modules/[module]/validation/[form.id]/onblur.php
	
	Each file contains a validation array. The keys of this array match the names
	of the fields to be validated by the event.
	
	The validation function is assigned to each field that is assigned an event: 
	$([fieldName]).[onblur] = function() { _fv.validate(this, '[event]') }
	
	The validation function calls an Ajax request which sends the field name and
	event to the forms validation class. See: /assets/validation.php. FormValidation is
	carried out and a response returned.
	
	Submitting the form
	------------------------------------
	todo
	
--------------------------------------------------------------------------------*/

	Event.observe(window, 'load', function(){
		
		_fv = new FormValidation;	
		
		$$('form._fv').each(function(form)
		{
			_fv.initialize_form(form);
		});
		
		$$('form._ffe').each(function(form)
		{
			form.focusFirstElement();
		});
		
	})

/*--------------------------------------------------------------------------------

	

--------------------------------------------------------------------------------*/

	var FormValidation = Class.create();
	
	FormValidation.prototype = {
	
	
	
	
	/*--------------------------------------------------------------------------------
	--------------------------------------------------------------------------------*/
	
		initialize: function()
		{
			// Temporarily locks out validation. Prevents multiple validation being executed when user events conflict. I.e. onblur vs. onsubmit
			this.Lock = false;
			
			// Specifies the path to the PHP forms script.
			this.Path = '/assets/3rdparty/validation/validation.php';
		},
	
	/*--------------------------------------------------------------------------------
	--------------------------------------------------------------------------------*/
	
		initialize_all: function()
		{
			$$('form').each(function(form)
			{
				_fv.initialize_form(form);
			});
		},
	
	
	/*--------------------------------------------------------------------------------
	--------------------------------------------------------------------------------*/
	
		initialize_form: function(form)
		{			
			lock_ajax_loading = true;		

			// If the form has validation then the name of the module it belongs to should be specified in the forms action
			// This is used to determine the directory to load the forms validation scripts.
			var object = form.getAttribute('action').toQueryParams();
			form.module = object['module'];
			
			
		//	if (form.module)
			{
				form.onsubmit_validation = new Array;
				
				// Disable the onsumbit event and load the forms 
				form.onsubmit = function()
				{
					$$('form#' + form.id + ' input[type="submit"]').each(function(objInput)
					{
						objInput.disabled = true;
					});
					
					_fv.validate(form, false);
					
					return false;
				}


				// For each form pass the module name and form id to the PHP forms script. The script returns an array of all fields and their
				// events. Each field is then assigned its events each triggering the validate() function.
				var myAjax = new Ajax.Request( 
					this.Path, 
					{
						method: 'post', 
						parameters: 'action=initialize&form_id=' + form.id + '&module=' + form.module,
						onComplete: function(response)
						{
						//	alert(response.responseText);
							var object = response.responseText.evalJSON();	
						//	for (n in object) { alert(n + ': ' + object[n]); }

							for(user_event in object)
							{
								object[user_event].each(function(field_name)
								{
									if ($(field_name))
									{
										// Create an array of all of the validation, this will be looped 
										form.onsubmit_validation[form.onsubmit_validation.length] = new Array(field_name, user_event);
										
										eval("$('" + field_name + "')." + user_event + " = function(){_fv.validate(this, '" + user_event + "')}");
									//	alert("$('" + field_name + "')." + user_event + " = function(){_fv.validate(this, '" + user_event + "')}");
										// i.e. $('username').onblur = function(){}
									}
								});
							}
						}
					}
				);
				
			
			
			/*--------------------------------------------------------------------------------
				There's a conflict between the onsubmit event and other events whereby 
				clicking onsubmit evokes another event causing multiple message alerts to 
				appear in quick succession and so flicker. Not very aesthetic!
				To prevent this from happening each form has a lock attribute. If set to true 
				then all events other then onsubmit will be disabled. This lock is enabled/
				disabled by mousing over/out the submit.
			--------------------------------------------------------------------------------*/
			
				$$('form#' + form.id + ' input[type="submit"]').each(function(objInput)
				{
					objInput.onmouseover = function () { _fv.Lock = true; } // This stops clicking the button from triggering a fields event
					objInput.onclick = function () { _fv.Lock = false; }
					objInput.onmouseout = function () { _fv.Lock = false; }
				})
				
				
			}
			
			lock_ajax_loading = false;		
		},
	
	
	
	
	/*--------------------------------------------------------------------------------
		Prevents the validation from being executed temporarily
	--------------------------------------------------------------------------------*/
	
		lock: function()
		{
			this.Lock = true;
			setTimeout( function() { _fv.Lock = false; }, 500 );
		},
	
	
	
	
	/*-------------------------------------------------------------------------------- 
	--------------------------------------------------------------------------------*/
	
		validate: function(element, user_event)
		{
			
			// Will focus on the 1st failing form field
			this.form_submitted = true;
			
			lock_ajax_loading = true;		
			
			if (
				!this.Lock
			)
			{
				this.lock();
				
				
				// If the user event exists then the objForm is currently an element within the form
				if (user_event)
				{
					form = element.form;
					this.form_submitted = false;
				}
				else
				{
					form = element;
				}
				
				var myAjax = new Ajax.Request( 
					this.Path, 
					{
						method: 'post', 
						parameters: 'action=validate'
									+ '&module=' + form.module
									+ '&form_id=' + form.id
									+ '&user_event=' + user_event // Onsubmit sets this to false which switches this to validate all
									+ '&field_name=' + element.name 
									+ '&' + form.serialize(),
						onComplete: function(response)
						{
							if (response.responseText)
							{
							//	alert(response.responseText);
								var object = response.responseText.evalJSON();
							}
						//	for (n in object) { alert(n + ': ' + object[n]); }
							
							// Remove all existing messages for the current form
							$$('#' + form.id + ' .validation-message').each(function(element)
							{
								element.remove();
							});
							
							$$('#' + form.id + ' .validation-failed').each(function(element)
							{
								element.removeClassName('validation-failed');
							});
							
							$$('#' + form.id + ' .validation-passed').each(function(element)
							{
								element.removeClassName('validation-passed');
							});
							
							
							
						/*--------------------------------------------------------------------------------
							If the return string contains a field then display the fields alert node
						--------------------------------------------------------------------------------*/
						
							for (n in object)
							{
							
								var value = object[n];
								
								switch (n)
								{
									
									// If an individual field has errors
									case 'failed':
									case 'passed':
										
										var field_name = value[0];
										var text = value[1];
										
										
										// Remove any previous messages assigned to this field
										$$('#' + form.id + ' .validation-message').each(function(element){
											element.remove();
										});
										
										
										// Get the fields container div and assign it with a class of the validation result
										var parent = $(field_name).up();
										parent.addClassName('validation-' + n);
										
										
										// Create new message element
										if (text.length > 0)
										{
											var objDiv = document.createElement('span');
											objDiv.addClassName('validation-message');
											objDiv.innerHTML = text;
											
											// Place message at bottom of fields container div.
											// Delay it for a few seconds in case the same message is repeated. This will place a gap
											// so the user is aware that the message is being re displayed.
											setTimeout(function(){parent.appendChild(objDiv);}, 250);
										}
										
										
										// If the form has been submitted then select the failed field
										if (_fv.form_submitted)
										{
											$(field_name).focus();
										}
										
										break;
									
									
									
									case 'alert':
									/*	
										// Create alert message window
										var objDiv = document.createElement('span');
										objDiv.setAttribute('id', form.id + '-message');
										objDiv.className = form.id + '-message';
										objDiv.innerHTML = value;
									
										// Insert into the top of the form
										$(form.id).insert({top:objDiv});
									*/
									
										alert(value);
										
										break;
									
									
									
									case 'location':
										window.location = value;
										break;
									
									
									
									case 'innerHTML':
										var id = value[0];
										var html = value[1];
										if ($(id))
										{
											$(id).innerHTML = html;
										}
										
										break;
										
										
									
									
									case 'eval':
										eval(value);	
										break;
										
										
										
								
								} // end: switch
								
							} // end: for
							
							
							$$('form#' + form.id + ' input[type="submit"]').each(function(objInput)
							{
								objInput.disabled = false;
							});
								
								
						} // end: onComplete
					}
				);
			}
			
			lock_ajax_loading = false;		
		}
	
	
	
	/*--------------------------------------------------------------------------------
	--------------------------------------------------------------------------------*/
	
	}

/*--------------------------------------------------------------------------------
--------------------------------------------------------------------------------*/

