/* Copyright (c) 2009 Yahoo! Inc. All rights reserved. The copyrights embodied in the content of this file are licensed under the BSD (revised) open source license */ package com.yahoo.astra.fl.containers { import fl.core.UIComponent; import com.yahoo.astra.containers.formClasses.FormEventObserver; import com.yahoo.astra.containers.formClasses.FormItem; import com.yahoo.astra.containers.formClasses.FormItemContainer; import com.yahoo.astra.containers.formClasses.FormLayoutStyle; import com.yahoo.astra.containers.formClasses.IForm; import com.yahoo.astra.containers.formClasses.IFormEventObserver; import com.yahoo.astra.events.FormLayoutEvent; import com.yahoo.astra.fl.containers.BoxPane; import com.yahoo.astra.fl.containers.layoutClasses.BaseLayoutPane; import com.yahoo.astra.layout.LayoutContainer; import com.yahoo.astra.layout.LayoutManager; import com.yahoo.astra.layout.modes.BoxLayout; import com.yahoo.astra.managers.IFormDataManager; import com.yahoo.astra.utils.NumberUtil; import flash.display.DisplayObject; import flash.events.Event; import flash.text.TextField; import flash.text.TextFormat; //-------------------------------------- // Style //-------------------------------------- /** * * The skin of required field indicator's skin. * * @default indicatorSkin * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="indicatorSkin", type="Class")] /** * * The TextFormat object to use to render the instructionText fields in the Form. * @default TextFormat("_sans", 10, 0x000000, false, false, false, '', '', TextFormatAlign.LEFT, 0, 0, 0, 0). * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="instructionTextFormat", type="flash.text.TextFormat")] /** * * The TextFormat object to use to render the formHeading field in the Form in the Form. * @default TextFormat("_sans", 11, 0x000000, bold, false, false, '', '', TextFormatAlign.LEFT, 0, 0, 0, 0). * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="headTextFormat", type="flash.text.TextFormat")] /** * Color Object of error box Sprite(showErrorMessageBox = true) in the Form. * @default Color 0x666666; * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="errorBoxColor", type="Object")] /** * * Alpha value of error box Sprite(showErrorMessageBox = true) in the Form. * @default .2 * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="errorBoxAlpha", type="Number")] /** * * The Form is a layout element containing multiple component items arranged vertically along with the definition for each items. * Similar to the Flex Form container, * it is mainly used with nested FormItems which are containers defined by a label and one or more children arranged horizontally or vertically. * * @example The following code shows a simple use of Form: * * * import com.yahoo.astra.containers.formClasses.FormLayoutStyle; * import com.yahoo.astra.fl.containers.Form; * import fl.controls.TextInput; * import fl.controls.TextArea; * import fl.controls.Button; * * // Init input fields. * // Make sure that you have Form component and UIcomponents(TextInput,TextArea,Button) in your library. * var nameInput:TextInput = new TextInput(); * var emailInput:TextInput = new TextInput(); * var commentInput:TextArea = new TextArea(); * nameInput.width = emailInput.width = commentInput.width = 200; * var submitButton:Button = new Button(); * submitButton.label = "SUBMIT"; * * var myForm:Form = new Form("Contact Us"); * // additional parameters for Form * myForm.autoSize = true; * myForm.indicatorLocation = FormLayoutStyle.INDICATOR_LEFT; * myForm.verticalGap = 10; * * var myFormDataArr : Array = [ * {label:"Name", items:nameInput}, * {label:"Email", items:emailInput}, * {label:"Message", items:commentInput,required:true}, * {label:"", items:submitButton}]; * * // define dataSource with data array. * myForm.dataSource = myFormDataArr; * * this.addChild(myForm); * * * @see http://developer.yahoo.com/flash/astra-flash/form * @see http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_08.html * @see com.yahoo.astra.containers.formClasses.FormItem * @see com.yahoo.astra.managers.FormDataManager * @author kayoh */ public class Form extends VBoxPane implements IForm { //-------------------------------------- // Constructor //-------------------------------------- /** * Constructor. * * @param formHeadingString String for optional text field of "FormHeading". */ public function Form(formHeadingString : String = null) { super(); formItemArr = []; //EventObserver to dispatch/listen event from Form class. formEventObserver = new FormEventObserver(); subscribeObserver(formEventObserver); if(formHeadingString && !headFormItem) attachFormHeadingLabel(formHeadingString); //Will show Form when the container settled right size. this.visible = false; this.addEventListener(Event.ENTER_FRAME, handler_enterFrame, false, 0, true); } //-------------------------------------- // Properties //-------------------------------------- /** * @private */ private var temp_adjusting_height : Number; /** * @private */ private var formItemArr : Array = []; /** * @private */ private var gotRequiredField : Boolean = false; /** * @private */ private var headingLabelField : TextField = null; /** * @private */ private var subHeadLineTxtFieldArray : Array = []; /** * @private */ private var longestlabelWidth : Number = NaN; /** * @private */ private var preferredheadLabelTextFormat : TextFormat = null; /** * @private */ private var preferredLabelTextFormat : TextFormat = null; /** * @private */ private var preferredInstructionTextFormat : TextFormat = null; /** * @private */ private var dataManager : IFormDataManager = null; /** * @private */ private var headFormItem : FormItem = null; /** * @private */ private var loopCatcher : int = 0; /** * @private */ private var formEventObserver : FormEventObserver = null; /** * Sets and gets dataManager for Form to collect and validate data. * * @see com.yahoo.astra.managers.FormDataManager */ public function get formDataManager() : IFormDataManager { return dataManager; } /** * @private */ public function set formDataManager(value : IFormDataManager) : void { dataManager = value; } /** * @private * Storage for the dataSource property. */ private var _dataSource : Object = null; /** *

Gets and sets the data to be shown and validated in a Form. * In order to collect and validate data, FormDataManager must be set before setting of dataSource in the Form.

*

Property Options:

*
*
label : String
*
The String for label text field.(e.g. lable:"State")
*
items : Object or String(or Object or String Array)
*
The DisplayObject to be contained and to be shown in a FormItem. String value will be attached as a textfield object.If there is multiple items, nest them into an array.(e.g.items:[stateComboBox,"Zip Code",zipcodeInput])
*
itemAlign : String
*
The alignment of multiple items in a FormItem. The default alignment is "horizontal"(FormLayoutStyle.HORIZONTAL)(e.g. itemAlign:FormLayoutStyle.VERTICAL)
*
instructionText : String
*
The String for additional label text field bottom of the item(s).(e.g. instructionText:"we'll not spam you!")
*
skin : DisplayObject
*
The DisplayObject to be applied as a background skin of the FormItem (e.g. skin:new myBeautifulSkinMC())
*
labelTextFormat : TextFormat
*
The TextFormat to be applied to label of the FormItem (e.g. labelTextFormat:new TextFormat("Times", 12, 0xff0000))
*
itemHorizontalGap : Number
*
The number of pixels in gaps between each items in a FormItems horizontaly.(e.g. itemHorizontalGap:8)
*
itemVerticalGap : Number
*
The number of pixels in gaps between each items in a FormItems verticaly.(e.g. itemVerticalGap:8)
*
id : String(or String Array)
*
The property of collected data.(e.g. id:"zip" will be saved in FormDataManager as FormDataManager.collectedData["zip"] = "94089")
*
source : Object(or Object Array)
*
The actual input source contains user input data.(e.g. source:[stateComboBox, zipcodeInput])
*
property : Object(or Object Array)
*
The additional property of source. If you defined valuePaser of FormDataManager as FlValueParser, don't need to set this property in general(e.g. source:[comboBox, textInput] , property:["abbreviation","text"]
*
validator : Function(or Function Array)
*
The Function to validate the source.(e.g. validator:validator.isZip)
*
validatorExtraParam : Object(or Object Array)
*
extra parameter(beside first parameter) of the validation.
*
required : Boolean(or Boolean Array)
*
The Boolean to decide to show required filed indicator(~~) and apply validation(validator).(e.g. id:["stateComboBox", "zipcodeInput"], required:[false, true])
*
errorString : String
*
The String to show under the item(s) fail to validation when showErrorMessageText is set true. If there is existing instructionText, will be replaced by errorString.(e.g. errorString:"What kind of zipcode is that?.")
*
* * * @example The following code shows a use of dataSource: * * // Download Adobe validator and add in the classpath * import com.adobe.as3Validators.as3DataValidation; * import com.yahoo.astra.fl.utils.FlValueParser; * // Init formDataManager with FlValueParser. * myForm.formDataManager = new FormDataManager(FlValueParser); * // Init validator to be used. * var validator : as3DataValidation = new as3DataValidation(); * var myFormDataArr : Array = [ * {label:"Name", items:nameInput, id:"name", source:nameInput}, * {label:"Address", items:[addressInput_line_1,addressInput_line_2 ], id:["address_line_1", "address_line_2"], source:[addressInput_line_1,addressInput_line_2]}, * {label:"Email", items:emailInput, id:"email", instructionText :"we'll not spam you!", source:emailInput, required:true, validator:validator.isEmail}, * {label:"", items:submitButton}]; * myForm.dataSource = new dataSource(myFormDataArr); * * * @default null */ public function get dataSource() : Object { return this._dataSource; } /** * @private */ public function set dataSource(value : Object) : void { this._dataSource = value; buildFromdataSource(); } /** * Setting string of optional text field on top of the Form. * @param value Text to be shown in the FormHeading text field. */ public function set formHeading(value : String) : void { if(!value) return; if(!headFormItem) attachFormHeadingLabel(value); headingLabelField.htmlText = value; } /** * @private * Storage for the showErrorMessageText property. */ private var _showErrorMessageText : Boolean = false; /** * @copy com.yahoo.astra.containers.formClasses.FormItem#showErrorMessageText * * @default false */ public function get showErrorMessageText() : Boolean { return _showErrorMessageText; } /** * @private */ public function set showErrorMessageText(value : Boolean) : void { _showErrorMessageText = value; } /** * @private * Storage for the showErrorMessageBox property. */ private var _showErrorMessageBox : Boolean = false; /** * Sets and gets to present the error result message box : a translucent gray box(alpha:.2 , color:0x666666) behind the item that failed to validate.
* * @example The following code shows a use of showErrorMessageBox: * * myForm.setStyle("errorBoxColor", 0xff00ff); * myForm.setStyle("errorBoxAlpha", 1); * myForm.showErrorMessageBox = true; * * @see setStyle * @default false */ public function get showErrorMessageBox() : Boolean { return _showErrorMessageBox; } /** * @private * Storage for the showErrorMessageBox property. */ public function set showErrorMessageBox(value : Boolean) : void { _showErrorMessageBox = value; } /** * @private * Storage for the labelWidth property. */ private var _labelWidth : Number = NaN; /** * @copy com.yahoo.astra.containers.formClasses.FormItem#labelWidth * * @default NaN; */ public function get labelWidth() : Number { return _labelWidth; } /** * @private */ public function set labelWidth(value : Number) : void { if(_labelWidth == value) return; _labelWidth = value; if(headFormItem) { if(headFormItem.labelItem) LayoutManager.update(headFormItem.labelItem, "preferredWidth", labelWidth); } } /** * @private * Storage for the itemVerticalGap property. */ private var _itemVerticalGap : Number = FormLayoutStyle.DEFAULT_FORMITEM_VERTICAL_GAP; /** * @copy com.yahoo.astra.containers.formClasses.FormItem#itemVerticalGap * * @default FormLayoutStyle.DEFAULT_FORMITEM_VERTICAL_GAP(6 px) */ public function get itemVerticalGap() : Number { return _itemVerticalGap; } /** * @private */ public function set itemVerticalGap(value : Number) : void { _itemVerticalGap = value; } /** * @private * Storage for the itemHorizontalGap property. */ private var _itemHorizontalGap : Number = FormLayoutStyle.DEFAULT_FORMITEM_HORIZONTAL_GAP; /** * @copy com.yahoo.astra.containers.formClasses.FormItem#itemHorizontalGap * * @default FormLayoutStyle.DEFAULT_FORMITEM_HORIZONTAL_GAP(6 px) */ public function get itemHorizontalGap() : Number { return _itemHorizontalGap; } /** * @private */ public function set itemHorizontalGap(value : Number) : void { _itemHorizontalGap = value; } /** * @private * Storage for the horizontalGap property. */ private var _horizontalGap : Number = FormLayoutStyle.DEFAULT_HORIZONTAL_GAP; /** * @copy com.yahoo.astra.containers.formClasses.FormItem#horizontalGap * * @default FormLayoutStyle.DEFAULT_HORIZONTAL_GAP(6 px) */ override public function get horizontalGap() : Number { return _horizontalGap; } /** * @private */ override public function set horizontalGap(value : Number) : void { _horizontalGap = value; } /** * @private * Storage for the verticalGap property. */ private var _verticalGap : Number = FormLayoutStyle.DEFAULT_VERTICAL_GAP; /** * The number of pixels in gaps between FormItems. * * @param value Number of pixels. * @default FormLayoutStyle.DEFAULT_VERTICAL_GAP(6 px) */ override public function get verticalGap() : Number { return _verticalGap; } /** * @private */ override public function set verticalGap(value : Number) : void { if(_verticalGap == value) return; super.verticalGap = _verticalGap = value; } /** * @private * Storage for the indicatorLocation property. */ private var _indicatorLocation : String = FormLayoutStyle.DEFAULT_INDICATOR_LOCATION; /** * @copy com.yahoo.astra.containers.formClasses.FormItem#indicatorLocation * * @default FormLayoutStyle.INDICATOR_LABEL_RIGHT */ public function get indicatorLocation() : String { return _indicatorLocation; } /** * @private */ public function set indicatorLocation(value : String) : void { _indicatorLocation = value; } /** * @private * Storage for the labelAlign property. */ private var _labelAlign : String = FormLayoutStyle.DEFAULT_LABELALIGN; /** * @copy com.yahoo.astra.containers.formClasses.FormItem#labelAlign * * @default FormLayoutStyle.RIGHT */ public function get labelAlign() : String { return _labelAlign; } /** * @private */ public function set labelAlign(value : String) : void { _labelAlign = value; } //-------------------------------------- // Public Methods //-------------------------------------- /** * Adds DisplayObject into the Form. If the data is provied by dataSource, addItem will not be used explicitly. * Also, if the child is not a FormItem instance, it will be attached to left edge of a Form. * * @param child DisplayObject to be contained. * @param required Optional parameter determines the requirement of the form. */ public function addItem(child : DisplayObject, required : Boolean = false) : void { if(child is FormItem) { var formItem : FormItem = child as FormItem; formItem = child as FormItem; formItem.subscribeObserver(formEventObserver); if(preferredLabelTextFormat) { notifyObserver(FormLayoutEvent.UPDATE_LABEL_FONT_CHANGE, preferredLabelTextFormat); } if(preferredInstructionTextFormat) { notifyObserver(FormLayoutEvent.UPDATE_INSTRUCTION_FONT_CHANGE, preferredInstructionTextFormat); } if(isNaN(labelWidth)) { if(!isNaN(formItem.labelWidth)) findLongestLabelWidth(formItem.labelWidth); if(longestlabelWidth > 0) { notifyObserver(FormLayoutEvent.UPDATE_LABEL_WIDTH, longestlabelWidth); } formItem.addEventListener(FormLayoutEvent.LABEL_ADDED, handler_formItemLabelAdded, false, 0, true); } else { notifyObserver(FormLayoutEvent.UPDATE_LABEL_WIDTH, labelWidth); } if(required) { formItem.required = true; gotRequiredField = true; } if(gotRequiredField) notifyObserver(FormLayoutEvent.UPDATE_GOT_REQUIRED_ITEM, gotRequiredField); if(showErrorMessageText) notifyObserver(FormLayoutEvent.UPDATE_ERROR_MSG_TEXT, showErrorMessageText); if(showErrorMessageBox) notifyObserver(FormLayoutEvent.UPDATE_ERROR_MSG_BOX, showErrorMessageBox); if(horizontalGap != FormLayoutStyle.DEFAULT_HORIZONTAL_GAP) { notifyObserver(FormLayoutEvent.UPDATE_HORIZONTAL_GAP, horizontalGap); } if(itemVerticalGap != FormLayoutStyle.DEFAULT_FORMITEM_VERTICAL_GAP) notifyObserver(FormLayoutEvent.UPDATE_ITEM_VERTICAL_GAP, itemVerticalGap); if(itemHorizontalGap != FormLayoutStyle.DEFAULT_FORMITEM_HORIZONTAL_GAP) notifyObserver(FormLayoutEvent.UPDATE_ITEM_HORIZONTAL_GAP, itemHorizontalGap); if(gotRequiredField && indicatorLocation) notifyObserver(FormLayoutEvent.UPDATE_INDICATOR_LOCATION, indicatorLocation); if(labelAlign != FormLayoutStyle.DEFAULT_LABELALIGN) notifyObserver(FormLayoutEvent.UPDATE_LABEL_ALIGN, labelAlign); this.addChild(formItem); } else { var container : FormItemContainer = new FormItemContainer(); container.addItem(child); this.addChild(container); } } /** * Sets additional items under the FormHeading field. * * @example The following code shows a use of subFormHeading: * * var myForm:Form = new Form("Contact Us."); * var asteriskMC : MovieClip = new indicatorSkin(); * myForm.subFormHeading(asteriskMC, "is required field."); * * * @param args Elements to be contained in subFormHeading field. Either String or DisplayObjects will be accepted. */ public function subFormHeading(...args) : void { if(args.length < 1) return; if(!headFormItem) attachFormHeadingLabel(""); var subHeadLabel : LayoutContainer = new LayoutContainer(new BoxLayout()); subHeadLineTxtFieldArray = []; for (var i : int = 0;i < args.length; i++) { var obj : * = args[i]; if(obj is String) { var subHeadLineTxtField : TextField = FormLayoutStyle.instructionTextField; if(preferredInstructionTextFormat) { subHeadLineTxtField.defaultTextFormat = preferredInstructionTextFormat; } subHeadLineTxtField.htmlText = obj.toString(); subHeadLabel.addChild(subHeadLineTxtField); subHeadLineTxtFieldArray.push(subHeadLineTxtField); } else { subHeadLabel.addChild(obj); } } headFormItem.itemContainer.addItem(subHeadLabel); } /** * Sets a style property on this component instance. * Calling this method can result in decreased performance, so use it only when necessary. *

Additional Styles for Form:

*
*
skin : Object
*
The skin of Form. Default is none.
*
indicatorSkin : DisplayObjectContainer
*
The skin of required field indicator's skin. Default is asterisk(~~).
*
errorBoxColor : Object
*
The color of errorMessageBox. Default is 0x6666.
*
errorBoxAlpha : Number
*
The alpha of errorMessageBox. Default is .2
*
textFormat : TextFormat
*
The text format of all the labels in the Form. Default is : "_sans", 11, 0x000000.
*
instructionTextFormat : TextFormat
*
The text format of all the instructionText fields in the Form. Default is : "_sans", 10, 0x000000.
*
headTextFormat : TextFormat
*
The text format of formHeading field in the Form. Default is : "_sans", 11, 0x000000, bold.
*
* * @example The following code shows a use of setStyle: * * var myForm:Form = new Form(); * myForm.setStyle("indicatorSkin", "myCustomIndicatorSkinMC"); * myForm.setStyle("textFormat", new TextFormat("Times", 13, 0xFF0000)); * * * * @param style The name of the style property. * * @param value The value of the style. * * @see com.yahoo.astra.containers.formClasses.FormLayoutStyle */ override public function setStyle(style : String, value : Object) : void { if(value && style == "textFormat") { longestlabelWidth = 0; preferredLabelTextFormat = value as TextFormat; return; } if(value && style == "instructionTextFormat") { preferredInstructionTextFormat = value as TextFormat; if(subHeadLineTxtFieldArray) { var subHeadLineTxtFieldArrayLeng : int = subHeadLineTxtFieldArray.length; for (var i : int = 0;i < subHeadLineTxtFieldArrayLeng; i++) { var subTextField : TextField = subHeadLineTxtFieldArray[i]; subTextField.setTextFormat(preferredInstructionTextFormat); } } return; } if(value && style == "headTextFormat") { preferredheadLabelTextFormat = value as TextFormat; if(headingLabelField) { headingLabelField.defaultTextFormat = preferredheadLabelTextFormat; this.formHeading = headingLabelField.text; } return; } if(style == "indicatorSkin" || style == "errorBoxAlpha" || style == "errorBoxColor") { FormLayoutStyle.defaultStyles[style] = value; } super.setStyle(style, value); } /** * @private * @see com.yahoo.astra.fl.containers.formClasses.FormItem#subscribeObserver */ public function subscribeObserver(formEventObserver : IFormEventObserver) : IFormEventObserver { return formEventObserver.subscribeObserver(this); } /** * @private * @see com.yahoo.astra.fl.containers.formClasses.FormItem#update */ public function update(target : String,value : Object = null) : void { /* * have no event to update in this class. */ } //-------------------------------------- // Private Methods //-------------------------------------- /** * @private */ private function notifyObserver(target : String, value : Object = null) : void { if(!formEventObserver) return; formEventObserver.setUpdate(target, value); } /** * @private */ private function handler_enterFrame(e : Event) : void { if(NumberUtil.fuzzyEquals(this.height, temp_adjusting_height) || loopCatcher > 20) { this.removeEventListener(Event.ENTER_FRAME, handler_enterFrame); this.visible = true; loopCatcher = 0; // all adjustment for Form is done. this.dispatchEvent(new FormLayoutEvent(FormLayoutEvent.FORM_BUILD_FINISHED)); return; } temp_adjusting_height = this.height; loopCatcher++; } /** * @private */ private function attachFormHeadingLabel(value : String) : void { headingLabelField = FormLayoutStyle.headTextField; if(preferredheadLabelTextFormat) headingLabelField.defaultTextFormat = preferredheadLabelTextFormat; headingLabelField.htmlText = value; headFormItem = new FormItem(headingLabelField); headFormItem.isFormHeadingLabel = true; headFormItem.itemAlign = FormLayoutStyle.VERTICAL; this.addItem(headFormItem, false); } /** * @private */ private function handler_formItemLabelAdded(e : FormLayoutEvent) : void { var formItem : FormItem = e.target as FormItem; findLongestLabelWidth(formItem.labelWidth); } /** * @private */ private function findLongestLabelWidth(labelWidth : Number = 0) : void { if(isNaN(longestlabelWidth)) longestlabelWidth = 0; if(labelWidth > longestlabelWidth) { longestlabelWidth = labelWidth; notifyObserver(FormLayoutEvent.UPDATE_LABEL_WIDTH, longestlabelWidth); } } /** * @private */ private function buildFromdataSource() : void { var dataLength : int = dataSource.length; for (var i : int = 0;i < dataLength; i++) { var curData : Object = dataSource[i]; if(curData["label"] == undefined ) { /* * Item with no Label. */ var itemContainer : FormItemContainer = new FormItemContainer(); if (curData["itemAlign"]) itemContainer.itemAlign = curData["itemAlign"]; if(curData["items"] is Array) { var curItemDataLength : int = curData["items"].length; for (var j : int = 0;j < curItemDataLength; j++) { itemContainer.addItem(curData["items"][j]); } } else { itemContainer.addItem(curData["items"]); } this.addItem(itemContainer, curRequired); } else { var curLabel : String = (curData["label"]) ? curData["label"] : ""; var curItmes : Object = (curData["items"]) ? curData["items"] : []; var curRequired : Boolean = false; if(curData["required"] is Array) { var reqLeng : int = curData["required"].length; for (var k : int = 0;k < reqLeng; k++) { var temp : Boolean = Boolean(curData["required"][k] as Boolean); curRequired ||= temp; } } else if(curData["required"] is String) { curRequired = (curData["required"] == "true") ? true : false; } else { curRequired = (curData["required"]) ? curData["required"] : false; } var curFormItem : FormItem = new FormItem(curLabel, curItmes); if (curData["errorString"]) curFormItem.errorString = curData["errorString"]; if (curData["itemAlign"]) curFormItem.itemAlign = curData["itemAlign"]; if (curData["instructionText"]) curFormItem.instructionText = curData["instructionText"]; if (curData["itemHorizontalGap"]) curFormItem.itemHorizontalGap = curData["itemHorizontalGap"]; if (curData["itemVerticalGap"]) curFormItem.itemVerticalGap = curData["itemVerticalGap"]; if (curData["skin"]) curFormItem.skin = curData["skin"]; if (curData["labelTextFormat"]) curFormItem.labelTextFormat = curData["labelTextFormat"]; this.addItem(curFormItem, curRequired); } var curId : Object = curData["id"]; if(!curId ) continue; if(curId && !dataManager) { throw new Error("You must set formDataManager before set the dataSource."); } if(curData["id"] is Array) { var curIdDataLength : int = curId.length; for (var l : int = 0;l < curIdDataLength; l++) { var curSource : Object = (curData["source"] is Array) ? curData["source"][l] : null; var curProperty : Object = (curData["property"] is Array) ? curData["property"][l] : null; var curValidator : Function = (curData["validator"] is Array) ? curData["validator"][l] : null; var validatorExtraParam : Object = (curData["validatorExtraParam"] is Array) ? curData["validatorExtraParam"][l] : null; var curRequiredArr : Boolean = (curData["required"] is Array) ? curData["required"][l] : false; var curTargetObj : DisplayObject = (curData["targetObj"] is Array) ? curData["targetObj"][l] as DisplayObject : curFormItem; var curEventFunction_success : Function = (curData["eventFunction_success"] is Array) ? curData["eventFunction_success"][l] as Function : null; var curEventFunction_fail : Function = (curData["eventFunction_fail"] is Array) ? curData["eventFunction_fail"][l] as Function : null; if(curFormItem) curFormItem.hasMultipleItems = true; dataManager.addItem( curData["id"][l], curSource, curProperty, curRequiredArr, curValidator, validatorExtraParam, curTargetObj, curEventFunction_success, curEventFunction_fail); } } else { dataManager.addItem( curData["id"], curData["source"], curData["property"], curRequired, curData["validator"], curData["validatorExtraParam"], (curData["targetObj"] is DisplayObject) ? curData["targetObj"] : curFormItem, curData["eventFunction_success"], curData["eventFunction_fail"]); } } } } }