All pastes #950741 Raw Edit

Stuff

public text v1 · immutable
·published 2008-03-20 20:21 UTC
rendered paste body
// TRAPEZE
// Copyright 2006 Trapeze, Inc. All Rights Reserved.
// This file is proprietary and confidential; unauthorized use or redistribution is prohibited.

/**
* @class 		FormManager / modded from SimplyFormed v1.0, by Adrian Stiegler
* @version 		1.0
* @author 		Adrian Stiegler
* @availability Flash Player 8.0
* @edition 		Flash 8.0 / AS2
*

============================================
* Creates and manages Forms and Form Data  *
============================================

*/


// Import Statements:
import com.trapeze.utils.Delegate;
import com.trapeze.utils.collections.HashMap;
import com.trapeze.bango.api.*;

class com.trapeze.managers.FormManager {
			
	// ::: PRIVATE PROPERTIES
	static private var _instance:FormManager;
		
	// main container arrays for objects and displayable movieclips for forms
	public var _formsObjectArray:Array;
	public var _formsDisplayArray:Array;
		
	private var _formsDepth:Number;


	/*=====================================
	* getInstance
	* 
	*/
	static public function getInstance():FormManager
	{
		if(_instance == undefined)
		{
			_instance = new FormManager();
		}
		return _instance;
	}
	
	
	/* Constructor ========================
	* 
	*/
	private function FormManager()
	{
		_formsObjectArray = new Array();
		_formsDisplayArray = new Array();
		_formsDepth = 0;
				
		_global.formsArray = _formsDisplayArray;
	}
	
	
	/* 
	MATCH FORM TYPE
	================================================================================================================================================================
	Provide a formInstance to parse the Bango XML and produce a form, using 'matchFormType' to create field_types
	================================================================================================================================================================
	*/
	public function createForm( formTarget:MovieClip, formName:String, formID:Number, userCallBack:Function, displayableForm:Boolean):Array
	{
				
		// check for user callback
		if ( userCallBack == undefined ) userCallBack = null;
		if ( displayableForm == undefined || displayableForm == null)
		{
			var _displayableForm = false;
			
		} else {
			
			var _displayableForm = displayableForm;
		}
		
		// create clip and form object inside
		var _form = formTarget.createEmptyMovieClip(formName, _formsDepth++);
		var _formBg = _form.attachMovie("_container", "back_mc", 0);		

		
		/* 
		SETUP FORM FUCNTIONS
		================================================================================================================================================================
		Next three functions set up the basic Form template
		================================================================================================================================================================
		*/

		setupFormObjectTemplate( _form, formID, userCallBack);		// set's up form object specific variables
		setFormDisplayables( _form );								// set's up form displayable variables
		setupFormAssets( _form );									// set's the physical movieclip assets
		
		/*
		================================================================================================================================================================
		*/
		
		
		// .. now get Form Data 
		_global.functionManager.getFormData( _form, formID, userCallBack );
		
		// add form into our 'formsArray'
		_formsDisplayArray.push(_form);
		
		// show / hide the form to additional params
		_form._visible = _displayableForm;

		// send to debugger
		_global.debugManager.traceMsg("FORM CREATED AT: " + _form);
		
		return _form;
	}
	
	
	
	/* 
	REMOVE FORM
	================================================================================================================================================================
	Provide a formInstance, and the form is removed from Display and the formDisplayArray
	================================================================================================================================================================
	*/
	public function removeForm( formInstance:MovieClip )
	{
		_global.debugManager.traceMsg("DELETING FORM: " + formInstance);
	
		for (var i = 0; i < _formsDisplayArray.length; i++)
		{
			if (_formsDisplayArray[i] == formInstance)
			{
				_formsDisplayArray.splice(i,i + 1);
			}
		}
		formInstance.removeMovieClip();
	}
	
	
	
	/* 
	REFRESH FORM INSTANCE
	================================================================================================================================================================
	Provide a formInstance, will refresh the form for re-usability purposes
	================================================================================================================================================================
	*/
	public function refreshFormInstance( formInstance:MovieClip )
	{
		/* 
		This function will refresh a currently setup form
		*/
		
		// reset all data , array , object vars
		
	}

	
	/* 
	SETUP FORM OBJECT TEMPLATE
	================================================================================================================================================================
	Creates all the required Objects, Hashmaps, Arrays, LoadVars, Listeners and variables for each basic form template
	================================================================================================================================================================
	*/
	private function setupFormObjectTemplate( formInstance:MovieClip, formID:Number, userCallBack:Function):Void
	{
		
		formInstance['formParams'] = new Object();						// displayable params for this form (used in setFormDisplayables)
		formInstance['formID'] = formID;								// contains unique FormID
		formInstance['formUserCallBack'] = userCallBack;				// contains the user specificed call back function (in case of overriding)
		
		formInstance['attributeVarTable'] = new HashMap();				// contains all form specific attributes like sizing, spacing , inital FormID
		formInstance['hiddenVarTable'] = new HashMap();					// contains all hidden data types for each form (used for cross referencing vars coming from Bango and sending back into Bango)

		formInstance['attributeVarTable'].name = 'attributeVarTable'
		formInstance['hiddenVarTable'].name = 'hiddenVarTable'
		
		formInstance['formData'] = new Array();							// will contain the formData after calling to Bango
		formInstance['formSendVars'] = new LoadVars();					// will contain all the formData variables to send out to Bango
		
		formInstance['xPosition'] = 0;									// used later in matchFormType for positioning formElements
		formInstance['yPosition'] = 0;									// ''
		formInstance['elementCount'] = 0;								// used to set relative ID's to both the Label and Field pair for any field type
		formInstance['lastFocused'] = undefined;						// used to hold as instance placeholder when swapping depths on focus
	
		// listeners
		formInstance['formListeners'] = new Object();					// used for all listeners of this form
		formInstance['formCreateSuccess'] = false;						// used to tell the managers if the initial form call was successful and created, if so, any other bangoCallComplete's will just be signal handled, not parsed into a new form on screen		
		
	}
	
	
	/* 
	SETUP FORM DISPLAYABLES
	================================================================================================================================================================
	Parses some initial XML based params for each Form, using a rich Hash Map and storing them in the formInstance's 'attributesVarTable' object
	================================================================================================================================================================
	*/
	public function setFormDisplayables( formInstance:MovieClip )
	{
		var _formParams = formInstance['formParams'];

		// set each form's defaults
		var _formID = getFormID( formInstance );
		var formParamsXML = new XML('<param name="FormID"><![CDATA[' + _formID + ']]></param>'
									+'<param name="cellPadding"><![CDATA[25]]></param>'
									+'<param name="formWidth"><![CDATA[400]]></param>'
									+'<param name="formHeight"><![CDATA[500]]></param>'
									+'<param name="cellSpacing"><![CDATA[5]]></param>'
									+'<param name="colLabelWidth"><![CDATA[200]]></param>'
									);		
		
		/*  
		
		Default values: formID, recipient, from, action, cellPadding, cellSpacing, formWidth, formHeight
	  
		Later when speaking to Bango, new key's are added into the varTable on any formInstance, 
		rewriting a FormID, or any specific additional variables with Data_Type as hidden) from Bango
		
		*/
		
		// set up keys into varTable
		for(var i in formParamsXML.childNodes)
		{
			
			var theParam:XMLNode = formParamsXML.childNodes[i];
			var key:String = theParam.attributes.name;
			var value:String = theParam.firstChild.nodeValue;			
			
			// add key / value
			formInstance['attributeVarTable'].addItem(key, value);
						
			// another example of using the internal functions to get values
			//getAttributesValue( formInstance, key ));
		}
	}
	
	
	/* 
	SETUP FORM DISPLAYABLES
	================================================================================================================================================================
	Phsyically adjusts all the form clips using the 'attributeVarTable' previously to style visual elements 
	================================================================================================================================================================
	*/
	private function setupFormAssets( formInstance:MovieClip )
	{
		
		// get our vars
		var _formWidth = Number(getAttributesValue( formInstance, "formWidth" ));
		var _formHeight = Number(getAttributesValue( formInstance, "formHeight" ));
		var _cellPadding = Number(getAttributesValue( formInstance, "cellPadding" ));
		var _cellSpacing = Number(getAttributesValue( formInstance, "cellSpacing" ));
		var _colLabelWidth = Number(getAttributesValue( formInstance, "colLabelWidth" ));
		
		// set size of background
		formInstance['back_mc']._width = _formWidth;
		formInstance['back_mc']._height = _formHeight;
		formInstance['back_mc']._alpha = 0;
				
		// create two columns inside container for labels and field types
		var col_left = formInstance.attachMovie("_container", "col_left", 1);			// visual placeholder (to line stuff up)
		var col_right = formInstance.attachMovie("_container", "col_right", 2);			// ''
		var formTextLabels = formInstance.attachMovie("_blank", "labels_mc", 3);
		var formFields = formInstance.attachMovie("_blank", "fields_mc", 4);

		// left column
		col_left.back_mc._width = _colLabelWidth - _cellSpacing;
		col_left.back_mc._height = formInstance['back_mc']._height;
		col_left._alpha = 0;
		
		// right column
		col_right.back_mc._width = _formWidth - _colLabelWidth;
		col_right.back_mc._height = formInstance['back_mc']._height;
		col_right._x = col_left._width + _cellSpacing;
		col_right._alpha = 0;
		
		// position form labels with left column
		formTextLabels._x = col_left._x;
		formTextLabels._y = col_left._y;
		
		// position form fields with right column
		formFields._x = col_right._x;
		formFields._y = col_right._y;
		
	}

	
	/* 
	MATCH FORM TYPE
	================================================================================================================================================================
	Provide a formInstance to parse the Bango XML and produce a form, using 'matchFormType' to create field_types
	================================================================================================================================================================
	*/
	public function parseFormData( formInstance:MovieClip )
	{
		
		var _cellSpacing = Number(getAttributesValue( formInstance, "cellSpacing" ));
		var formData = formInstance['formData'];		// internal data array
		var refer = this;
		

		// MATCH TYPES WITH ELEMENTS
		for (var i = 0; i < formData.length; i++) {
			matchFormType( formInstance, formData[i] );
		}

		
		// ::: SUBMIT
		var field_type = formInstance['fields_mc'].attachMovie("Button", "submit", formInstance['fields_mc'].getNextHighestDepth());
		field_type._type = "button";
		field_type.label = "Submit";
		field_type.setSize(72,22);
		
		// position
		field_type._y = formInstance['yPosition'];
		
		field_type.onPress = function() {
			refer.sendFormData( formInstance );
		}
		
		// ::: RESET
		var field_type = formInstance['fields_mc'].attachMovie("Button", "submit", formInstance['fields_mc'].getNextHighestDepth());
		field_type._type = "button";
		field_type.label = "Reset";
		field_type.setSize(72,22);		
		
		
		// ::: POSITION
		field_type._y = formInstance['yPosition'];
		field_type._x = formInstance['fields_mc']['submit'].x + formInstance['fields_mc']['submit'].width + _cellSpacing;
		formInstance['yPosition'] += field_type._height;
		
		field_type.onPress = function() {
			refer.clearFormData( formInstance );
		}
	}
	
	
	/* 
	MATCH FORM TYPE
	================================================================================================================================================================
	Pass a formInstance, and the XML element from a series, or a single and proper form types are created and displayed on screen
	================================================================================================================================================================
	*/
	private function matchFormType( formInstance:MovieClip, formElement:Object )
	{
		/*
		--------------------------------
		INDEX OF ELEMENT
		--------------------------------
		trace(formElement.Name);
		trace(formElement.Data_Type);
		trace(formElement.Value);
		trace(formElement.Options);
		trace(formElement.Label);
		trace(formElement.Required);
		trace(formElement.Row_);
		trace(formElement.Column_);
		trace(formElement.Tab_Index);
		trace(formElement.Field_Size);
		trace(formElement.Restriction);
		--------------------------------
		*/

		
		var _Name = formElement.Name;
		var _DataType = formElement.Data_Type.toString().toLowerCase();
		var _TabIndex = formElement.Tab_Index;
		var _Value = formElement.Value;
		var _FieldSize = Number( formElement.Field_Size );
		var _cellSpacing = Number(getAttributesValue( formInstance, "cellSpacing" ));
		
		
		
		// HIDDEN ATTRIBUTE
		if (_DataType == "hidden") 									
		{
			// let's add into our 'hiddenVarTable'
			formInstance['hiddenVarTable'].addItem(formElement.Name, formElement.Value);
		}
				
		
		// TEXT LABEL
		if (_DataType == "text" || _DataType == "password") 		
		{
			// label
			var field_label = formInstance["labels_mc"].attachMovie("Label", "label" + formInstance['labels_mc'].getNextHighestDepth(), formInstance['labels_mc'].getNextHighestDepth());
			field_label.myID  = formInstance['elementCount'];
			field_label.text = formElement.Label;
			field_label.setSize(formInstance["col_left"].back_mc._width);
			
			// field
			var field_type = formInstance['fields_mc'].attachMovie("TextInput", "input" + formInstance['fields_mc'].getNextHighestDepth(), formInstance['fields_mc'].getNextHighestDepth());
			field_type.myID = formInstance['elementCount'];
			field_type._type = "text";
			
			// set formElement default settings (Tab Index, Field Size, Required, Restrictions, Row and Column (not being used in Version 1.0) 
			field_type.border = true;
			field_type.setSize(_FieldSize, 22);	
			
			// position
			field_label._y = formInstance['yPosition'];
			field_type._y = formInstance['yPosition'];
			formInstance['yPosition'] += field_type.height + _cellSpacing;			
			
			if (_DataType == "password") field_type.password = true;
		}
			

		// TEXT AREA
		if (_DataType == "textarea")
		{
			// label
			var field_label = formInstance["labels_mc"].attachMovie("Label", "label" + formInstance['labels_mc'].getNextHighestDepth(), formInstance['labels_mc'].getNextHighestDepth());
			field_label.myID  = formInstance['elementCount'];
			field_label.text = formElement.Label;
			field_label.setSize(formInstance["col_left"].back_mc._width);
			
			// textarea
			var field_type = formInstance['fields_mc'].attachMovie("TextArea", "input" + formInstance['fields_mc'].getNextHighestDepth(), formInstance['fields_mc'].getNextHighestDepth());
			field_type.myID = formInstance['elementCount'];
			field_type._type = "textarea";
			
			// set properties
			field_type.editable = true;
			field_type.wordWrap = true;
			field_type.border = true;
			field_type.text = "";
			field_type.setSize(formElement.Field_Size, 50);
			
			field_label._y = formInstance['yPosition'];
			field_type._y = formInstance['yPosition'];
			formInstance['yPosition'] += field_type.height + _cellSpacing;
		}
		
		
		// CHECKBOX / RADIO
		if (_DataType == "checkbox" || _DataType == "radio")	
		{
			
			// checkbox field / label
			var field_type = formInstance['fields_mc'].attachMovie("CheckBox", "checkbox" + formInstance['fields_mc'].getNextHighestDepth(), formInstance['fields_mc'].getNextHighestDepth());
			field_type.myID = formInstance['elementCount'];
			field_type._type = "checkbox";						

			// set properties
			field_type.label = formElement.Label;
			field_type.labelPlacement = "right";
			field_type.setSize(formElement.Field_Size, 22);

			field_type._y = formInstance['yPosition'];
			formInstance['yPosition'] += field_type.height + _cellSpacing;
			
			if (_Value == 1) field_type.selected = true;
		}
		
		
		// DROP DOWN (ComboBox)
		if (_DataType == "select") 		
		{
		
			// label
			var field_label = formInstance["labels_mc"].attachMovie("Label", "label" + formInstance['labels_mc'].getNextHighestDepth(), formInstance['labels_mc'].getNextHighestDepth());
			field_label.myID  = formInstance['elementCount'];
			field_label.text = formElement.Label;
			field_label.setSize(formInstance["col_left"].back_mc._width);
			
			// field
			var field_type = formInstance['fields_mc'].attachMovie("ComboBox", "combobox" + formInstance['fields_mc'].getNextHighestDepth(), formInstance['fields_mc'].getNextHighestDepth());
			field_type.myID = formInstance['elementCount'];
			field_type._type = "select";

			// set properties
			field_type.setSize(_FieldSize, 22);
			field_type.editable = false;
			
			// get value | label from element
			var _fieldOptions = formElement.Options.split(",");
			for (var i = 0; i < _fieldOptions.length; i++)
			{
				var _fieldAttributes = _fieldOptions[i].split('|');
				var _itemValue = _fieldAttributes[0];
				var _itemLabel = _fieldAttributes[1];
				
				field_type.addItem({data:_itemValue, label:_itemLabel});
			}
			
			// position
			field_label._y = formInstance['yPosition'];
			field_type._y = formInstance['yPosition'];
			formInstance['yPosition'] += field_type.height + _cellSpacing;
		}
		
		
		// RADIO GROUP
		if (_DataType == "radio-group") {}
		

		
		/* 
		FORM COMMON VARIABLES These variables will be checked on sendFormData
		================================================================================================================================================================
		Below are the common variables each field_type owns, this is cross referenced with 'matchFormErrors' and other 1:1 relationships of Data to Clips
		================================================================================================================================================================
		*/
		field_type.varName = formElement.Name;
		field_type.varValue = formElement.Value;
		field_type.required = formElement.Required;	
		field_type.restrictions = formElement.Restriction;
		field_type.tabIndex = _TabIndex;						// set tab Index		
				
				
		/* 
		LISTENERS for each form type
		================================================================================================================================================================
		Each field_type has a listener for focusIn and onChanged
		================================================================================================================================================================
		*/
		
		field_type.addEventListener("focusIn", formInstance['formListeners']);
		formInstance['formListeners'].focusIn = function( evtObj:Object )
		{
			// swap depths
			var _field = evtObj.target;
			var _fieldContainer = _field._parent;
			
			if (_fieldContainer._parent['lastFocused'] != undefined)
			{
				_field.swapDepths(_fieldContainer._parent['lastFocused']);
			}
			
			// set to last focused object
			_fieldContainer._parent['lastFocused'] = _field;
		}
		
		// increment the element count for this form
		formInstance['elementCount']++;
	}

	/* 
	MATCH FORM ERRORS
	================================================================================================================================================================
	This function is used to match any improper field's requested by Bango to adjust
	================================================================================================================================================================
	*/
	private function matchFormErrors( formInstance:MovieClip, formErrors:Object )
	{
		
		// parse errors and highlight fields
		for (var obj in formErrors) {
				
			var _errorName = formErrors[obj].Name;				
			var _errorMessage = formErrors[obj].Message.toString();
			
			// find matching field 
			for (var field_type in formInstance['fields_mc'])
			{
				if (formInstance['fields_mc'][field_type]._type != 'button')
				{
					if (formInstance['fields_mc'][field_type].varName == _errorName) {
						
						var _clipInstance = formInstance['fields_mc'][field_type];
						
						// found our matching varName to errorName
						_global.debugManager.traceMsg("BANGO VALIDATION ISSUE AT: " + _clipInstance + " with errorMessage " + _errorMessage);
					}
				}
			}
		}
	}
	
	
	/* 
	CLEAR FORM DATA
	================================================================================================================================================================
	Provide a formInstance and all the field types will be cleared /reset
	================================================================================================================================================================
	*/
	private function clearFormData( formInstance:MovieClip )
	{
		
		for (var clip in formInstance["fields_mc"]) {
						
			// catalogue all fields, except any buttons
			if (formInstance["fields_mc"][clip]._type != "button")
			{

				if (formInstance["fields_mc"][clip]._type != "select") {
					
					// clear text
					formInstance["fields_mc"][clip].text = "";
					
					// clear varValue
					formInstance["fields_mc"][clip].varValue = undefined;
					
				} else {
					
					// set to start index
					formInstance["fields_mc"][clip].selectedIndex = 0;
				}
			}
		}
	}
	
	
	/* 
	SEND FORM DATA
	================================================================================================================================================================
	Provide a formInstance, will parse the varName / varValue's iand send the form data to Bango
	================================================================================================================================================================
	*/
	private function sendFormData( formInstance:MovieClip )
	{
		/*
		
		Setup with varName and varValue for each field_type
		
		formInstance["fields_mc"][clip].varName
		formInstance["fields_mc"][clip].varValue
		
		*/

		// clean the loadVars
		formInstance['formSendVars'] = new LoadVars();
		
		// run through all clips and create seamless string to send to form URL
		for (var clip in formInstance["fields_mc"]) {
						
			// catalogue all fields, except any buttons
			if (formInstance["fields_mc"][clip]._type != "button") {
				
				// IF TEXT / TEXT AREA
				if (formInstance["fields_mc"][clip]._type == "text" || formInstance["fields_mc"][clip]._type == "textarea") {
					formInstance["fields_mc"][clip].varValue = formInstance["fields_mc"][clip].text;
				}
				
				// IF DROP DOWN
				if (formInstance["fields_mc"][clip]._type == "select") {
					formInstance["fields_mc"][clip].varValue = formInstance["fields_mc"][clip].getItemAt(formInstance["fields_mc"][clip].selectedIndex).data;
				}
				
				// IF CHECKBOX
				if (formInstance["fields_mc"][clip]._type == "checkbox") {
					formInstance["fields_mc"][clip].varValue = formInstance["fields_mc"][clip].selected;
				}
				
				// IF RADIO-GROUP
				if (formInstance["fields_mc"][clip]._type == "radio-group") {
	
					// ToDo: This is not yet tested, since we don't have any radio-groups in Bango yet.
					
					// if radio button is set to true, set value to label
					formInstance["fields_mc"][clip].varValue = null;
					
					if (formInstance["fields_mc"][clip].groupName != null && formInstance["fields_mc"][clip].selected == true) {
						formInstance["fields_mc"][clip].varValue = formInstance["col_right"][clip].label;
					}
				}
							
				// APPLY variables into formInstance's 'formSendVars' LoadVars object to send out
				if (formInstance["fields_mc"][clip].varValue != null && formInstance["fields_mc"][clip].varValue != "") {

					var _sendVarName = formInstance["fields_mc"][clip].varName.toString();
					var _sendVarValue = formInstance["fields_mc"][clip].varValue;

					// apply varName into formSendVars, and set to varValue
					formInstance['formSendVars'][_sendVarName] = _sendVarValue;
				}
			}
		}
		
		// add hidden attributes into formSendVars
		var _hiddenVariableTableLength = formInstance['hiddenVarTable'].getLength();

		var _keyArray = formInstance['hiddenVarTable'].getKeys();
		var _valueArray = formInstance['hiddenVarTable'].getValues();

		// add hidden variables into our 'formSendVars' LoadVars object
		for (var i = 0; i < _hiddenVariableTableLength; i++) {
			
			if (_keyArray[i] == "Form_Submit_To") {
				
				// let's rewrite our 'Form_Submit_To' key to 'func' (This is sort of a small security gate in itself)
				formInstance['formSendVars']['func'] = _valueArray[i];
			} else {
				formInstance['formSendVars'][_keyArray[i]] = _valueArray[i];
			}
		}

		// send to debugger
		_global.debugManager.traceMsg("CONSTRUCTED VAR OBJECT 'formSendVars' for: " + formInstance);
		
		// let's send out now
		_global.functionManager.sendFormData( formInstance );
	}
	
	/* 
	GET ATTRIBUTES VALUE
	================================================================================================================================================================
	Provide a formInstance and a searchable key to return a Form Attribute of choice ( displayable params only, etc. Spacing, Padding )
	================================================================================================================================================================
	*/
	private function getAttributesValue( formInstance:MovieClip, key:String):String{
		
		var value:String = String(formInstance['attributeVarTable'].getValue(key));
		return value;
	}
	
	/* 
	GET HIDDEN VALUE
	================================================================================================================================================================
	Provide a formInstance and a searchable key to return a Form Hidden Value of choice ( Form_Submit_To (func), Headers, Recipients etc )
	================================================================================================================================================================
	*/
	private function getHiddenValue( formInstance:MovieClip, key:String):String{
		
		var value:String = String(formInstance['hiddenVarTable'].getValue(key));
		return value;
	}
	
	/* 
	GET FORM ID
	================================================================================================================================================================
	Returns the proper ID number of the passed formInstance param
	================================================================================================================================================================
	*/
	public function getFormID( formInstance:MovieClip ):Number
	{
		return formInstance['formID'];
	}
}