
// Show and Hide Form Branching with validation.
/*
1. works with last version of jQ 1.3.2
2. V1.1 Philip Tutty May2009
*/

/* 
Definition:

this plugin is designed to allow the markup of a form so that it displays different fieldsets in the form based on the users choice of radio inputs. It is design as to allow any number of these 'branchs' to occur. Its is also designed to hide the 'child branchs' of a parent branch that becomes hidden.

The plugin also toggles the state of validation applied to any inputs when the fieldset containing it is hidden. 


How it works:

1. Each radio button set you use to control the show/hide of a branch should have an id="branch1_option1" and id="branch1_option2".
Only the  branch number should change as you had more sets of radio buttons.

2. The corresponding fieldsets to show/hide based on the radio selction should use:
class="branch1_option1", class="branch1_option2" or class="branch1_both" if you want the fieldset(s) to be displayed for both options.

as its a class you can have more than one fieldset with the same class.

3. the next branch you add should use the same syntax but just increase the branch number by 1 : 
id="branch1_option1" for the radio button
class="branch2_option1" for the fieldset

4. All fieldsets with a class name starting with 'branch' are hidden initially and validation switched off

5. Apply validation to the form inputs using class="required" (see marc grabanski's validation plugin docs) this script will turn this state on or off depending on whether the fieldset is hidden or not.

6. Does not submit inputs in hidden fieldsets to wikmail

*/

// wrapper for the plugin
(function ($) {
$.fn.formbranching = function () {
return this.each(function () {

// runs the function on page load - all div id ending with '_hidebranch' are hidden to start with.
HideBranchsInitial();

// attaches action to radio buttons
BranchSetup();
// removes input not visible before submit so they don't show in wikmail
RemoveBeforeSubmit()

// adds the event handler to all inputs that start with ID called 'branch'
function BranchSetup() {	
$("input[ID^='branch']").click(function(){
var thisval = $(this).val();

		// little workaround cos IE does not support onChange well
		if (thisval != CurrentVal){
			 // onClick its gets the full ID of the calling radio buttons. 
			var ThisID = $(this).attr("ID");
			//calls the tooglebranch function and passes it it this ID
			var CurrentVal = thisval;
			ToggleBranch(ThisID);
		}	   							 
	   	
	   
	});
}




// Evaluate if any children of a branch already exist(are visible) on the page and hides them if neccessary
function HideChildren(ParentID){
	var ParentBranchNum = ParentID.substring(6,7);
	
	// get a collection of all the fieldsets starting with class 'branch'
	$("fieldset[class^='branch']").each(function() {
	  // get the class
	  var ThisClassName = $(this).attr("class");
	  // extract the number after 'branch'  
	  var ThisBranchNum = ThisClassName.substring(6,7);
	  
	  
		  // test to see if it is visible and higher than the current branchnum	
		  if ( $(this).is(":visible") && (ThisBranchNum > ParentBranchNum)) {
					
				// perform the following on fieldset which fit the requirements in the if statement
				$(this).find(":input").each(function() {
													   
				// if they have a class of 'notrequired' 
					if ($(this).hasClass("required")) {
						// of each input remove class 'notrequired' and replace it with required
						$(this).toggleClass("notrequired").toggleClass("required");
						}
				});
				
				
			   $(this).fadeOut("slow");
		  }
				
				
				
	   });
		
}




// toggles the fieldset visiblity and validation based on branch number and option number
function ToggleBranch(RadioID) {
   //calls the HideChildren function that will hidden any children of that branch if they are opened.
   HideChildren(RadioID);
   // isolated only the first 7 character so we get branch1 or branch2 et al.
   var WhichBranch = RadioID.substring(0,7);
   // isolated the last 7 characters to we get either option1 or option2.
   var WhichOption = RadioID.substring(8,15);
   // Contruct the strings for branch number and _option1 , _option2 , _both 
   var Option1Class = WhichBranch + '_option1';
   var Option2Class = WhichBranch + '_option2';
   var OptionBothClass = WhichBranch + '_both';
   // construct jquery selectors for all of the above which collect the fieldsets with that class.
   var $OptionBothClass = $("fieldset." + OptionBothClass);
   var $Option1Class = $("fieldset." + Option1Class);
   var $Option2Class = $("fieldset." + Option2Class);
  
 

   // If a class ending with _option1 is passed in
   	 if (WhichOption == 'option1') {
		 // find all the inputs(including textarea and selectboxes) within option_1 class fieldsets
	     $Option1Class.find(":input").each(function() {
												   
		 // if they have a class of 'notrequired' 
			if ($(this).hasClass("notrequired")) {
				// of each input remove class 'notrequired' and replace it with required
				$(this).toggleClass("notrequired").toggleClass("required");
				}
		    });
		 
		 // find all the inputs in the fieldset to hide
		 $Option2Class.find(":input").each(function() {
		 // if any have the last required
			if ($(this).hasClass("required")) {
				// removes required and replace with notrequired
				$(this).toggleClass("notrequired").toggleClass("required");
				}
		    });
		  // show the option 1 fieldsets 
		  
		  // hide option 2 fieldsets 
		  $Option2Class.fadeOut("fast")
		  $Option1Class.fadeIn("slow");
											
		  
		  
	// OPTION 2 	    
	} else if (WhichOption == 'option2') {
		   
		  // get all the inputs in the fieldssets with class option2 
		  $Option2Class.find(":input").each(function() {
		 // checks to see if a required or notrequired class has been added
			if ($(this).hasClass("notrequired")) {
				// removes notrequired and adds required
				$(this).toggleClass("notrequired").toggleClass("required");
				}
		    });
		  
		 $Option1Class.find(":input").each(function() {
		 // checks to see if a required or notrequired class has been added
			if ($(this).hasClass("required")) {
				// removes notrequired and adds required
				$(this).toggleClass("notrequired").toggleClass("required");
				}
		    });
		 
		  $Option1Class.fadeOut("fast");
		  $Option2Class.fadeIn("slow");
										
	
	}
	
	
	// BOTH
	// Displays fieldset with class 'Branch[n]_both' and adds required back in.
	$OptionBothClass.find(":input").each(function() {
		 // checks to see if a required or notrequired class has been added
			if ($(this).hasClass("notrequired")) {
				// removes notrequired and adds required
				$(this).toggleClass("notrequired").toggleClass("required");
				}
		    });
    $OptionBothClass.fadeIn("slow");
	
}

// search all fieldsets with a class starting with 'branch' 
function HideBranchsInitial() {

	var $AllBranchs = $("fieldset[class^='branch']");
	
	// toogle the required class
	$AllBranchs.find(":input").each(function() {
	 // changes all required class into notrequired
		 if ($(this).hasClass("required")) { 
			// toggles the classes
			$(this).toggleClass("required").toggleClass("notrequired");
		 }
			
	});	
	// hides all those divs
  $AllBranchs.hide();
}

// on submit give all inputs that are not visible name="" so that are they are not sent to the form recipient by wikmail
function RemoveBeforeSubmit() {	
	$(this).submit(function(){
	//alert ("the form is being submitted");
	// for each fieldset with class starting with branch
	$("fieldset[class^='branch']").each(function() {
					// if the branch is not visible.							 
					if ($(this).is(":visible") == false)
					{
					  	// for each input in the invisible fieldset
						$(this).find(":input").each(function(){ 
						    // remove the name attribute
							$(this).removeAttr("name");
					    });
					}
	 });
	

	return true;
	});
}



    // closing wrapper of plugin
	});
  };
})(jQuery);
