Studio Developer Manual / Version 2404
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.
import {bind} from "@jangaroo/runtime"; import Config from "@jangaroo/runtime/Config"; import ConfigUtils from "@jangaroo/runtime/ConfigUtils"; import Button from "@jangaroo/ext-ts/button/Button"; import TextField from "@jangaroo/ext-ts/form/field/Text"; import BindPropertyPlugin from "@coremedia/studio-client.ext.ui-components/plugins/BindPropertyPlugin"; import PropertyFieldPlugin from "@coremedia/studio-client.main.editor-components/sdk/premular/PropertyFieldPlugin"; import SetPropertyLabelPlugin from "@coremedia/studio-client.main.editor-components/sdk/premular/fields/plugins/SetPropertyLabelPlugin"; import SetPropertyEmptyTextPlugin from "@coremedia/studio-client.main.editor-components/sdk/premular/fields/plugins/SetPropertyEmptyTextPlugin"; import BindDisablePlugin from "@coremedia/studio-client.main.editor-components/sdk/premular/fields/plugins/BindDisablePlugin"; import UrlPropertyFieldBase from "./UrlPropertyFieldBase"; import PropertyFieldExample_properties from "./PropertyFieldExample_properties"; interface UrlPropertyFieldConfig extends Config<UrlPropertyFieldBase>, Partial<Pick<UrlPropertyField, "readOnly" | "hideIssues" >> { } class UrlPropertyField extends UrlPropertyFieldBase { declare Config: UrlPropertyFieldConfig; constructor(config: Config<UrlPropertyField> = null) { super((()=> ConfigUtils.apply(Config(UrlPropertyField, { items: [ Config(TextField, { itemId: "urlTextField", name: "properties." + this.propertyName, plugins: [ Config(PropertyFieldPlugin, { propertyName: config.propertyName, }), Config(SetPropertyLabelPlugin, { bindTo: config.bindTo, propertyName: config.propertyName, }), Config(SetPropertyEmptyTextPlugin, { bindTo: config.bindTo, propertyName: config.propertyName, }), Config(BindDisablePlugin, { bindTo: config.bindTo, }), Config(BindPropertyPlugin, { bindTo: config.bindTo.extendBy( 'properties', config.propertyName ), ifUndefined: "", bidirectional: true, }), ] }), Config(Button, { itemId: "urlOpenButton", text: PropertyFieldExample_properties.UrlPropertyField_open_text, handler: bind(this, this.openFrame), }), ], }), config))()); } } export default UrlPropertyField;
The base class:
import {as} from "@jangaroo/runtime"; import Config from "@jangaroo/runtime/Config"; import Container from "@jangaroo/ext-ts/container/Container"; import ValueExpression from "@coremedia/studio-client.client-core/data/ValueExpression"; interface UrlPropertyFieldBaseConfig extends Config<Container>, Partial<Pick<UrlPropertyFieldBase, "bindTo" | "propertyName" >> { } class UrlPropertyFieldBase extends Container { declare Config: UrlPropertyFieldBaseConfig; constructor(config: Config<UrlPropertyFieldBase> = null) { super(config); } /** * A property path expression leading to the Bean whose property is edited. */ bindTo: ValueExpression = null; /** * The property of the Bean to bind in this field. */ propertyName: string = null; /** * Try to open a new window with the string currently stored in the property used as the URL. */ openFrame(): void { const url = as(this.bindTo.extendBy('properties', this.propertyName).getValue(), String); if (url) { window.open(url, 'externalLinkTarget'); } } } export default UrlPropertyFieldBase;
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 TypeScript file itself, it is good practice to separate out application code in a base class.
import { bind } from "@jangaroo/runtime"; import Config from "@jangaroo/runtime/Config"; import Button from "@jangaroo/ext-ts/button/Button"; Config(Button, { itemId: "urlOpenButton", text: "...", handler: bind(this, this.openFrame), })
Example 9.30. Using a base class method