Notes on Data Validation

I’ve been answering some questions for folks internally and externally about validation and thought I’d try to post it here for anyone who’s interested. This is a combination of personal opinion as to how validation can work as well as notes on how it does work now…


Validation in Flex is a mechanism for determining if data is valid. That data can be any field of any object, anywhere. The Flex system tries to build on this simple concept and add in the ability for certain data to be automatically validated. And we then take it a step further and if possible display errors at the source of their problem (the red border around a UI component).Before getting into a few more details I want to share some of the thoughts that went behind the design of our validation framework. First, we always want to encourage a separation of Model and View. The view onto data might look different than the raw representation of data itself (think formatting). Therefore, we built around the principle that it is data that is valid or invalid, not the view onto that data. This is why you validate a Model’s field, not the TextInput’s text.The second principle we followed is that validation should not affect data flow. In Flex, data is often passed around using data binding which therefore implies that the source and destination should always be in sync. In fact, there is no way to determine if the source and destination are in sync because it is assumed they always will be (with the notable exception of not syncing an initially undefined/null/empty-string value). Given that binding implies synchronization, it seemed that it’d be wrong for a binding to not take place if the data it was trying to pass was invalid. We decided the data should go to its destination and other parts of the system should prevent further application execution if there is a problem. I’ve seen differences of opinion on this approach and am open to incorporating other ideas into the system in the future if they make sense.OK, now some more details on automatic and manual validation. A field is automatically validated if it is the destination of a binding expression. This generally implies that you will validate Models as opposed to UI controls, as it’s often safe to assume that data already in Models will be correct while user input may be incorrect. If the field you want to validate is not the destination of a binding (or you want to re-execute validation on something already bound) you need to use the Validator.isValid method (or Validator.isStructureValid). See the ASDoc and chapters for more info.Now what about making the red borders and error tooltips appear. When a binding is created the compiler looks at the source expression and sees if it can find a UIComponent as part of it. If it does, that becomes the automatic listener for a Validator using the destination as its field. So when we see a binding expression like this:

<mx:Model id="foo"><bar>{someInput.text}</bar></mx:Model>

we see that the source expression is “someInput.text” and the destination is “foo.bar”. A Validator with field="foo.bar" will thus have a default listener of “someInput” (the UIComponent). So there we go, automatic validation listeners. Now if the compiler didn’t make the connection correctly or if you want a different component to be your listener, simply reassign the listener on the Validator tag (the docs discuss how to be a validation listener).Extra notes:A Validator can be assigned to validate objects not in your document. You can validate components that live in other documents no problem:

<mx:Validator field="someComponent.someOtherComponent.someObject.someField" listener="someComponentOnMyDocument" />

If the Validator is defined in another document but you want to call isValid from another location, the isValid call is ready for that as well.The method signature for isValid is this: Validator.isValid(document, field), document is the reference to the document where you defined the Validator. field is the string that should exactly match the field declaration on the Validator tag.So if you’re willing to call isValid yourself you don’t need to worry about setting up binding for validation to work (and it doesn’t need to validate against an mx:Model). And if you want the red borders to appear and you’re not using binding, you set up the listener. And if all of that needs to happen in another document, no problem.Hope this sheds some light on validation. Feel free to make comments on the docs or here if you’d like more info on something.