close

Filter

loading table of contents...

Studio Developer Manual / Version 2107

Table Of Contents

7.4.3 Compound Field

The 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 &lt;code>readOnly&lt;/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


Search Results

Table Of Contents
warning

Your Internet Explorer is no longer supported.

Please use Mozilla Firefox, Google Chrome, or Microsoft Edge.