
/*--------------------------------------------------------------------------------
	
	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 = '/cms/ajax/form_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 + '-message').each(function(element)
							{
								element.remove();
							});
							
						/*--------------------------------------------------------------------------------
							If the return string contains a field then display the fields alert node
						--------------------------------------------------------------------------------*/
						
							for (n in object)
							{
							
								switch (n)
								{
									case 'field':
									
										var field_name = object['field']['name'];
										var text = object['field']['value'];
										
										
										// Create alert message window
										var objDiv = document.createElement('span');
										objDiv.setAttribute('id', field_name + '-message');
										objDiv.className = form.id + '-message';
										objDiv.innerHTML = text;
										
										// Append alert message window to page
										parents = $(field_name).ancestors();
										parents[0].appendChild(objDiv);
					
										if (_fv.form_submitted)
										{
											$(field_name).focus();
										}
										
										break;
									
									
									
									
									case 'alert':
									
										var text = object['alert'];
										
										// Create alert message window
										var objDiv = document.createElement('span');
										objDiv.setAttribute('id', form.id + '-message');
										objDiv.className = form.id + '-message';
										objDiv.innerHTML = text;
									
										// Insert into the top of the form
										$(form.id).insert(objDiv, {top:''});
										
									//	alert(object['alert']);
										break;
									
									
									
									case 'location':
										window.location = object['location'];
										break;
									
									
									
									case 'innerHTML':
										var id = object['innerHTML'][0];
										var html = object['innerHTML'][1];
										$(id).innerHTML = html;
										
										break;
										
										
									
									
									case 'eval':
										eval(object['eval']);	
										break;
								
								} // end: switch
								
							} // end: for
							
							
							$$('form#' + form.id + ' input[type="submit"]').each(function(objInput)
							{
								objInput.disabled = false;
							});
								
								
						} // end: onComplete
					}
				);
			}
			
			lock_ajax_loading = false;		
		}
	
	
	
	/*--------------------------------------------------------------------------------
	--------------------------------------------------------------------------------*/
	
	}

/*--------------------------------------------------------------------------------
--------------------------------------------------------------------------------*/
