define([
'components.dt/js/spi/creators/Creator',
'components.dt/js/spi/creators/CreatorType'
], function (
Creator,
CreatorType
) {
'use strict';
/**
* Interface describing a lightweight Popup Creator raising a popup window
* right after a view is created and added to a page, intended to modify
* the view's properties before the create process finishes.
*
* <p>Interface for creators that show a popup for entering basic component
* properties (data binding, type, field name, label) when new component is to
* be created.</p>
*
* <p>The infrastructure first calls {@link components.dt/js/spi/creators/PopupCreator#createView createView}
* to create a view with default state and properties. When the view is created
* and added to the page {@link components.dt/js/spi/creators/PopupCreator#getDropPopupController getDropPopupController}
* is called to obtain a {@link components.dt/js/spi/creators/DropPopupController DropPopupController}
* instance. The infrastructure finally raises a popup with data provided by
* the returned DropPopupController. It's up to the implementor to ensure
* the view is properly updated with any modifications done inside the popup.</p>
*
* <p>Even though ABCS by default raises a popup to customize the created
* view, the creator may be called through the {@link components.dt/js/api/ComponentFactory Creator API}
* by other creators to include the view into their own composed view hierarchy
* in which case the popup will not be opened and the creator ({@link components.dt/js/spi/creators/PopupCreator#createView createView})
* is obliged to return a full working view based on the passed <code>createContext</code>
* containing the default properties. See the example below for demonstation.</p>
*
* <p>You are obliged to implement:</p>
* <ul>
* <li>{@link components.dt/js/spi/creators/PopupCreator#createView createView}
* to create the default view. The returned view should be as complete as
* possible as the method may be called through the {@link components.dt/js/api/ComponentFactory Creator API} by other creators
* without the popup even being raised.</li>
* <li>{@link components.dt/js/spi/creators/PopupCreator#getDropPopupController getDropPopupController}
* to return an instance of {@link components.dt/js/spi/creators/DropPopupController DropPopupController}
* providing the popup's view model, HTML markup and {@link components.dt/js/spi/creators/DropPopupController.DropCustomizer DropCustomizer}
* instance.</li>
* <li>{@link components.dt/js/spi/creators/PopupCreator#getType getType} to
* specify the creator is a popup creator</li>
* </ul>
*
* @AbcsExtension stable
* @version 16.3.5
* @exports components.dt/js/spi/creators/PopupCreator
* @augments components.dt/js/spi/creators/Creator
* @constructor
* @private
* @example
* <caption>HTML markup for the popup</caption>
* <div>
* <label for="componentdropCustomizer-label">Text</label>
* <input id="componentdropCustomizer-label" type="text"
* placeholder="Enter Text" data-bind="ojComponent: {
* component: 'ojInputText',
* value: text
* }">
* </div>
* <div>
* <button data-bind="ojComponent: {
* component: 'ojButton',
* label: 'Finish'
* }, click: finish">
* </button>
* <button data-bind="ojComponent: {
* component: 'ojButton',
* label: 'Cancel'
* }, click: cancel">
* </button>
* </div>
* @example
* <caption>How to use popup creators</caption>
* define([
* 'components.dt/js/spi/creators/CreatorType'
* 'components.dt/js/spi/creators/DropPopupController',
* 'text!mycomponent/templates/popup.html
* ], function (CreatorType, DropPopupController, popupMarkup) {
*
* 'use strict';
*
* var MyCreator = function () {
* // constructor init
* };
*
* MyCreator.prototype.getType = function () {
* return CreatorType.POPUP;
* };
*
* MyCreator.prototype.createView = function (activePage, container, createContext) {
* // the method creates a default view with default properties.
* var componentFactory = ComponentFactory.create(activePage);
* // set the default view's property value
* var properties = {
* text: 'Default Text'
* };
*
* // the method should take createContext into account and fill as
* // many properties as possible to make the view complete because
* // when called through the Component Creator API the popup will
* // not be raised.
* if (createContext && createContext.text) {
* properties.text = createContext.text;
* }
*
* var view = componentFactory.createView({
* type: 'org.my.myComponent',
* properties: properties,
* displayName: 'My Component'
* });
* return view;
* };
*
* MyCreator.prototype.getDropPopupController = function (view) {
* // right after the view is created the infrastructure calls this method
* // to get an instance of DropPopupController providing the html markup,
* // view model and the callback implementation for the popup.
* var myPopupViewModel = this._createModel();
* var customizer = new MyCreator.MyDropCustomizer(view, myPopupViewModel);
*
* // create an instance of DropPopupController with required popup model and markup.
* var controller = new DropPopupController(myPopupViewModel, popupMarkup, customizer);
*
* // attach a finish handler to your model and dismiss the popup
* // when the model says so using an API finish method.
* myPopupViewModel.finishHandler = function (result) {
* controller.finish(result);
* };
* return controller;
* };
*
* MyCreator.prototype._createModel = function () {
* var model = {
* text: ko.observable(),
* finishHandler: undefined,
* finish: function () {
* this.finishHandler(true);
* },
* cancel: function () {
* this.finishHandler(false);
* }
* };
* return model;
* };
*
* MyCreator.prototype.getOptions = function () {
* return {
* // the creator is expected to create only one type of view: org.my.myComponent
* possibleGeneratedViewTypes: ['org.my.myComponent'],
* // min width of the component will be 2 columns
* minWidth: 2
* };
* };
*
* var MyDropCustomizer = function (view, model) {
* this._view = view;
* this._model = model;
* };
*
* MyDropCustomizer.prototype.opened = function () {
* // you can do something useful here
* };
*
* MyDropCustomizer.prototype.closed = function (accepted) {
* if (accepted) {
* // popup was accepted and closed, let's update view properties
* this._view.getProperties().setValue('text', this._model.text());
* }
* // do not forget to return a promise resolving to the view instance
* return Promise.resolve(this._view);
* };
*
* MyCreator.MyDropCustomizer = MyDropCustomizer;
*
* return MyCreator;
*
* });
*
*/
var PopupCreator = function () {
AbcsLib.checkThis(this);
Creator.call(this);
};
AbcsLib.extend(PopupCreator, Creator);
/**
* Specifies the type of the creator.
* <p>Popup creators must return {@link components.dt/js/spi/creators/CreatorType.POPUP CreatorType.POPUP}
* type.</p>
*
* @AbcsExtension stable
* @version 16.3.5
* @overrides
* @returns {components.dt/js/spi/creators/CreatorType} creator type
*/
PopupCreator.prototype.getType = function () {
return CreatorType.POPUP;
};
/**
* Creates and returns a {@link components.dt/js/spi/creators/DropPopupController DropPopupController}
* instance for the PopupCreator implementation. DropPopupController is a class
* controlling the behavior of the opened popup modyfying the created view's
* properties during the view create process. See {@link components.dt/js/spi/creators/PopupCreator PopupCreator}
* for an example on how to implement this method.
*
* <p><strong>Must</strong> be overridden and implemented in descendants.
*
* @AbcsExtension stable
* @version 16.3.5
* @param {pages.dt/js/api/View} view created view to be customized.
* @returns {components.dt/js/spi/creators/DropPopupController} DropPopupController instance
*/
PopupCreator.prototype.getDropPopupController = function (/*view*/) {
throw new Error('getDropPopupController() must be implemented.');
};
/**
* Override to specify any special open options for the drop customizer.
* @returns {Object} object with options
*/
PopupCreator.prototype.getDropCustomizerOpenOptions = function () {
return {};
};
return PopupCreator;
});