package components { import flash.display.DisplayObject; import flash.events.Event; import mx.containers.Form; import mx.containers.FormItem; import mx.controls.ComboBox; import mx.controls.TextInput; import mx.core.Container; import mx.core.UIComponent; import mx.events.FlexEvent; import mx.events.ValidationResultEvent; import mx.validators.ValidationResult; import mx.validators.Validator; public class ExtendedForm extends Form { private var requiredValidators:Array; private var invalidCounter:Number = 0; [Bindable] public var newElement:Boolean = false; public function ExtendedForm() { super(); requiredValidators = new Array(); } private function addHandlerContainer(container:Container, required:Boolean):void { for(var i:Number = 0; i < container.numChildren; i++) { var object:DisplayObject = container.getChildAt(i); if(object is FormItem) { processFormItem(FormItem(object), required); } else if(object is Container) { addHandlerContainer(Container(object), required); } else if(object is UIComponent) { addElements(UIComponent(object), required); } } } private function addElements(component:UIComponent, required:Boolean):void { component.addEventListener(FlexEvent.INVALID, function(event:Event):void { if(invalidCounter == 0) { setStyle("oldBorderStyle", getStyle("borderStyle")); setStyle("oldBorderColor", getStyle("borderColor")); setStyle("borderStyle", "solid"); setStyle("borderColor", getStyle("errorColor")); dispatchEvent(new FlexEvent(FlexEvent.INVALID)); } invalidCounter++; component.setStyle("oldBackgroundColor", getStyle("backgroundColor")); component.setStyle("backgroundColor", getStyle("errorColor")); }); component.addEventListener(FlexEvent.VALID, function(event:Event):void { invalidCounter--; if(invalidCounter == 0) { setStyle("borderStyle", getStyle("oldBorderStyle")); setStyle("borderColor", getStyle("oldBorderColor")); dispatchEvent(new FlexEvent(FlexEvent.VALID)); } component.setStyle("backgroundColor", getStyle("oldBackgroundColor")); }); if(required) { if(component is TextInput) { var validator:Validator = new Validator(); validator.source = component; validator.property = "text"; validator.triggerEvent = ""; requiredValidators.push(validator); } else if(component is ComboBox) { validator = new Validator(); validator.source = component; validator.property = "selectedLabel"; validator.triggerEvent = ""; requiredValidators.push(validator); } else if(component is EditableList) { validator = new Validator(); validator.source = component; validator.property = "firstItem"; validator.triggerEvent = ""; requiredValidators.push(validator); } } } private function processFormItem(formItem:FormItem, required:Boolean = false):void { for(var i:Number = 0; i < formItem.numChildren; i++) { var component:UIComponent = UIComponent(formItem.getChildAt(i)) if(component is Container && !(component is EditableList)) { var container:Container = Container(component); addHandlerContainer(container, formItem.required || required); } else { addElements(component, formItem.required || required); } } } public override function addChild(child:DisplayObject):DisplayObject { var newChild:DisplayObject = super.addChild(child); if(newChild is FormItem) { var formItem:FormItem = FormItem(newChild); processFormItem(formItem); } return newChild; } public function addRequiredValidator(validator:Validator):void { for(var i:Number = 0; i < requiredValidators.length; i++) { if(Validator(requiredValidators[i]).source == validator.source) { requiredValidators[i] = validator; } } } public function validate():Boolean { var retval:Boolean = true; for each(var validator:Validator in requiredValidators) { var resultEvent:ValidationResultEvent = validator.validate(); for each(var result:ValidationResult in resultEvent.results) { if(result.isError) { retval = false; } } } return retval; } } }