Studio Developer Manual / Version 2101
Table Of ContentsThe following code example shows a more complex scenario, where a field for a URL is created that lets the user open a browser window or tab for the linked page with a single click.
The EXML declaration:
<?xml version="1.0" encoding="UTF-8"?> <local:UrlPropertyFieldBase xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns="exml:ext.config" xmlns:local="com.coremedia.blueprint.studio.forms.fields.*" xmlns:editor="exml:com.coremedia.cms.editor.sdk.config" xmlns:ui="exml:com.coremedia.ui.config"> <fx:Script><![CDATA[ import com.coremedia.ui.data.ValueExpression; /** * An optional ValueExpression which makes the component read-only if it is evaluated to true. */ [Bindable] public var forceReadOnlyValueExpression:ValueExpression; private var config:StringPropertyField; public native function UrlPropertyField(config:StringPropertyField = null); ]]></fx:Script> <fx:Declarations> <!--- Set the <code>readOnly</code> config option of the contained field. --> <fx:Boolean id="readOnly"/> <!--- Don't show any validation issues on this property field. --> <fx:Boolean id="hideIssues"/> </fx:Declarations> <local:items> <!-- The URL is edited in a text field. --> <TextField itemId="urlTextField" name="{'properties.' + config.propertyName}"> <plugins> <!-- register the new property editor --> <editor:PropertyFieldPlugin propertyName="{config.propertyName}"/> <!-- Generate an appropriate label. --> <editor:SetPropertyLabelPlugin bindTo="{config.bindTo}" propertyName="{config.propertyName}"/> <!-- When the field is empty, an informational message should appear. --> <editor:SetPropertyEmptyTextPlugin bindTo="{config.bindTo}" propertyName="{config.propertyName}"/> <!-- Disable the field as appropriate for a content form. --> <editor:BindDisablePlugin bindTo="{config.bindTo}"/> <!-- Bind the content of the field to the given content property. --> <ui:BindPropertyPlugin bindTo="{config.bindTo.extendBy('properties', config.propertyName)}" ifUndefined="" bidirectional="true"/> </plugins> </TextField> <!-- Add a link to the URL displayed in the field. The actual handling is done by the super class. --> <Button itemId="urlOpenButton" text="{resourceManager.getString('com.coremedia.blueprint.studio.forms.fields.PropertyFieldExample', 'UrlPropertyField_open_text')}" handler="{openFrame}"/> </local:items> </local:UrlPropertyFieldBase>
The base class:
package com.coremedia.blueprint.studio.forms.fields { import com.coremedia.ui.data.ValueExpression; import ext.container.Container; public class UrlPropertyFieldBase extends Container { public function UrlPropertyFieldBase(config:UrlPropertyField = null) { super(config); } /** * A property path expression leading to the Bean whose property is edited. */ [Bindable] public var bindTo:ValueExpression; /** * The property of the Bean to bind in this field. */ [Bindable] public var propertyName:String; /** * Try to open a new window with the string currently stored in the property used as the URL. */ public function openFrame():void { var url:String = bindTo.extendBy('properties', propertyName).getValue() as String; if (url) { window.open(url, 'externalLinkTarget'); } } } }
The above is an example of a compound field, where you need to wrap multiple Ext JS components in a container. This is possible, but you must take care to declare and pass around all configuration properties that need to be set on subcomponents.
There is also some application logic, which is what the base class is for. While you could
technically embed any code into the MXML file itself, it is good practice to separate out
application code in an ActionScript base class. Note how the MXML component references the
method openFrame
from the base class using curly brackets:
<Button itemId="urlOpenButton" text="..." handler="{openFrame}"/>
Example 7.24. Using a base class method