Component “Templates” in Flex 2.0

First, let me be very clear: Flex 2.0 does NOT support templates. But this article will show you a way to make it look and act as if it does.

A “template” is different from a custom component. A template typically specifies a number of parts with some of the areas left open for substitution. I think of templates as being done exclusively in MXML whereas components can be 100% ActionScript or a combination of AS and MXML. Dreamweaver has the ability to do templates using regions.

Note: An example is available for download at the end of the article.

Panel Template

Suppose you want to create a Panel with a certain look and use it frequently in your application. Perhaps the Panel has a ControlBar with a “Search” and “Help” button. You want to make sure the Panel has the ControlBar and Buttons all of the time, but you want to change the contents of the Panel. A template, called SearchPanel.mxml, to do this might look like:

<mx:Panel xmlns:mx="...." layout="absolute">
<mx:Metadata>
[Event("search")]
[Event("help")]
</mx:Metedata>
<!-- put children here -->
<mx:ControlBar>
<mx:Button label="Search" click="dispatchEvent(new Event('search'))" />
<mx:Button label="Help" click="dispatchEvent(new Event('help'))" />
</mx:ControlBar>
</mx:Panel>

To use this you might do:

<SearchPanel title="Employee Search" search="findEmployees()">
<mx:Form left="10" top="10" right="10" bottom="10">
... form items here ...
</mx:Form>
</SearchPanel>

If you were to write this in Flex today, you would get a compilation error saying that SearchPanel already had children. You cannot add more children from outside of the component. If you had written SearchPanel without the ControlBar, then this would work. But then every SearchPanel would not automatically have a ControlBar.

One solution is to write this as a custom component which creates the ControlBar and Buttons in ActionScript. I won’t do that here because I have a much better way to do it.

Making the ‘Template’

Let’s go back to SearchPanel and keep it the same, except add in this Script block:

<mx:Script>
<[[CDATA
private var _components:Array;
public function set subComponents( a:Array ) : void
{
_components = a;
}
private function addComponents() : void
removeAllChildren();
for(var i:int=0; i < _components.length; i++) {
addChild( _components[i] );
}
}
]]>
</mx:Script>

and modify the root tag: <mx:Panel xmlns:mx=”….” layout=”absolute” creationComplete=”addComponents()”>

Now use this in your program:

<SearchPanel title="Employee Search" search="findEmployees()">
<subComponents>
<mx:Form left="10" top="10" right="10" bottom="10">
... form items here
</mx:Form>
</subComponents>
</SearchPanel>

Notice that the Form, and any other children you want to add to the Panel, are defined by the <subComponent> property. In the Script block for the SearchPanel, subComponents is a set method which takes an Array. This Array will be 1 or more components defined in MXML. In this example, that Array is the <mx:Form>. Notice that the simple loop just takes each element of the Array and adds it to the Panel.

Now you have a “template”!

Default Property

But wait – there’s more. This is the really cool part. Go back into SearchPanel.mxml and add the following line to the <mx:Metadata> right after [Event(“help”)]:

[DefaultProperty("subComponents")]

Now change the main program just slightly by removing the <subComponents> tag:

<SearchPanel title="Employee Search" search="findEmployees()">
<mx:Form left="10" top="10" right="10" bottom="10">
... form items here
</mx:Form>
</SearchPanel>

Notice that <subComponents> is gone and this now looks like a real container. This works because of the DefaultProperty metadata. You’ve set the SearchPanel’s default property name to be “subComponents” which automatically places the <mx:Form> into the subComponent array.

Conclusion

While real templates are not available in Flex 2.0 you can come mighty close to making it look as though they are. This is possible because of the way components are now created in Flex 2.0 (using the new operator) and the DefaultProperty metadata.

Download Example

This example is similar to the one described above. Here, the component is a Panel wrapped by a Canvas. This is done so that minimize and maximize buttons can float over the Panel’s title bar.

Download file

27 Responses to Component “Templates” in Flex 2.0

  1. lidija says:

    I like this approach. Could you post a working example for us beginners to understand it better?
    Thank you.

  2. Great example Peter! I’ll be sure to put it to good use. It’s a great way to have custom components that already have child containers/controls.

    Very neat!

    -Andrew

  3. Peter Ent says:

    I’ve added a zip file download to the end of the article. The zip contains a more complex example, but that is more realistic.

  4. lidija says:

    Thanks a lot!

  5. Javier says:

    Great approach!!, is this coding way available in Flex 1.5?

  6. Peter Ent says:

    Unfortunately this not possible in Flex 1.5. What makes this work is the ability to create components and then assign them to a container afterwards. Here, the presence of the component in MXML causes it to be created and then put into an Array and made available via the defaultProperty. Then the component (as an object) is added to a container.

    In Flex 1.5, components could only be created by another component (createChild()).

  7. Dong Lee says:

    I wonder if above codings can be used with a ActionScript class so that there is only one generic SearchPanel that has following children:
    1. form : capture the search parameters
    2. datagrid : search results
    3. control bar with few buttons – to serve user actions

    With reasonably sized appliation there’d be various search screens. Whatever search module passes a parameter(search name, search object…) to the AS Class so that the class can dynamically create the SearchPanel with the children mentioned above, form, datagrid, controlbar.
    Can Flex2 do this?

  8. Peter Ent says:

    You could do what you suggest with a properties for the different parts. For example:

    If this is what you mean, I think Flex 2 can handle it.

  9. Rob says:

    Thank you, this explanation makes more sense than the one in the documentation from Adobe.

    I’ve found one drawback though. Using this approach you can no longer use the design view in Flex. It does not show the children in the MinMaxPanel. Is there a way around this?

    If the alternative is to write the template in pure ActionScript, can you please give an example how this would work?

    Thank you,

    – Rob

  10. brent dearth says:

    Very elegant … now suddenly most of these packaged components make sense to me. That metadata tag is very useful. Thanks!

  11. Tom Krcha says:

    Hi,

    as Rob asked (Posted by: Rob at November 28, 2006 11:55 AM)
    You cannot see the usage of templates and changes in design view of Flex. You see there only Template but no children in it, even if they are there.

    Is there any possibility how to accomplish this?

    Thanks a lot.
    Tom

  12. Peter Ent says:

    I’m afraid that still isn’t possible with Flex 2. Perhaps it will be in a future version. You can always go to our wishform (http://www.adobe.com/go/wish) and make the request.

  13. Chuck says:

    Hi,

    I’m preparing to have a web application developed in Flex 2.0 or 3.0 that allows someone to select a pre-defined HTML email template. The template would have frames for text and graphics, but the information inside are just placeholders. When the user selects a template they want to customize, it drops it into a drawing window. The user can now click on a frame inside the template to make it active and then drop-n-drop their graphic files. When they drop them into place, it would automatically fit them into the frame. They could also click on a text frame and begin typing or do a “paste”. When they click on the text frames, the program will automatically open a rich text editor that enables them to adjust the font, size, etc. Ultimately, they could see how this looks using the WYSIWYG view and then save the file.

    Does this sound like something you can do in Flex? If so, are you personally available to write this?

    Thanks!
    Chuck
    ——————-
    Peter:
    Chuck, I’m not available to lend a hand here, but for something like this you should look at the Flex Rich Text Editor control (mx.controls.RichTextEditor).

    The Flash player has limited support for HTML. Adding a true HTML renderering engine to the Flash Player would make it many megabytes in size and default the small footprint goal of the Player. So make sure RTE has what you need.

    You can also look into Adobe AIR – this is essentially a desktop Flex app. But AIR does have a built-in HTML engine because AIR isn’t expected to be downloaded on the fly. However, it too, uses the same RTE control.

  14. hans.xie says:

    thanks, Peter. that’s what I need.

  15. Muhammad Kamran Shafi says:

    Hi,

    I tried writing another MXML component (newComponent) extended from MinMaxPanel, if I try to add any items to my newComponent I get the same error
    “multiple sets of visual children have been specified”. Is there a work around to this?

    Thanks.
    ————————–
    Peter: You have to follow the same pattern as the MinMaxPanel and add a property for your additional components. Since the MinMaxPanel is already using a default property, you’ll have to make an explicit one.

  16. Thank you, this explanation makes more sense than the one in the documentation from Adobe.

  17. thanks, Peter. that’s what I need.

  18. Marcus Stade says:

    VERY cool stuff! Thanks a lot!

  19. hemgui says:

    Very usefull!! Thanks a lot

  20. Ramon says:

    That’s good workaround, but I’m not sure if the component inheritance is now available in Flex 3.0, because we are now building app using Flex 3, it seems if you directly inherits some custom component with UI objects, the errors still exist, thanks.

  21. Greg says:

    Ive read a few solutions to this problem, and this seems the most elegant to me. Im using Flex 3 – and it works well.

    Thanks Peter!

  22. Hi,

    I’m preparing to have a web application developed in Flex 2.0 or 3.0 that allows someone to select a pre-defined HTML email template. The template would have frames for text and graphics, but the information inside are just placeholders. When the user selects a template they want to customize, it drops it into a drawing window. The user can now click on a frame inside the template to make it active and then drop-n-drop their graphic files

  23. hello sir,
    i will like to have ur number.i need the wine cure .