define([
'components.dt/js/api/ComponentProviderRegistry',
'components.dt/js/api/constants/Collection',
'components.dt/js/api/constants/EntityDetail',
'components.dt/js/api/constants/Link',
'components.dt/js/api/constants/Property',
'components.dt/js/creators/ViewComposer',
'components.dt/js/creators/impl/ButtonCreator',
'components.dt/js/creators/impl/ComboBoxCreator',
'components.dt/js/creators/impl/DateInputCreator',
'components.dt/js/creators/impl/DateTimeInputCreator',
'components.dt/js/creators/impl/EmailInputCreator',
'components.dt/js/creators/impl/ImageCreator',
'components.dt/js/creators/impl/LinkCreator',
'components.dt/js/creators/impl/ListCreator',
'components.dt/js/creators/impl/NumberInputCreator',
'components.dt/js/creators/impl/ParagraphCreator',
'components.dt/js/creators/impl/PropertyCreator',
'components.dt/js/creators/impl/RichTextCreator',
'components.dt/js/creators/impl/TableCreator',
'components.dt/js/creators/impl/TextAreaCreator',
'components.dt/js/creators/impl/TextInputCreator',
'components.dt/js/creators/impl/TimeInputCreator',
'components.dt/js/creators/impl/URLInputCreator',
'pagedesigner.dt/js/grid/GridOperations',
'pages.dt/js/api/Pages',
'pages.dt/js/api/Properties',
'pages.dt/js/api/View',
'pages.dt/js/api/ViewType',
'viewmodel/js/api/ArchetypeFactory',
'viewmodel/js/api/ArchetypeType',
'viewmodel.dt/js/api/ArchetypeUtils'
], function (
componentProviderRegistry,
Collection,
EntityDetail,
Link,
Property,
ViewComposer,
ButtonCreator,
ComboBoxCreator,
DateInputCreator,
DateTimeInputCreator,
EmailInputCreator,
ImageCreator,
LinkCreator,
ListCreator,
NumberInputCreator,
ParagraphCreator,
PropertyCreator,
RichTextCreator,
TableCreator,
TextAreaCreator,
TextInputCreator,
TimeInputCreator,
URLInputCreator,
GridOperations,
Pages,
Properties,
View,
ViewType,
ArchetypeFactory,
ArchetypeType,
ArchetypeUtils
) {
'use strict';
/**
* Helper class for component Creators providing various methods for
* creating views for the associated page. {@link components.dt/js/spi/creators/Creator Creator}
* implementors should create any view instances through this class instead
* of trying to instantiate {@link pages.dt/js/api/View View}s on their own.
*
* <p>Start with acquiring an instance with {@link components.dt/js/api/ComponentFactory.create ComponentFactory.create},
* then you can call its instance methods to create various built-in components.</p>
*
* @AbcsExtension stable
* @exports components.dt/js/api/ComponentFactory
* @param {pages.dt/js/api/Page} page page you will create components for.
* @version 16.3.5
* @constructor
* @private
*/
var ComponentFactory = function (page) {
AbcsLib.checkDefined(page, 'page');
AbcsLib.checkThis(this);
this._page = page;
};
ComponentFactory.ERROR_EXPECTED_LIST = 'Expecting a list view.';
ComponentFactory.ERROR_CREATOR_NOT_FOUND = function (type) {
return 'Component creator for \'' + type + '\' not found.';
};
ComponentFactory._ERROR_LINK_UNKNOWN_TARGET_TYPE = function (type) {
return 'Unknown link target type: \'' + type + '\'.';
};
ComponentFactory._ERROR_EMPTY_PROPERTIES = function (parameterName) {
return 'At least one property must be set for \'' + parameterName + '\'';
};
/**
* Factory create method returning an instance of this class.
*
* @AbcsExtension stable
* @static
* @param {pages.dt/js/api/Page} page page you will create components for.
* @returns {components.dt/js/api/ComponentFactory}
* @version 16.3.5
*/
ComponentFactory.create = function (page) {
AbcsLib.checkDefined(page, 'page');
return new ComponentFactory(page);
};
ComponentFactory.prototype.createButton = function (createContext) {
return new ButtonCreator().createView(this._page, undefined, createContext);
};
/**
* Creates a text input component with properties set to the defaults passed in
* the createContext.
*
* @AbcsExtension unstable
* @param {Object} createContext create context with default component
* properties to set when the component is created.
* @param {viewmodel/js/api/Archetype} createContext.archetype bound archetype instance
* @param {entity/js/api/Property} createContext.boundProperty bound entity field instance
* @param {String} [createContext.label] input component's label text
* @param {String} [createContext.labelPosition] input component's label position.
* Choose one of {@link components.dt/js/api/constants/Input.LabelPosition Input.LabelPosition}
* @param {String} [createContext.placeholderText] placeholderText text value.
* @param {Boolean} [createContext.readOnly] flag marking the input component as read-only
* @param {String} [createContext.helpDefinition] text displayed as the help tooltip
* next to the component's label.
* @param {String} [createContext.helpSource] URL of a resource with more detailed help
* about the component. The URL will be opened when the help icon next to the help
* icon next to the component's label is clicked.
*
* @returns {pages.dt/js/api/View} created text input view
*
* @example <caption>Create a required component bound to a property of an entity archetype</caption>
* var componentFactory = ComponentFactory.create(activePage);
* var component = componentFactory.createTextInput({
* label: 'LABEL',
* labelPosition: Link.LabelPosition.LEFT,
* archetype: archetypeInstance,
* boundProperty: boundPropertyInstance,
* placeholderText: 'Enter value',
* required: true,
* });
*
* @example <caption>Create a component bound to a property of an entity archetype
* with clickable help icon opening a URL with detailed help.</caption>
* var componentFactory = ComponentFactory.create(activePage);
* var component = componentFactory.createTextInput({
* archetype: archetypeInstance,
* boundProperty: boundPropertyInstance,
* helpDefinition: 'This is help, click to see more',
* helpSource: 'http://docs.oracle.com/'
* });
*/
ComponentFactory.prototype.createTextInput = function (createContext) {
AbcsLib.checkParameterCount(1);
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['archetype', 'boundProperty', 'label',
'labelPosition', 'placeholderText', 'readOnly', 'required', 'helpDefinition', 'helpSource']);
AbcsLib.checkDefined(createContext.archetype, 'createContext.archetype');
AbcsLib.checkDefined(createContext.boundProperty, 'createContext.boundProperty');
return new TextInputCreator().createView(this._page, undefined, createContext);
};
/**
* Creates a date input view with properties set to the defaults passed in
* the createContext.
*
* @AbcsExtension unstable
* @param {Object} createContext create context with default component
* properties to set when the view is created.
* @param {viewmodel/js/api/Archetype} createContext.archetype bound archetype instance
* @param {entity/js/api/Property} createContext.boundProperty bound entity field instance
* @param {String} [createContext.label] input component's label text
* @param {String} [createContext.labelPosition] input component's label position.
* Choose one of {@link components.dt/js/api/constants/Input.LabelPosition Input.LabelPosition}
* @param {String} [createContext.placeholderText] placeholderText text value.
* @param {Boolean} [createContext.readOnly] flag marking the input component as read-only
* @param {String} [createContext.helpDefinition] text displayed as the help tooltip
* next to the component's label.
* @param {String} [createContext.helpSource] URL of a resource with more detailed help
* about the component. The URL will be opened when the help icon next to the help
* icon next to the component's label is clicked.
*
* @returns {pages.dt/js/api/View} created date input view
*/
ComponentFactory.prototype.createDateInput = function (createContext) {
AbcsLib.checkParameterCount(1);
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['archetype', 'boundProperty', 'label',
'labelPosition', 'placeholderText', 'readOnly', 'required', 'helpDefinition', 'helpSource']);
AbcsLib.checkDefined(createContext.archetype, 'createContext.archetype');
AbcsLib.checkDefined(createContext.boundProperty, 'createContext.boundProperty');
return new DateInputCreator().createView(this._page, undefined, createContext);
};
/**
* Creates a date-time input view with properties set to the defaults passed in
* the createContext.
*
* @AbcsExtension unstable
* @param {Object} createContext create context with default component
* properties to set when the view is created.
* @param {viewmodel/js/api/Archetype} createContext.archetype bound archetype instance
* @param {entity/js/api/Property} createContext.boundProperty bound entity field instance
* @param {String} [createContext.label] input component's label text
* @param {String} [createContext.labelPosition] input component's label position.
* Choose one of {@link components.dt/js/api/constants/Input.LabelPosition Input.LabelPosition}
* @param {String} [createContext.placeholderText] placeholderText text value.
* @param {Boolean} [createContext.readOnly] flag marking the input component as read-only
* @param {String} [createContext.helpDefinition] text displayed as the help tooltip
* next to the component's label.
* @param {String} [createContext.helpSource] URL of a resource with more detailed help
* about the component. The URL will be opened when the help icon next to the help
* icon next to the component's label is clicked.
*
* @returns {pages.dt/js/api/View} created datetime input view
*/
ComponentFactory.prototype.createDateTimeInput = function (createContext) {
AbcsLib.checkParameterCount(1);
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['archetype', 'boundProperty', 'label',
'labelPosition', 'placeholderText', 'readOnly', 'required', 'helpDefinition', 'helpSource']);
AbcsLib.checkDefined(createContext.archetype, 'createContext.archetype');
AbcsLib.checkDefined(createContext.boundProperty, 'createContext.boundProperty');
return new DateTimeInputCreator().createView(this._page, undefined, createContext);
};
/**
* Creates a time input view with properties set to the defaults passed in
* the createContext.
*
* @AbcsExtension unstable
* @param {Object} createContext create context with default component
* properties to set when the view is created.
* @param {viewmodel/js/api/Archetype} createContext.archetype bound archetype instance
* @param {entity/js/api/Property} createContext.boundProperty bound entity field instance
* @param {String} [createContext.label] input component's label text
* @param {String} [createContext.labelPosition] input component's label position.
* Choose one of {@link components.dt/js/api/constants/Input.LabelPosition Input.LabelPosition}
* @param {String} [createContext.placeholderText] placeholderText text value.
* @param {Boolean} [createContext.readOnly] flag marking the input component as read-only
* @param {String} [createContext.helpDefinition] text displayed as the help tooltip
* next to the component's label.
* @param {String} [createContext.helpSource] URL of a resource with more detailed help
* about the component. The URL will be opened when the help icon next to the help
* icon next to the component's label is clicked.
*
* @returns {pages.dt/js/api/View} created time view
*/
ComponentFactory.prototype.createTimeInput = function (createContext) {
AbcsLib.checkParameterCount(1);
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['archetype', 'boundProperty', 'label',
'labelPosition', 'placeholderText', 'readOnly', 'required', 'helpDefinition', 'helpSource']);
AbcsLib.checkDefined(createContext.archetype, 'createContext.archetype');
AbcsLib.checkDefined(createContext.boundProperty, 'createContext.boundProperty');
return new TimeInputCreator().createView(this._page, undefined, createContext);
};
/**
* Creates a number input view with properties set to the defaults passed in
* the createContext.
*
* @AbcsExtension unstable
* @param {Object} createContext create context with default component
* properties to set when the view is created.
* @param {viewmodel/js/api/Archetype} createContext.archetype bound archetype instance
* @param {entity/js/api/Property} createContext.boundProperty bound entity field instance
* @param {String} [createContext.label] input component's label text
* @param {String} [createContext.labelPosition] input component's label position.
* Choose one of {@link components.dt/js/api/constants/Input.LabelPosition Input.LabelPosition}
* @param {String} [createContext.placeholderText] placeholderText text value.
* @param {Boolean} [createContext.readOnly] flag marking the input component as read-only
* @param {String} [createContext.helpDefinition] text displayed as the help tooltip
* next to the component's label.
* @param {String} [createContext.helpSource] URL of a resource with more detailed help
* about the component. The URL will be opened when the help icon next to the help
* icon next to the component's label is clicked.
*
* @returns {pages.dt/js/api/View} created number view
*/
ComponentFactory.prototype.createNumberInput = function (createContext) {
AbcsLib.checkParameterCount(1);
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['archetype', 'boundProperty', 'label',
'labelPosition', 'placeholderText', 'readOnly', 'required', 'helpDefinition', 'helpSource']);
AbcsLib.checkDefined(createContext.archetype, 'createContext.archetype');
AbcsLib.checkDefined(createContext.boundProperty, 'createContext.boundProperty');
return new NumberInputCreator().createView(this._page, undefined, createContext);
};
/**
* Creates an email input view with properties set to the defaults passed in
* the createContext.
*
* @AbcsExtension unstable
* @param {Object} createContext create context with default component
* properties to set when the view is created.
* @param {viewmodel/js/api/Archetype} createContext.archetype bound archetype instance
* @param {entity/js/api/Property} createContext.boundProperty bound entity field instance
* @param {String} [createContext.label] input component's label text
* @param {String} [createContext.labelPosition] input component's label position.
* Choose one of {@link components.dt/js/api/constants/Input.LabelPosition Input.LabelPosition}
* @param {String} [createContext.placeholderText] placeholderText text value.
* @param {Boolean} [createContext.readOnly] flag marking the input component as read-only
* @param {String} [createContext.helpDefinition] text displayed as the help tooltip
* next to the component's label.
* @param {String} [createContext.helpSource] URL of a resource with more detailed help
* about the component. The URL will be opened when the help icon next to the help
* icon next to the component's label is clicked.
*
* @returns {pages.dt/js/api/View} created email view
*/
ComponentFactory.prototype.createEmailInput = function (createContext) {
AbcsLib.checkParameterCount(1);
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['archetype', 'boundProperty', 'label',
'labelPosition', 'placeholderText', 'readOnly', 'required', 'helpDefinition', 'helpSource']);
AbcsLib.checkDefined(createContext.archetype, 'createContext.archetype');
AbcsLib.checkDefined(createContext.boundProperty, 'createContext.boundProperty');
return new EmailInputCreator().createView(this._page, undefined, createContext);
};
/**
* Creates a URL input view with properties set to the defaults passed in
* the createContext.
*
* @AbcsExtension unstable
* @param {Object} createContext create context with default component
* properties to set when the view is created.
* @param {viewmodel/js/api/Archetype} createContext.archetype bound archetype instance
* @param {entity/js/api/Property} createContext.boundProperty bound entity field instance
* @param {String} [createContext.label] input component's label text
* @param {String} [createContext.labelPosition] input component's label position.
* Choose one of {@link components.dt/js/api/constants/Input.LabelPosition Input.LabelPosition}
* @param {String} [createContext.placeholderText] placeholderText text value.
* @param {Boolean} [createContext.readOnly] flag marking the input component as read-only
* @param {String} [createContext.helpDefinition] text displayed as the help tooltip
* next to the component's label.
* @param {String} [createContext.helpSource] URL of a resource with more detailed help
* about the component. The URL will be opened when the help icon next to the help
* icon next to the component's label is clicked.
*
* @returns {pages.dt/js/api/View} created URL input view
*/
ComponentFactory.prototype.createURLInput = function (createContext) {
AbcsLib.checkParameterCount(1);
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['archetype', 'boundProperty', 'label',
'labelPosition', 'placeholderText', 'readOnly', 'required', 'helpDefinition', 'helpSource']);
AbcsLib.checkDefined(createContext.archetype, 'createContext.archetype');
AbcsLib.checkDefined(createContext.boundProperty, 'createContext.boundProperty');
return new URLInputCreator().createView(this._page, undefined, createContext);
};
/**
* Creates a paragraph component with properties set to the defaults passed
* in the createContext.
*
* @AbcsExtension unstable
* @param {Object} createContext create context with default component
* properties to set when the view is created.
* @param {String} [createContext.text] default textual content of the paragraph.
* @param {viewmodel/js/api/Archetype} [createContext.archetype] optional bound archetype instance.
* When not specified the paragraph will stay unbound and static.
* @param {entity/js/api/Property} createContext.boundProperty optional bound entity field instance.
* When not specified the paragraph will stay unbound and static.
* @param {String[]} [createContext.styleFormat] optional formatting options.
* Can be chosen from {@link components.dt/js/api/constants/Paragraph Paragraph} predefined
* options.
* @param {String} [createContext.styleSize] optional font size options.
* Can be chosen from {@link components.dt/js/api/constants/Paragraph Paragraph} predefined
* options.
*
* @returns {pages.dt/js/api/View} created paragraph component's view
*/
ComponentFactory.prototype.createParagraph = function (createContext) {
AbcsLib.checkParameterCount(1);
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['text', 'archetype', 'boundProperty', 'styleFormat', 'styleSize']);
if (createContext.styleFormat) {
AbcsLib.checkDataType(createContext.styleFormat, AbcsLib.Type.ARRAY);
}
return new ParagraphCreator().createView(this._page, undefined, createContext);
};
/**
* Create a Rich Text component.
*
* @AbcsExtension unstable
*
* @param {object} createContext - Create context with default Rich Text
* properties to set when the view is created.
* @param {viewmodel/js/api/Archetype} createContext.archetype - Bound archetype instance.
* @param {entity/js/api/Property} createContext.boundProperty - Bound entity field instance.
* @param {boolean} [createContext.readOnly] - Flag marking the rich text as read-only.
* @param {boolean} [createContext.pairView] - Flag to create as pair view (label + rich text).
*
* @returns {pages.dt/js/api/View} Created Rich Text component's view.
*/
ComponentFactory.prototype.createRichText = function (createContext) {
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkDefined(createContext.archetype, 'createContext.archetype');
AbcsLib.checkDefined(createContext.boundProperty, 'createContext.boundProperty');
// Backward compatibility: If createContext.pairView is undefined, double
// negation converts it to false (no pair view), which was the default
// behavior in previous versions.
return new RichTextCreator().createView(this._page, undefined, createContext, !!createContext.pairView);
};
/**
* Creates a text area component with properties set to the defaults passed in
* the createContext.
*
* @AbcsExtension unstable
* @param {Object} createContext create context with default component
* properties to set when the component is created.
* @param {viewmodel/js/api/Archetype} [createContext.archetype] bound archetype instance
* @param {entity/js/api/Property} [createContext.boundProperty] bound entity field instance
* @param {String} [createContext.label] input component's label text
* @param {String} [createContext.labelPosition] input component's label position.
* Choose one of {@link components.dt/js/api/constants/Input.LabelPosition Input.LabelPosition}
* @param {String} [createContext.placeholderText] placeholderText text value.
* @param {Boolean} [createContext.readOnly] flag marking the input component as read-only
* @param {String} [createContext.helpDefinition] text displayed as the help tooltip
* next to the component's label.
* @param {String} [createContext.helpSource] URL of a resource with more detailed help
* about the component. The URL will be opened when the help icon next to the help
* icon next to the component's label is clicked.
* @param {Number} [createContext.rows] number of rows the text area should occupy
* by default.
*
* @returns {pages.dt/js/api/View} created text input view
*/
ComponentFactory.prototype.createTextArea = function (createContext) {
AbcsLib.checkParameterCount(1);
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['archetype', 'boundProperty', 'label',
'labelPosition', 'placeholderText', 'readOnly', 'required', 'helpDefinition', 'helpSource', 'rows']);
if (createContext.rows) {
AbcsLib.checkDataType(createContext.rows, AbcsLib.Type.NUMBER);
}
return new TextAreaCreator().createView(this._page, undefined, createContext);
};
/**
* Creates a combo box view with properties set to the defaults passed in
* the createContext.
*
* @AbcsExtension unstable
* @param {Object} createContext create context with default combo box
* properties to set when the view is created.
* @param {viewmodel/js/api/Archetype} createContext.archetype bound archetype instance
* @param {entity/js/api/Property} createContext.boundProperty bound entity field instance
* @param {String} [createContext.label] combo box label text
* @param {String} [createContext.labelPosition] combo box's label position.
* Choose one of {@link components.dt/js/api/constants/Input.LabelPosition Input.LabelPosition}
* @param {String} [createContext.placeholderText] placeholderText text value.
* @param {entity/js/api/Property} [createContext.displayField] combo box's display field.
* This specifies what field from the referenced entity will be displayed
* as the textual value of the combo box items.
* @param {Boolean} [createContext.readOnly] flag marking the combo box as read-only
* @param {String} [createContext.helpDefinition] text displayed as the help tooltip
* next to the component's label.
* @param {String} [createContext.helpSource] URL of a resource with more detailed help
* about the component. The URL will be opened when the help icon next to the help
* icon next to the component's label is clicked.
*
* @returns {pages.dt/js/api/View} created combo box view
*/
ComponentFactory.prototype.createComboBox = function (createContext) {
AbcsLib.checkParameterCount(1);
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['archetype', 'boundProperty', 'label', 'labelPosition',
'placeholderText', 'displayField', 'readOnly', 'required', 'helpDefinition', 'helpSource']);
AbcsLib.checkDefined(createContext.archetype, 'createContext.archetype');
AbcsLib.checkDefined(createContext.boundProperty, 'createContext.boundProperty');
return new ComboBoxCreator().createView(this._page, undefined, createContext);
};
/**
* Creates a link component with properties set to the defaults passed in
* the createContext.
*
* @AbcsExtension unstable
* @param {Object} createContext create context with default link properties
* to set when the component is created.
* @param {String} createContext.label text of the link label
* @param {components.dt/js/api/constants/Link.LabelPosition} createContext.labelPosition positioning of the link label.
* @param {String} createContext.displayText textual representation of the link target displayed in the page
* @param {Object} createContext.target a target to open when the link is clicked. May be a page or a URL.
* @param {components.dt/js/api/constants/Link.TargetType} createContext.target.type type of the target, may be a URL or an ABCS page
* @param {pages.dt/js/api/Page} createContext.target.page an existing ABCS page opened when the link is clicked.
* It is required when <code>target.type</code> is set to {@link components.dt/js/api/constants/Link.TargetType Link.TargetType.PAGE}
* @param {String} createContext.target.url a URl to open when the link is clicked.
* It is required when <code>target.type</code> is set to {@link components.dt/js/api/constants/Link.TargetType Link.TargetType.URL}
*
* @returns {pages.dt/js/api/View} created combo box view
* @example <caption>Create a link component bound to a static URL</caption>
* var componentFactory = ComponentFactory.create(activePage);
* var linkComponent = componentFactory.createLink({
* label: 'LABEL',
* labelPosition: Link.LabelPosition.LEFT,
* displayText: 'My Custom Link',
* target: {
* type: Link.TargetType.URL,
* url: 'http://www.oracle.com'
* }
* });
* @example <caption>Create a link component bound to an existing ABCS page</caption>
* var componentFactory = ComponentFactory.create(activePage);
* var linkComponent = componentFactory.createLink({
* label: 'LABEL',
* labelPosition: Link.LabelPosition.LEFT,
* displayText: 'My Custom Link',
* target: {
* type: Link.TargetType.PAGE,
* page: existingABCSPageInstance
* }
* });
*/
ComponentFactory.prototype.createLink = function (createContext) {
AbcsLib.checkParameterCount(1);
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['label', 'labelPosition', 'displayText', 'target']);
AbcsLib.checkDefined(createContext.label, 'createContext.label');
AbcsLib.checkDataType(createContext.label, AbcsLib.Type.STRING);
AbcsLib.checkDefined(createContext.labelPosition, 'createContext.labelPosition');
AbcsLib.checkDefined(createContext.displayText, 'createContext.displayText');
AbcsLib.checkDataType(createContext.displayText, AbcsLib.Type.STRING);
AbcsLib.checkDefined(createContext.target, 'createContext.target');
AbcsLib.checkObjectLiteral(createContext.target, ['type', 'url', 'page']);
AbcsLib.checkDefined(createContext.target.type, 'createContext.target.type');
switch (createContext.target.type) {
case Link.TargetType.PAGE:
AbcsLib.checkDefined(createContext.target.page, 'createContext.target.page');
break;
case Link.TargetType.URL:
AbcsLib.checkDefined(createContext.target.url, 'createContext.target.url');
AbcsLib.checkDataType(createContext.target.url, AbcsLib.Type.STRING);
break;
default:
throw new Error(ComponentFactory._ERROR_LINK_UNKNOWN_TARGET_TYPE(createContext.target.type));
}
return new LinkCreator().createView(this._page, undefined, createContext);
};
/**
* Create an Image component.
*
* @AbcsExtension unstable
*
* @param {object} createContext - Create context with default Image component
* properties to set when the view is created.
* @param {Object} createContext.image specification of the image the component
* will dispay.
* @param {String} createContext.imagePath Path to the image, specifying this
* parameter will make the image component static.
* @param {String} [createContext.altText] Alternative textual representation
* when the image cannot be loaded.
*
* @returns {pages.dt/js/api/View} Created Image component's view.
* @example <caption>Create a built-in static image component</caption>
* // create a built-in image component
* var image = componentFactory.createImage({
* imagePath: 'package/path_to_resource.png',
* altText: 'ALTERNATE TEXT'
* });
*/
ComponentFactory.prototype.createImage = function (createContext) {
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['altText', 'imagePath']);
AbcsLib.checkDefined(createContext.imagePath, 'imagePath');
return new ImageCreator().createView(this._page, undefined, createContext);
};
ComponentFactory.prototype.createGrid = function (context) {
var Properties = require('pages.dt/js/api/Properties');
var properties;
properties = new Properties();
properties.setValue('designerIsDroppable', context.designerIsDroppable === false ? false : true);
//will not by default generate wrapping ABCS element, one of the consequence - the component can't be selected
properties.setValue('designerIsWrappable', context.designerIsDroppable === true ? true : false);
return this._page.getViewFactory().createView({
id: this._page.createViewId(ViewType.GRID),
type: ViewType.GRID,
properties: properties
});
};
ComponentFactory.prototype.createEntityDetail = function (context) {
// TODO deleter for ENTITY_DETAIL
var archetype = this._createArchetype(context[EntityDetail.ENTITY], !!context[EntityDetail.REUSE_ARCHETYPE]);
var form = this.createGrid(context);
form.setType(ViewType.ENTITY_DETAIL);
form.setArchetype(archetype);
return form;
};
ComponentFactory.prototype.createOneToOneEntityDetail = function (context) {
var parentArchetype;
var parentEntity = context.parentEntity;
if (!parentEntity) {
throw new Error('parentEntity was not set');
}
var page = this._page;
var viewModelDefinition = page.getViewModelDefinition();
viewModelDefinition.findArchetypesByType(ArchetypeType.ENTITY_DETAIL).forEach(function(candidateArchetype) {
if (candidateArchetype.getEntityId() === parentEntity.getId()) {
//found
parentArchetype = candidateArchetype;
}
});
if (!parentArchetype) {
throw new Error('in order to add ' + context[EntityDetail.ENTITY].getId() +
' to this page the page must already contain detail archetype for ' +
parentEntity.getId());
}
// TODO deleter for ENTITY_DETAIL
var archetype = this._createArchetype(context[EntityDetail.ENTITY], !!context[EntityDetail.REUSE_ARCHETYPE]);
var form = this.createGrid(context);
form.setType(ViewType.ENTITY_DETAIL);
form.setArchetype(archetype);
archetype.setMasterArchetype(parentArchetype.getInstancePath());
viewModelDefinition.refreshArchetype(archetype);
return form;
};
ComponentFactory.prototype.findListArchetypeFor = function (entity) {
ComponentFactory.findListArchetypeFor(entity, this._page);
};
ComponentFactory.prototype.findListArchetypeFor = function (entity, page) {
var listArchetype;
var viewModelDefinition = page.getViewModelDefinition();
viewModelDefinition.findArchetypesByType(ArchetypeType.LIST).forEach(function(candidateArchetype) {
if (candidateArchetype.getEntityId() === entity.getId()) {
//found
listArchetype = candidateArchetype;
}
});
if (listArchetype === undefined) {
throw new Error('in order to add Question query the page must alrady contain list archetype for answers');
}
return listArchetype;
};
ComponentFactory.prototype.findPageForListArchetype = function (entity) {
var listArchetypePage;
Pages.getPages().forEach(function (page) {
var viewModelDefinition = page.getViewModelDefinition();
viewModelDefinition.findArchetypesByType(ArchetypeType.LIST).forEach(function (candidateArchetype) {
if (candidateArchetype.getEntityId() === entity.getId()) {
//found
listArchetypePage = page;
}
});
});
if (listArchetypePage === undefined) {
throw new Error('in order to add Question query one page must already contain list archetype for answers');
}
return listArchetypePage;
};
/**
* Appends the component at the end of requested page.
* @param {pages.dt/js/api/Page} page page to modify
* @param {pages.dt/js/api/View} component component's top view to add to the page
* @param {Object} layoutConstraints layout constraints
* @param {Number} layoutConstraints.column zero-based column index (max 11)
* defining where to put the component in the pages's layout.
* @param {Number} layoutConstraints.width number of columns the component view
* is about to occupy.
*/
ComponentFactory.appendToPage = function (page, component, layoutConstraints) {
AbcsLib.checkParameterCount(3);
AbcsLib.checkDefined(page, 'page');
AbcsLib.checkDefined(component, 'component');
AbcsLib.checkDefined(layoutConstraints, 'layoutConstraints');
var view = page.getView();
var rowIndex = GridOperations.getLayout(view).length;
ComponentFactory.addChildView(view, component, {
row: rowIndex,
column: layoutConstraints.column || 0,
width: layoutConstraints.width,
createRow: true
});
};
ComponentFactory.prototype.createQuery = function (context) {
// TODO deleter for QUERY_FORM
var archetype = this._createArchetype(context[EntityDetail.ENTITY],
!!context[EntityDetail.REUSE_ARCHETYPE],
ArchetypeType.QUERY_DATA, {
queryName: 'something',
queryDescriptionId: context.query
});
var form = this.createGrid(context);
form.setType(ViewType.QUERY_FORM);
form.setArchetype(archetype);
return form;
};
/**
* Creates table component with predefined properties and bahaviour.
*
* @AbcsExtension unstable
*
* @param {Object} createContext properties defining the created table's
* bahaviour.
* @param {entity/js/api/Entity} createContext.entity entity the table will
* be bound to.
* @param {entity/js/api/Property[]} createContext.selectedProperties properties
* to show in the table. Pass at least one property as table with no columns
* cannot be created.
* @param {String} [createContext.caption] optional text used as the table's
* caption. While it is optional you should still set it to a non-empty text
* as filled table caption is one of the rules of accessibility.
* For now it's optional but will be required once official public API.
* @param {operation/js/api/Condition} [createContext.customCondition] optional
* condition that will be automatically used as the table's default query.
*
* @param {Object} [createContext.createAction] options defining how and if the create action
* is to be set up. When not set the create action will be set up as if
* {@link components.dt/js/api/constants/Table.ActionMode Table.ActionMode.DEFAULT}
* is set as <code>createAction.mode</code>.
* @param {components.dt/js/api/constants/Table.ActionMode} createContext.createAction.mode defines
* the way the create action is created.
* @param {pages.dt/js/api/Page} [createContext.createAction.page] required when <code>createAction.mode</code>
* is set to {@link components.dt/js/api/constants/Table.ActionMode Table.ActionMode.OPEN_PAGE}
* and represents the page to open when the action is invoked.
* @param {components.dt/js/api/ComponentFactory~createCollectionAction} [createContext.createAction.createAction]
* Required when <code>createAction.mode</code> is set to {@link components.dt/js/api/constants/Table.ActionMode Table.ActionMode.CUSTOM}
* and will be called when table creator is about to set up the action.
*
* @param {Object} [createContext.detailAction] options defining how and if the open detail action
* is to be set up. When not set the detail action will be set up as if
* {@link components.dt/js/api/constants/Table.ActionMode Table.ActionMode.DEFAULT}
* is set as <code>detailAction.mode</code>.
* @param {components.dt/js/api/constants/Table.ActionMode} createContext.detailAction.mode defines
* the way the open detail action is created.
* @param {pages.dt/js/api/Page} [createContext.detailAction.page] required when <code>detailAction.mode</code>
* is set to {@link components.dt/js/api/constants/Table.ActionMode Table.ActionMode.OPEN_PAGE}
* and represents the page to open when the action is invoked.
* @param {components.dt/js/api/ComponentFactory~createCollectionAction} [createContext.detailAction.createAction]
* Required when <code>detailAction.mode</code> is set to {@link components.dt/js/api/constants/Table.ActionMode Table.ActionMode.CUSTOM}
* and will be called when table creator is about to set up the action.
* @param {entity/js/api/Property} [createContext.detailAction.link] set up a column displaying
* this property as a link activating the action (opening the detail page).
*
* @param {Object} [createContext.deleteAction] options defining how and if the create action
* is to be set up. When not set the delete action will be set up as if
* {@link components.dt/js/api/constants/Table.ActionMode Table.ActionMode.DEFAULT}
* is set as <code>deleteAction.mode</code>.
* @param {components.dt/js/api/constants/Table.ActionMode} createContext.deleteAction.mode defines
* the way the delete action is created.
* <strong>Note that</strong> only {@link components.dt/js/api/constants/Table.ActionMode DEFAULT}
* and {@link components.dt/js/api/constants/Table.ActionMode NONE} are allowed
* for delete action.
*
* @param {Object} [createContext.editAction] options defining how and if the edit action
* is to be set up. When not set the edit action will be set up as if
* {@link components.dt/js/api/constants/Table.ActionMode Table.ActionMode.DEFAULT}
* is set as <code>editAction.mode</code>.
* @param {components.dt/js/api/constants/Table.ActionMode} createContext.editAction.mode defines
* the way the edit action is created.
* @param {pages.dt/js/api/Page} [createContext.editAction.page] required when <code>editAction.mode</code>
* is set to {@link components.dt/js/api/constants/Table.ActionMode Table.ActionMode.OPEN_PAGE}
* and represents the page to open when the action is invoked.
* @param {components.dt/js/api/ComponentFactory~createCollectionAction} [createContext.editAction.createAction]
* Required when <code>editAction.mode</code> is set to {@link components.dt/js/api/constants/Table.ActionMode Table.ActionMode.CUSTOM}
* and will be called when table creator is about to set up the action.
* @param {entity/js/api/Property} [createContext.editAction.link] set up a column displaying
* this property as a link activating the action (opening the edit page).
* @returns {pages.dt/js/api/View} created table view
* @example <caption>Create simple table</caption>
* var entity = Abcs.Entities().findById('my.custom.bop.Employee');
* var nameProperty = entity.getProperty('firstname');
* var lastnameProperty = entity.getProperty('lastname');
* // create table for employee BO
* // with most of the settings set to defaults
* var table = factory.createTable({
* entity: Abcs.Entities().findById('my.custom.bop.Employee'),
* selectedProperties: [nameProperty, lastnameProperty],
* caption: 'Employee Table'
* });
*
* @example <caption>Create table with customized actions</caption>
* var entity = Abcs.Entities().findById('my.custom.bop.Employee');
* var nameProperty = entity.getProperty('firstname');
* var lastnameProperty = entity.getProperty('lastname');
* // create table for employee BO
* var table = factory.createTable({
* entity: Abcs.Entities().findById('my.custom.bop.Employee'),
* selectedProperties: [nameProperty, lastnameProperty],
* caption: 'Employee Table',
* // neither create action or create page will not be generated
* createAction: {
* mode: Table.ActionMode.NONE
* },
* // edit action will open not default but a customized
* // 'myCustomEditPage' page
* editAction: {
* mode: Table.ActionMode.OPEN_PAGE,
* page: Pages.getPage('myCustomEditPage')
* },
* // detail action will open default detail page and the lastnameProperty
* // column will render as a link invoking the action on click
* detailAction: {
* mode: Table.ActionMode.DEFAULT,
* link: lastnameProperty
* }
* });
*/
// TODO createContext.caption should not be optional i guess
ComponentFactory.prototype.createTable = function (createContext) {
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['entity', 'selectedProperties', 'linkDetail', 'linkEdit',
'sortingEnabled', 'sortingProperty', 'sortingOrder',
'filterEnabled', 'filterProperty', 'advancedSearchEnabled',
'createAction', 'detailAction', 'editAction', 'deleteAction',
'caption', 'customCondition'
]);
AbcsLib.checkDefined(createContext.entity, 'createContext.entity');
AbcsLib.checkDefined(createContext.selectedProperties, 'createContext.selectedProperties');
if (!createContext.selectedProperties.length) {
throw new Error(ComponentFactory._ERROR_EMPTY_PROPERTIES('createContext.selectedProperties'));
}
if (createContext.caption) {
AbcsLib.checkDataType(createContext.caption, AbcsLib.Type.STRING);
}
ComponentFactory._upgradeCollectionContextInput(createContext);
ComponentFactory._checkCollectionActionsInput(createContext);
return new TableCreator().createView(this._page, undefined, createContext);
};
/**
* Creates list component with predefined properties and bahaviour.
*
* @AbcsExtension unstable
*
* @param {Object} createContext properties defining the created list's
* bahaviour.
* @param {entity/js/api/Entity} createContext.entity entity the list will
* be bound to.
* @param {String} createContext.layout layout to select for the list component,
* should be one of {@link components.dt/js/api/constants/List.LayoutMode List.LayoutMode}.
* @param {operation/js/api/Condition} [createContext.customCondition] optional
* condition that will be automatically used as the list's default query.
*
* @param {Object} [createContext.createAction] options defining how and if the create action
* is to be set up. When not set the create action will be set up as if
* {@link components.dt/js/api/constants/List.ActionMode List.ActionMode.DEFAULT}
* is set as <code>createAction.mode</code>.
* @param {components.dt/js/api/constants/List.ActionMode} createContext.createAction.mode defines
* the way the create action is created.
* @param {pages.dt/js/api/Page} [createContext.createAction.page] required when <code>createAction.mode</code>
* is set to {@link components.dt/js/api/constants/List.ActionMode List.ActionMode.OPEN_PAGE}
* and represents the page to open when the action is invoked.
* @param {components.dt/js/api/ComponentFactory~createCollectionAction} [createContext.createAction.createAction]
* Required when <code>createAction.mode</code> is set to {@link components.dt/js/api/constants/List.ActionMode List.ActionMode.CUSTOM}
* and will be called when list creator is about to set up the action.
*
* @param {Object} [createContext.detailAction] options defining how and if the open detail action
* is to be set up. When not set the detail action will be set up as if
* {@link components.dt/js/api/constants/List.ActionMode List.ActionMode.DEFAULT}
* is set as <code>detailAction.mode</code>.
* @param {components.dt/js/api/constants/List.ActionMode} createContext.detailAction.mode defines
* the way the open detail action is created.
* @param {pages.dt/js/api/Page} [createContext.detailAction.page] required when <code>detailAction.mode</code>
* is set to {@link components.dt/js/api/constants/List.ActionMode List.ActionMode.OPEN_PAGE}
* and represents the page to open when the action is invoked.
* @param {components.dt/js/api/ComponentFactory~createCollectionAction} [createContext.detailAction.createAction]
* Required when <code>detailAction.mode</code> is set to {@link components.dt/js/api/constants/List.ActionMode List.ActionMode.CUSTOM}
* and will be called when list creator is about to set up the action.
* @param {entity/js/api/Property} [createContext.detailAction.link] set up a column displaying
* this property as a link activating the action (opening the detail page).
*
* @param {Object} [createContext.deleteAction] options defining how and if the create action
* is to be set up. When not set the delete action will be set up as if
* {@link components.dt/js/api/constants/List.ActionMode List.ActionMode.DEFAULT}
* is set as <code>deleteAction.mode</code>.
* @param {components.dt/js/api/constants/List.ActionMode} createContext.deleteAction.mode defines
* the way the delete action is created.
* <strong>Note that</strong> only {@link components.dt/js/api/constants/List.ActionMode DEFAULT}
* and {@link components.dt/js/api/constants/List.ActionMode NONE} are allowed
* for delete action.
*
* @param {Object} [createContext.editAction] options defining how and if the edit action
* is to be set up. When not set the edit action will be set up as if
* {@link components.dt/js/api/constants/List.ActionMode List.ActionMode.DEFAULT}
* is set as <code>editAction.mode</code>.
* @param {components.dt/js/api/constants/List.ActionMode} createContext.editAction.mode defines
* the way the edit action is created.
* @param {pages.dt/js/api/Page} [createContext.editAction.page] required when <code>editAction.mode</code>
* is set to {@link components.dt/js/api/constants/List.ActionMode List.ActionMode.OPEN_PAGE}
* and represents the page to open when the action is invoked.
* @param {components.dt/js/api/ComponentFactory~createCollectionAction} [createContext.editAction.createAction]
* Required when <code>editAction.mode</code> is set to {@link components.dt/js/api/constants/List.ActionMode List.ActionMode.CUSTOM}
* and will be called when list creator is about to set up the action.
* @param {entity/js/api/Property} [createContext.editAction.link] set up a column displaying
* this property as a link activating the action (opening the edit page).
* @returns {pages.dt/js/api/View} created list view
* @example <caption>Create simple list</caption>
* var entity = Abcs.Entities().findById('my.custom.bop.Employee');
* var nameProperty = entity.getProperty('firstname');
* var lastnameProperty = entity.getProperty('lastname');
* // create list for employee BO with most of the settings set to defaults
* var list = factory.createList({
* entity: Abcs.Entities().findById('my.custom.bop.Employee'),
* layout: List.Layout.ONE_COLUMN
* });
*
* @example <caption>Create list with customized actions</caption>
* var entity = Abcs.Entities().findById('my.custom.bop.Employee');
* var nameProperty = entity.getProperty('firstname');
* var lastnameProperty = entity.getProperty('lastname');
* // create list for employee BO with most of the settings set to defaults
* var list = factory.createList({
* entity: Abcs.Entities().findById('my.custom.bop.Employee'),
* layout: List.LayoutMode.ONE_COLUMN,
* // neither create action or create page will not be generated
* createAction: {
* mode: List.ActionMode.NONE
* },
* // edit action will open not default but a customized
* // 'myCustomEditPage' page
* editAction: {
* mode: List.ActionMode.OPEN_PAGE,
* page: Pages.getPage('myCustomEditPage')
* }
* });
*/
ComponentFactory.prototype.createList = function (createContext) {
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['entity', 'layout', 'linkDetail', 'linkEdit',
'sortingEnabled', 'sortingProperty', 'sortingOrder',
'filterEnabled', 'filterProperty', 'advancedSearchEnabled',
'createActionDetail', 'selectedProperties',
'createAction', 'detailAction', 'editAction', 'deleteAction',
'customCondition'
]);
AbcsLib.checkDefined(createContext.entity, 'createContext.entity');
AbcsLib.checkDefined(createContext.layout, 'createContext.layout');
ComponentFactory._upgradeCollectionContextInput(createContext);
ComponentFactory._checkCollectionActionsInput(createContext);
var listView = new ListCreator().createView(this._page, undefined, createContext);
// temporary as a BW compatibility, will be removed once
if (createContext.detailAction && createContext.detailAction.link) {
listView._creator_api_link_detail = createContext.detailAction.link.getId();
} else if (createContext.editAction && createContext.editAction.link) {
listView._creator_api_link_edit = createContext.editAction.link.getId();
}
return listView;
};
/**
* Creates a list property component with properties set to the defaults passed in
* the createContext.
*
* @AbcsExtension unstable
* @param {pages.dt/js/api/View} listView instance of list view component as it was
* returned from {@link components.dt/js/api/ComponentFactory#createList ComponentFactory.createList}.
* @param {Object} createContext create context with default component
* properties to set when the component is created.
* @param {entity/js/api/Property} createContext.property instance of a BO
* field the view will be bound to.
* @param {String} [createContext.label] input component's label text
* @param {String} [createContext.labelPosition] input component's label position.
* Choose one of {@link components.dt/js/api/constants/Input.LabelPosition Input.LabelPosition}
* @param {String} [createContext.rendererComponent] special renderer that will
* be used when the component is building its DOM. By default the component
* renders a single-line text DOM element, but lets you specify a specific
* renderer such as multi-line text. The value should be one of renderers
* defined in {@link components.dt/js/api/constants/Property Property} and
* is specific to the property's type (will throw an error for unsupported
* renderer).
*
* Be careful when choosing the renderer and use proper enums based on the
* property's type:
*
* <ul>
* <li>{@link components.dt/js/api/constants/Property.TextRenderingComponentType Property.TextRenderingComponentType}
* for properties of type {@link entity/js/api/PropertyType.TEXT PropertyType.TEXT}</li>
* </ul>
*
* @returns {pages.dt/js/api/View} created list property view
*
* @example Create multi-line list property bound to incident's description field
* var incidentBO = Abcs.Entities().findById('my.custom.bop.Incident');
* var descriptionProperty = incidentBO.getproperty('description');
*
* // create new list view
* var listView = componentFactory.createList({
* entity: Abcs.Entities().findById('my.custom.bop.Employee'),
* layout: List.Layout.ONE_COLUMN
* });
*
* // create list property bound to description
* var descriptionView = componentFactory.createListProperty(listView, {
* boundProperty: descriptionProperty,
* rendererComponent: Property.TextRenderingComponentType.MULTI_LINE_TEXT
* });
*
* // add the view to the list into the first row
* componentFactory.addChildToList(list, descriptionView, {
* listColumn: 0,
* row: 0,
* column: 0,
* width: 6,
* createRow: true
* });
*/
ComponentFactory.prototype.createListProperty = function (listView, createContext) {
AbcsLib.checkParameterCount(arguments, 2);
AbcsLib.checkDefined(listView, 'listView');
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkObjectLiteral(createContext, ['boundProperty', 'property', 'label', 'labelPosition', 'rendererComponent']);
if (createContext.property) {
// BW compatibility
createContext.boundProperty = createContext.property;
}
AbcsLib.checkDefined(createContext.boundProperty, 'createContext.' + createContext.boundProperty);
if (listView.getType() !== ViewType.TOP_LIST_CONTAINER) {
throw new Error(ComponentFactory.ERROR_EXPECTED_LIST);
}
if (createContext.rendererComponent) {
Property.checkRenderer(createContext.boundProperty.getType(), createContext.rendererComponent);
}
createContext.property = createContext.boundProperty;
createContext.entity = listView.getEnclosingArchetype().getEntity();
if (listView._creator_api_link_detail === createContext.boundProperty.getId()) {
createContext.detailActionLink = true;
} else if (listView._creator_api_link_edit === createContext.boundProperty.getId()) {
createContext.editActionLink = true;
}
return new PropertyCreator().createView(this._page, listView, createContext);
};
ComponentFactory.prototype.createCustom = function (type, createContext) {
AbcsLib.checkDefined(type, 'type');
createContext = createContext || {};
var creator = componentProviderRegistry.findCreator(type);
if (!creator) {
throw new Error(ComponentFactory.ERROR_CREATOR_NOT_FOUND(type));
}
var view = creator.createView(this._page, undefined, createContext);
view.getProperties().setValue(View.MIN_WIDTH_KEY, creator.getOptions().minWidth);
return view;
};
ComponentFactory.prototype.addChildToList = function (listView, childView, layoutConstraints) {
AbcsLib.checkDefined(listView, 'listView');
AbcsLib.checkDefined(childView, 'childView');
AbcsLib.checkDefined(layoutConstraints, 'layoutConstraints');
AbcsLib.checkDefined(layoutConstraints.listColumn, 'layoutConstraints.listColumn');
var listRow = listView.findChildOfType(ViewType.LIST_ROW);
var listColumns = listRow.getChildren();
var container = listColumns[layoutConstraints.listColumn];
var viewComposer = new ViewComposer(childView);
viewComposer.composeViews(container, layoutConstraints);
};
/**
* Creates a generic view of given type with defined properties.
* <p>In custom Creators you should use this method to create your views
* instead of trying to construct View instances directly though their
* constructors.</p>
*
* @AbcsExtension stable
* @param {Object} createContext
* @param {String} createContext.displayName view display name, for example
* 'Text Field', 'Opportunity Table' etc.
* @param {String} createContext.type view type you want to create
* @param {Object} [createContext.properties] a map of view properties.
* <p>You do not have to construct view {@link pages.dt/js/api/Properties Properties}
* yourself, instead pass a simple key-value map of your view properties and
* the instance will be created and injected into the created view by this
* method automatically (and obtained later with {@link pages.dt/js/api/View#getProperties View.getProperties}).</p>
* @returns {pages.dt/js/api/View} created view
* @version 16.3.5
* @example <caption>How to create a view in my Creator</caption>
* Creator.prototype.createView = function (activePage) {
* var componentFactory = ComponentFactory.create(activePage);
* var properties = {
* myProp: 'prop value'
* };
*
* // create the view for this component
* var view = componentFactory.createView({
* displayName: 'My Custom Component',
* type: 'my.componentId',
* properties: properties
* });
*
* view.getProperties().setValue('myProp', 'modified prop value');
*
* return view;
* };
*/
ComponentFactory.prototype.createView = function (createContext) {
AbcsLib.checkDefined(createContext, 'createContext');
AbcsLib.checkDefined(createContext.displayName, 'createContext.displayName');
AbcsLib.checkDefined(createContext.type, 'createContext.type');
AbcsLib.checkObjectLiteral(createContext, ['displayName', 'type', 'properties']);
var properties = createContext.properties;
if (properties && (typeof properties.getKeys !== 'function' || typeof properties.getValue !== 'function')) {
properties = new Properties(properties);
}
var view = this._page.getViewFactory().createView({
id: this._page.createViewId(createContext.type),
displayName: createContext.displayName,
properties: properties,
type: createContext.type
});
return view;
};
/**
* Organizes two views into a hierarchy, i.e. adds <code>childView</code>
* as a child of <code>parentView</code>. In case the parent view is a container
* such as a panel or a grid, you should pass also the <code>layoutConstraints</code>
* to properly set the parent view's layout.
*
* @param {pages.dt/js/api/View} parentView parent view
* @param {pages.dt/js/api/View} childView child view to add into the parent.
* @param {Object} [layoutConstraints] layout constraints
* @param {Number} layoutConstraints.row zero-based row index defining where to
* put the child in the parent's layout
* @param {Number} layoutConstraints.column zero-based column index (max 11)
* defining where to put the child in the parent's layout.
* @param {Number} layoutConstraints.width number of columns the child view
* is about to occupy.
* @param {Boolean} [layoutConstraints.createRow] if set to <code>true</code>
* the child view will be added to a completely new row added at the row index.
* @example <caption>How to add child to a parent</caption>
* var parentView;
* var buttonView;
* // adds the button view as a child of the parent view without any layout
* ComponentFactory.addChildView(parentView, buttonView);
* @example <caption>How to add child to a container with layout</caption>
* var gridView;
* var buttonView;
*
* // will add the button to the third column of the third row in the panel
* // layout. The button will be stretched over two panel columns.
* ComponentFactory.addChildView(panelView, buttonView, {
* row: 2,
* column: 2,
* width: 2
* });
*
* // will create a new row above the previous third row inside the panel
* // and add the button to the third column of the created row. The button
* will be stretched over four panel columns.
* ComponentFactory.addChildView(panelView, buttonView, {
* row: 2,
* column: 2,
* width: 4,
* createRow: true
* });
*/
ComponentFactory.addChildView = function (parentView, childView, layoutConstraints) {
if (layoutConstraints) {
GridOperations.addView(parentView, childView, layoutConstraints);
} else {
parentView.addChild(childView);
}
};
ComponentFactory.prototype._createArchetype = function (entity, reuseExisting, archType, descriptorOptions) {
if (!archType) {
archType = ArchetypeType.ENTITY_DETAIL;
}
var page = this._page;
var viewModelDefinition = page.getViewModelDefinition();
var archetype;
if (reuseExisting) {
viewModelDefinition.findArchetypesByType(archType).forEach(function(candidateArchetype) {
if (candidateArchetype.getEntityId() === entity.getId()) {
//found
archetype = candidateArchetype;
}
});
}
if (!archetype) {
//create
var archetypeId = ArchetypeUtils.generateArchetypeId(entity, archType, viewModelDefinition);
var descriptor = {
id: archetypeId,
type: archType
};
if (descriptorOptions) {
descriptor = $.extend(descriptor, descriptorOptions);
}
archetype = ArchetypeFactory.create(entity, descriptor);
viewModelDefinition.addArchetype(archetype);
}
return archetype;
};
ComponentFactory._upgradeCollectionContextInput = function (createContext) {
if (createContext.createActionDetail) {
createContext.detailAction = createContext.detailAction || {
mode: Collection.ActionMode.CUSTOM,
createAction: createContext.createActionDetail
};
}
if (createContext.linkDetail) {
createContext.detailAction = createContext.detailAction || {
mode: Collection.ActionMode.DEFAULT
};
createContext.detailAction.link = createContext.linkDetail;
}
if (createContext.linkEdit) {
createContext.editAction = createContext.editAction || {
mode: Collection.ActionMode.DEFAULT
};
createContext.editAction.link = createContext.linkEdit;
}
};
ComponentFactory._checkCollectionActionInput = function (actionContext, prefix) {
AbcsLib.checkDefined(actionContext.mode, prefix + '.mode');
if (actionContext.mode === Collection.ActionMode.OPEN_PAGE) {
AbcsLib.checkDefined(actionContext.mode, prefix + '.page');
} else if (actionContext.mode === Collection.ActionMode.CUSTOM) {
AbcsLib.checkDefined(actionContext.createAction, prefix + '.createAction');
AbcsLib.checkDataType(actionContext.createAction, AbcsLib.Type.FUNCTION);
}
};
ComponentFactory._checkCollectionActionsInput = function (createContext) {
if (createContext.createAction) {
ComponentFactory._checkCollectionActionInput(createContext.createAction, 'createContext.createAction');
}
if (createContext.detailAction) {
ComponentFactory._checkCollectionActionInput(createContext.detailAction, 'createContext.detailAction');
}
if (createContext.editAction) {
ComponentFactory._checkCollectionActionInput(createContext.editAction, 'createContext.editAction');
}
};
/**
* Creates a business action invoked from a collection when user clicks on
* a link or selects the action from the popup menu.
* @AbcsExtension unstable
* @callback components.dt/js/api/ComponentFactory~createCollectionAction
* @param {viewmodel/js/api/Archetype} archetype instance of table archetype
* @return {BusinessCode} business code action
*/
var ContextBuilder = function () {
AbcsLib.checkThis(this);
this._context = {};
};
ContextBuilder.prototype.setProperty = function (propertyName, value) {
this._context[propertyName] = value;
return this;
};
ContextBuilder.prototype.build = function () {
return this._context;
};
ComponentFactory.ContextBuilder = ContextBuilder;
return ComponentFactory;
});