Long time, no news…. It’s been almost 6 weeks since the last update of Siam Flex Framework. But today I am proud to present to you the first beta release of Siam!
I’ve been spending a lot of time refining the core elements of Siam to ensure that we have the right API going forward.
So what’s new?
- Easier configuration with improved syntax and default specification
- Editors and validators are now supported
- Simpler API using factory and context classes
- Structured import for all data representation classes
- More control over formatting behavior
Where can I download it?
The project is hosted at .
You can try out the latest features with the Siam Flex Explorer:
The explorer encapsulate an example of application using all features of Siam and allows you to alter its XML configuration at run-time for demonstration purposes. The embedded example include implementations of a dynamic data grid and form, as wells as an adapted chart component.
Details follow below…
Structured Imports
Siam heavily relies on reflection to parse configurations and have to deal with one common Flex issue… If a class is not initially imported into the application, trying to resolve its class name will always fail. The new API allows you to structure and organize your data representation classes import, as show below. Note: the import setters (e.g. importRenderers
…) are optional and have no effect on the behavior of SiamManager
.
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:siam=""> <mx:Script> <![CDATA[ import mx.formatters.* import mx.controls.*; import mx.validators.*; ... ]]> </mx:Script> <siam:SiamManager id="siam"> <mx:XML source="siam.cfg.xml" /> <siam:importFormatters>{[DateFormatter,NumberFormatter,CurrencyFormatter,ZipCodeFormatter,PhoneFormatter]}</siam:importFormatters> <siam:importRenderers>{[Label,CheckBox]}</siam:importRenderers> <siam:importEditors>{[TextInput, NumericStepper, CheckBox, ComboBox, HSlider, ColorPicker, Image]}</siam:importEditors> <siam:importValidators>{[StringValidator,EmailValidator,RegExpValidator]}</siam:importValidators> </siam:SiamManager> ... </mx:Application>
Formatters
- standard implementation is now available (missing from SDK). The format function implicitly calls
toString()
on any given non-null parameter or returnsnull
otherwise (org.siam.impl.data.formatters.StringFormatter
) - a default formatter may be configured by simply using keyword
default
as an id - ability to override formatting behavior when input is missing or blank (see
ifNull
andifEmpty
, may be configured for each formatter)
XML Configuration
<formatters> <class name="org.siam.impl.data.formatters.StringFormatter"> <formatter id="default" ifNull="n/a" ifEmpty="(Blank)" /> </class> <class name="mx.formatters.NumberFormatter"> <formatter id="integer" precision="0" /> </class> <class name="mx.formatters.CurrencyFormatter"> <formatter id="money" precision="1" currencySymbol="$ " /> </class> <class name="mx.formatters.PhoneFormatter"> <formatter id="phone" formatString="(##)###-####" /> </class> </formatters>
API Examples
var formatters:IFormattersManager = siam.formatters; trace(formatters.format(10, "money")); // $ 10.0 trace(formatters.format("text", "any")); // text trace(formatters.format(null, "any")); // n/a trace(formatters.format("", "any")); // (Blank) trace(formatters.has("boolean")); // false
Renderers
- each renderer can be described using setters, variables and now style properties
- a default renderer may be configured by simply using keyword
default
as an id. For instance, you might want to center horizontally all your application data renderers (especially useful with data grids) - each renderer can be instantiated through factory pattern which is accessible via
IRendererContext
.
XML Configuration
<renderers> <class name="mx.controls.Label"> <renderer id="default" textAlign="center" /> <renderer id="number" textAlign="right" color="0xFF0000" /> </class> <class name="mx.controls.Image"> <renderer id="image" /> </class> <class name="mx.controls.CheckBox"> <renderer id="boolean" textAlign="center" enabled="false" /> </class> <class name="custom.GravatarImage"> <renderer id="gravatar" size="60" /> </class> </renderers>
API Examples
var renderers:IRenderersManager = siam.renderers; var renderer:IRendererContext = renderers.find("fourwd"); trace(ObjectUtil.toString(renderer.factory)); /* (org.siam.utils::UIComponentFactory)#0 generator = (mx.controls::Label) properties = (Object)#1 styles = (Object)#2 textAlign = "center" */
Editors
- each editor can be described using setters, variables and style properties.
- arrays are supported globally and can be useful for enumerations (e.g in a
ComboBox
) - a default editor may be configured by simply using keyword
default
as an id (useful with data forms, e.g text inputs). - for each editor, you may specify via
dataField
the property that returns the new data (for instance needed in Flex DataGrid components). - each editor can be instantiated through factory pattern which is accessible via
IEditorContext
(along with other metadata)
XML Configuration
<editors> <class name="mx.controls.TextInput"> <editor id="default" textAlign="right" dataField="text" /> </class> <class name="mx.controls.NumericStepper"> <editor id="yearStepper" textAlign="right" dataField="value" minimum="1990" maximum="2010"/> <editor id="priceStepper" textAlign="right" dataField="value" minimum="0" maximum="50000" stepSize="500" /> </class> <class name="mx.controls.CheckBox"> <editor id="boolean" dataField="selected" /> </class> <class name="mx.controls.ComboBox"> <editor id="categories" dataProvider="[assets/luxury.jpg,assets/sedan.jpg,assets/suv.jpg,assets/hybrid.jpg]" dataField="selectedItem" /> </class> <class name="mx.controls.HSlider"> <editor id="mileageSlider" dataField="value" maximum="150000" liveDragging="true" /> </class> <class name="mx.controls.ColorPicker"> <editor id="colorPicker" dataField="selectedColor" /> </class> </editors>
API Examples
var editors:IEditorsManager = siam.editors; var editor:IEditorContext = editors.find("price"); trace(editor.dataField); // text trace(ObjectUtil.toString(editor.factory)); /* (org.siam.utils::UIComponentFactory)#0 generator = (mx.controls::TextInput) properties = (Object)#1 styles = (Object)#2 textAlign = "right" */
Validators
- each validator can be described using setters and variables.
- regular expressions are supported globally but need to be escaped in the XML configuration file (see
mx.validators.RegExpValidator
) - a default validator may be configured by simply using keyword
default
as an id (for instance, all text inputs in your application are by default required). - each validator can be instantiated through factory pattern which is accessible via
IValidatorContext
.
XML Configuration
<validators> <class name="mx.validators.StringValidator"> <validator id="default" /> <validator id="requiredOnly" required="true" /> </class> <class name="mx.validators.RegExpValidator"> <validator id="zipcode" expression="^\d{2}-\d{3}$" required="true" /> </class> <class name="mx.validators.EmailValidator"> <validator id="email" required="true" /> </class> </validators>
API Examples
var validators:IValidatorsManager = siam.validators; var validator:IValidatorContext = validators.find("email"); trace(ObjectUtil.toString(validator.factory)); /* (mx.core::ClassFactory)#0 generator = (mx.validators::EmailValidator) properties = (Object)#1 required = true */
Schemas
- Multiple data model schemas can be described in a Siam XML configuration file.
- Each schema property can point to any data representation id (
formatter
,renderer
,editor
,validator
). If none is specified, it will use the default one (if any). - Any meta-data may be added to the property configuration and retrieve via function
findMetadata
inISchemaManager
.
XML Configuration
<schemas> <schema id="car"> <property id="category" name="Category" renderer="image" editor="categories" /> <property id="make" name="Make" validator="requiredOnly" /> <property id="model" name="Model" validator="requiredOnly" /> <property id="year" name="Year" editor="yearStepper" /> <property id="mileage" name="Mileage" formatter="integer" renderer="number" editor="mileageSlider"/> <property id="price" name="Price" formatter="money" renderer="number" editor="priceStepper" /> <property id="location" name="Location" validator="zipcode" /> <property id="owner" name="Owner" renderer="gravatar" validator="email" /> <property id="contact" name="Contact" formatter="phone" /> <property id="fourwd" name="4WD" renderer="boolean" editor="boolean" /> </schema> </schemas>
API Examples
var car:Object = { make:"Land Rover", mileage:"17800" }; var schema:ISchemaManager = siam.manage("car"); trace(schema.findMetadata("name", "fourwd")); // 4WD trace(schema.format(car, "mileage")); // 17,800 trace(schema.format(car, "year")); // n/a trace(schema.findRenderer("owner")); // [Object IRendererContext] trace(schema.findEditor("price")); // [Object IEditorContext] trace(schema.findValidator("email")); // [Object IValidatorContext]
Conclusion
I was able to successfully use this beta version in an application for a customer, dealing with:
- dynamic data grid and forms for administration purposes
- reporting dashboards with pivot tables and charting components
- basic OLAP and CRUD operations with lightweight transfer objects and simple data-types
All in all, it saved me bunch of times and now maintenance has never been easier…
Please try it out and let me know if you like it and how it works for your applications. I’d be very curious to know what limitations exist in other types of applications and architectures (complex TO, web services, …)
I am looking forward to your feedback.
Julien
Very very nice article. As I am sitting next you, seeing your work everyday, I know how powerful this thing really is. Hope other Flex dudes will realize it soon too.
Wow.. this is very cool. I want to jump in and work on it. Is 0.4 the latest update?
Great article really helpful.Agree with Michal..its about time others realized how powerful and useful flex frame work is.