

/*
Name: ViewStateMagic, Version 1.1 ! (17-APR-2003)
Home: http://www16.brinkster.com/rajspace/ViewStateMagic.html

Authors: Version 1.1 - Kumar Gaurav Khanna
			Version 1.0 - Rajiv. R
Email: gaurav@wintoolzone.com
		 MailMe@Rajspace.Org

Purpose: ASP.NET's cool feature of ViewState, now available to any server-side programming -ASP, JSP, etc ... 


What's new in 1.1: 
------------------

View state management for multiple forms in a page.

Rajiv R speaks: 
	1.0 released on 15-APR-2003 ... 1.1 on 17-APR-2003 ... :) 
	All credits of 1.1 to Gaurav. Visit him @ WinToolZone.Com !

Gaurav speaks: 
	Well, this piece is based on core written by Raj. I was following the thread at B.NET,
	http://groups.msn.com/bdotnet/, and found it quite interesting. With my projects not taking much of my time,
	I downloaded it and checked it out. Interesting code Raj, good work :)

	Going through the limitations, I thought I would first implement support for multiple form's view state
	management. Note that in ASP.NET (which introduces the concept of view state), everything is contained
	on a single form, and hence the concept of multiple forms doesn't come into play.

	But environments like PERL,ASP, JSP, etc do have multiple form concept. Hence, I put in an hour and came up
	with v1.01 that now supports multiple form view state management. You can download it, temporarily, from
	http://www.wintoolzone.com/downloads/viewstatemagic101.zip. But the permanent link will be at Raj's web, @
	http://www16.brinkster.com/rajspace/ViewStateMagic.html. Follow it up there for updates.



*******************************
How to use ViewStateMagic, Version 1.1?
*******************************
    1. Include viewstatemagic.js file in your source file. 
    2. OnLoad of <BODY>, call loadGlobalViewState()
    3. OnSubmit of each <FORM>, call setGlobalViewState(this) 
    4. If you intend to retain the values of form element, set enableviewstate=true in the element as a attribute & value. 
    5. Within the <FORM> have a hidden variable named "__viewstate". 
    6. After creating all of your user <FORM>, create one more <FORM> with a "__viewstate" hidden member  and 
		set the value of this element across requests from the Request object, as 
	   shown below:

	   <Form name="frmMain" method="post" action="default.asp">
		<!-- used to save global view state information -->
		<input type="hidden" name="__viewstate" value="<%=Request.Form("__viewState")%>">
	   </form>

**************
Knock, Knock !
**************

    Please let your thoughts flow to me! Be whatever, I will love to hear from you. In case, you need any variation to the magic, you are welcome to consult me. If you encounter any bugs or errors, I will be thankful to you. MailMe@Rajspace.Org 


***************************
Known facts and Limitations
*************************** 
  
    1. Tried & Tested on IE5.0.     
    2. Performs magic on TextBox, RadioButton, CheckBox, TextArea, Single-Select! Does not on multi-select listboxes. 

*******
CAUTION: 
	When the VALUE of any <form> element is == or ][ or KGK_19790209_KGK this script in this state will fail. Edit the SPLIT_CODE, START_CODE & END_CODE variable values suitably if you are expecting == or ][ in your element values.
*******

*/
var SPLIT_CODE="==";	
var START_CODE="[";
var END_CODE="]";

// KGK-17/04/2003
// This seperation code will be used as a seperator when view states from multiple forms will be
// stored together as a single entity.
var VIEW_SEP="KGK_19790209_KGK";

// KGK-17/04/2003
// Each user form calls this function during its "OnSubmit", passing a pointer to the form
// as an argument. This pointer is required so that we can store the view state of all the 
// forms in the pointed forms "__viewstate" member.
function saveGlobalViewState(objForm)
{
	// init
	var strGlobalViewState = "";

	// enumerate all the forms, except the last one
	for(formNumber=0;formNumber<document.forms.length-1;formNumber++)
	{
		var formName=document.forms[formNumber];
		if (strGlobalViewState=="")
			strGlobalViewState = setViewState(formName);	
		else
			strGlobalViewState = strGlobalViewState + VIEW_SEP + setViewState(formName);
	}

	// save the view state in the form being submitted
	objForm.__viewstate.value=strGlobalViewState;
}

// RAJ/KGK-17/04/2003
// This method was invoked directly in v1.0, but is now called by "saveGlobalViewState", passing
// it pointer to the form whose view state has to be retrieved. The function returns the processed
// view state.
function setViewState(formName)	{

		var strViewState=START_CODE+"formname"+SPLIT_CODE+formName.name+END_CODE		

		for(i=0;i<formName.elements.length;i++)	{
		var object=formName.elements[i];
			if(object.name!="__viewstate" && object.type!="submit" && 					 
					object.type!="button" && object.getAttribute("enableviewstate")!="false"
					 && object.getAttribute("enableviewstate")!=null)	{
					var KeyValue="";
							switch (object.type){   
								case "checkbox" :       
									KeyValue=START_CODE+object.name+SPLIT_CODE+object.checked+END_CODE								
									break;   
								case "radio" :    
									if(object.checked)	{							
										KeyValue=START_CODE+object.name+SPLIT_CODE+object.value+END_CODE																
									}
									break;   
								default : 
									KeyValue=START_CODE+object.name+SPLIT_CODE+object.value+END_CODE
							}
					strViewState=strViewState+KeyValue;			
			}
		}

		// return the processed view state
		return strViewState;
}

// KGK-17/04/2003
// This method is called by the page, which requires the view states of all the forms to be 
// fetched and restored, as the last piece of code. The "global" view state (which is a consolidation
// of view states from all the forms) is read from the last form of the page, from the "__viewstate"
// member, and processed.
function loadGlobalViewState()
{
	// Get the "global" view state
	var strGlobalViewState = document.forms[document.forms.length-1].__viewstate.value;
	
	// Get individual view states
	var arrGlobalViewState = strGlobalViewState.split(VIEW_SEP);

	// Dont do anything if no view states found
	if (strGlobalViewState==""|| strGlobalViewState==null)
	{
		return;
	}

	// For each form (except the last one which stores the global view state), restore the
	// view state of the form.
	for(formNumber=0;formNumber<document.forms.length-1;formNumber++)
	{
		var objForm=document.forms[formNumber];
		loadViewState(objForm, arrGlobalViewState[formNumber]);
	}
}

function loadViewState(objForm, strViewState)	{

		var formObject=objForm;
		var viewstate=strViewState;

		if(viewstate!="null" && viewstate!="")	{
			viewstate=viewstate.substring(1,viewstate.length-1);

			var arrValues=viewstate.split(END_CODE + START_CODE);
			var arrKeyValues=arrValues[0].split("==");
			var elementName=arrKeyValues[0];
			var elementValue=arrKeyValues[1];

			if(elementValue==formObject.name){
				for(i=1;i<arrValues.length;i++)	{
					var arrKeyValues=arrValues[i].split(SPLIT_CODE);
					var elementName=arrKeyValues[0];
					var elementValue=arrKeyValues[1];
					var object=(elementName!="")?eval("document."+formObject.name+"."+elementName):null;

					if(object!=null)	 {
						if(object.length>0 && object.type!="select-one")	 { //length is valid for single-select and radio. To avoid single-select for getting to this block, the 2nd check is made.
							//Block for radio buttons-START
							for(j=0;j<object.length;j++)	{
								if(object[j].value==elementValue)	{
									if(object[j].getAttribute("enableviewstate")!="false" && object[j].getAttribute("enableviewstate")!=null)	{
										object[j].checked=true;
										break;
									}
								}
							}
							//Block for radio buttons-END
						}
						else	{
							if(object.getAttribute("enableviewstate")!="false" && object.getAttribute("enableviewstate")!=null)	{
								switch (object.type){   
									case "checkbox" :
										if(elementValue=="true" || elementValue=="on")
											object.checked=true;
										else
											object.checked=false;								
										break;   
									default : 
										object.value=elementValue;
								}
							}
						}
					}
				}
			}
		}
}



