/// <reference path="../../../node_modules/angular/angular.js" /> /// <reference path="OCacheService.js" /> /// <reference path="OContextService.js" /> /// <reference path="OControlService.js" /> /// <reference path="OFilterService.js" /> /// <reference path="OFrameworkService.js" /> /// <reference path="OFunctionService.js" /> /// <reference path="OGridService.js" /> /// <reference path="ONoneService.js" /> /// <reference path="ONotificationService.js" /> /// <reference path="ORestCallService.js" /> /// <reference path="OScreenService.js" /> /// <reference path="OService.js" /> /// <reference path="OSharePointService.js" /> /// <reference path="OUtilityService.js" /> /// <reference path="OViewInfoService.js" /> /** * @file Custom scripting service which contains functions that are available and supported for custom scripting. This library is inserted into the snippets as "CSL". * @author Glen Staes & Joey Lemmens * @copyright Ometa BVBA 2016 */ (function () { var CustomScriptingLibrary = function ($injector, $q, $rootScope, $timeout) { // Manually inject all other services (prevent cross references) //var Cache = $injector.get("OCacheService"); var Context; var Controls; //var Filters = $injector.get("OFilterService"); var F = $injector.get("OFrameworkService"); var MSG = $injector.get("OMessageService"); var Functions; var Grids; //var Notifications = $injector.get("ONotificationService"); var Screens; var U = $injector.get("OUtilityService"); var ViewInfo; /** * The custom scripting library namespace. * @version 1.1.0 * @namespace CSL * @type {object} */ var CSL = {}; /** @private * @function getComponent * @description Returns the screen or grid configuration for the given componentId. * @param {string} componentId - Specify the component identifier. * @return {object} Returns the configuration of the grid or screen. */ var getComponent = function (componentId) { if (angular.isUndefined(Grids)) Grids = $injector.get("OGridService"); if (angular.isUndefined(Screens)) Screens = $injector.get("OScreenService"); if (angular.isUndefined(ViewInfo)) ViewInfo = $injector.get("OViewInfoService"); if (angular.isUndefined(Context)) Context = $injector.get("OContextService"); var component = ViewInfo.getGridDefinition(componentId); if (angular.isUndefined(component)) component = Screens.getScreen({ screenId: componentId }); if (angular.isUndefined(component)) component = Context.getContextManager(componentId); return component; }; /** @private * @function getComponentScope * @description This function gets the root element of the current component (o-adm or o-cm) and returns the controller of that component. * @returns {Object} The controller of the current component. */ var getComponentScope = function () { var rootElement = $injector.get("$rootElement"); var adm = rootElement.find("o-adm"); var cm = rootElement.find("o-cm"); return adm.length ? adm.data().$oAdmController : cm.data().$oCmController; }; /** @private * @function checkRequiredInput * @description Checks whether the passed variables for all the items are not undefined. Throws an error if any property is undefined. * @param {object} requiredInput - Specify an object with required input. The key is the name of the input, the value is the passed in value. * @throws Will throw an error if requiredInput is undefined. */ var checkRequiredInput = function (requiredInput) { angular.forEach(requiredInput, function (value, key) { if (angular.isUndefined(value)) throw MSG.getMessage("validation.required", [key]); }); }; /** @private * @function checkAllowedComponents * @description Checks whether the given component is allowed. A component is allowed if its type is one of the allowed types. * @param {Object} componentConfig - Specify the component configuration. * @param {sourceTypeEnum[]} allowed - Specify an array of allowed sourceTypes: adm, grid, create, update, display, cm, picker * @param {string} functionName - Specify the name of the function. * @param {string} componentId - Specify the identifier of the component. * @throws Will throw an error if the type of component is not allowed. */ var checkAllowedComponents = function (componentConfig, allowed, functionName, componentId) { if (allowed.indexOf(componentConfig.sourceType) === -1) throw MSG.getMessage("components.functionNotAllowed", [functionName, componentId, componentConfig.sourceType, allowed.join(", ")]); }; /** @private * @function throwIfComponentNotFound * @description Throws an error, indicating the component could not be found, when the passed variable is undefined. * @param {object} component - Specify the component you want to check. * @param {string} componentId - Specify the id of the component that was used for retrieving the component. * @throws Will throw an error if component is undefined. */ var throwIfComponentNotFound = function (component, componentId) { if (!U.isDefined(component)) throw MSG.getMessage("components.notFound", [componentId]); }; /** @private * @function throwIfComponentNotFound * @description Throws an error, indicating the view field could not be found, when the passed variable is undefined. * @param {object} viewField - Specify the viewField you want to check. * @param {string} componentId - Specify the id of the component that was used for retrieving the view field. * @param {string} id - Specify the identifier that was used for retrieving the view field. * @throws Will throw an error if viewField is undefined */ var throwIfViewFieldNotFound = function (viewField, componentId, id) { if (!U.isDefined(viewField)) throw MSG.getMessage("viewFields.notFoundOnComponent", [componentId, id]); }; /*---------------------------------- * * VIEW FIELDS * *--------------------------------*/ /** * Contains all the methods for custom scripting on a view field * @memberof CSL * @namespace CSL.viewField * @name CSL.viewField * @type {object} */ CSL.viewField = {}; /** @function CSL.viewField.getConfiguration * @alias CSL.viewField.getConfiguration * @memberof! CSL.viewField * @method CSL.viewField.getConfiguration * @description This function returns the configuration for a view field on a component. The component could either be a screen, grid or context manager. If the view field doesn't * exist on the component, an exception will be thrown. * @param {Object} options - Specify the options for this function. * @param {string} options.componentId - Specify the unique identifier of the grid, screen or context manager. * @param {string} options.viewFieldName - Specify the name of the view field to get the configuration from. * @example * CSL.viewField.getConfiguration({ componentId: sourceId, viewFieldName: "Product ID" }); * @throws Will throw an error if any required input field is not set (componentId and viewFieldName). * @throws Will throw an error when a component with the passed componentId could not be found. * @throws Will throw an error when the component has no field configured for the given view field name. * @returns {Object} Returns the configuration of the view field. */ CSL.viewField.getConfiguration = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "componentId": settings.componentId, "viewFieldName": settings.viewFieldName }); // Try to get the component var component = getComponent(settings.componentId); throwIfComponentNotFound(component, settings.componentId); // Try to get the view field configuration var viewField = ViewInfo.getViewFieldByOriginalName(settings.componentId, settings.viewFieldName); throwIfViewFieldNotFound(viewField, settings.componentId, settings.viewFieldName); return viewField.config; }; /** @function csl.viewField.value * @alias CSL.viewField.value * @memberof! CSL.viewField * @method CSL.viewField.value * @description This function returns the current value for the given view field by calling the getControlValue function on the view field configuration. * If a value was passed to the function, it will be set first by calling the setControlValue function on the view field configuration. * @param {Object} options - Specify the options for this function. * @param {string} options.componentId - Specify the unique identifier of the screen or context manager. * @param {string} options.viewFieldName - Specify the name of the view field to get the configuration from. * @param {*} [options.value] - Specify the value for the field. This value will be set. * @example * // Gets the value * var productName = CSL.viewField.value({ componentId: sourceId, viewFieldName: "Product Name" }); * @example * // Sets the value * var updatedProductName = CSL.viewField.value({ * componentId: sourceId, * viewFieldName: "Product Name", * value: "Thrubanower" * }); * @throws Will throw an error if any required input field is not set (componentId and viewFieldName). * @throws Will throw an error when a component with the passed componentId could not be found if the view field is not used in inline editing. * @throws Will throw an error when the component has no field configured for the given view field name. * @returns {*} This function returns the value of the view field in its specific type. Date view field => value is a date */ CSL.viewField.value = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); ViewInfo = $injector.get("OViewInfoService"); Grids = $injector.get("OGridService"); checkRequiredInput({ "componentId": settings.componentId, "viewFieldName": settings.viewFieldName }); // Try to get the view field configuration var viewField = ViewInfo.getViewFieldByOriginalName(settings.componentId, settings.viewFieldName); throwIfViewFieldNotFound(viewField, settings.componentId, settings.viewFieldName); // Try to get the component var component = getComponent(settings.componentId); if (angular.isUndefined(viewField.runtime.originalGridId)) { throwIfComponentNotFound(component, settings.componentId); checkAllowedComponents(component, [U.enums.sourceType.cm, U.enums.sourceType.create, U.enums.sourceType.update, U.enums.sourceType.display], "CSL.viewField.value", settings.componentId); } // Set the value if a value is passed in if (angular.isDefined(settings.value)) { if (angular.isDefined(viewField.runtime.originalGridId)) { return CSL.grid.setCellValue({ gridId: viewField.runtime.originalGridId, viewFieldName: settings.viewFieldName, value: settings.value }); } else viewField.setControlValue(settings.value); } if (angular.isDefined(viewField.runtime.originalGridId)) { return Grids.getCurrentDataItem(viewField.runtime.originalGridId)[settings.viewFieldName]; } else { // #9053 / #9482 - Only in IE we need to invert the boolean value. But this is the responsibility of the CSL user. return viewField.getControlValue(); } }; /** @function CSL.viewField.updateFormFields * @alias CSL.viewField.updateFormFields * @memberof! CSL.viewField * @method CSL.viewField.updateFormFields * @description This function sets the value of the configured "Update Form Fields After Selection". If no data source is configured on the view field, calling this function is * useless. If a value is passed for a field that is no update form field, the value will not be set. * @param {Object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @param {string} options.viewFieldName - Specify the name of the view field to update the "update fields" from. * @param {Object} options.values - Specify values for the update form fields. Use the name of the view field as key and the new value for the field as value. * @example * CSL.viewField.updateFormFields({ * screenId: sourceId, * viewFieldName: "Product Category ID", * values: { "Product Category Name": "Drinks" } * }); * @throws Will throw an error if any required input field is not set (screenId, viewFieldName and values). * @throws Will throw an error when a component with the passed componentId could not be found. * @throws Will throw an error when the component has no field configured for the given view field name. */ CSL.viewField.updateFormFields = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "screenId": settings.screenId, "viewFieldName": settings.viewFieldName, "values": settings.values }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.cm, U.enums.sourceType.create, U.enums.sourceType.update], "CSL.viewField.updateFormFields", settings.screenId); // Try to get the view field configuration var viewField = ViewInfo.getViewFieldByOriginalName(settings.screenId, settings.viewFieldName); throwIfViewFieldNotFound(viewField, settings.screenId, settings.viewFieldName); // Call the method from the service Controls.updateFormFieldsFromDataSources({ screenId: settings.screenId, viewField: viewField, value: { updateFormFields: settings.values } }); }; /** @function CSL.viewField.toggleEnabled * @alias CSL.viewField.toggleEnabled * @memberof! CSL.viewField * @method CSL.viewField.toggleEnabled * @description This function sets whether the view field is available for editing or not. If no value is passed, the current availability will be inversed. * @param {Object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @param {string} options.viewFieldName - Specify the name of the view field. * @param {Object} [options.enabled] - Specify whether the view field should be enabled. If this value is not specified, the current value will be inversed. * @example * CSL.viewField.toggleEnabled({ screenId: sourceId, viewFieldName: "Product Description" }); * CSL.viewField.toggleEnabled({ screenId: sourceId, viewFieldName: "Product Description", enabled: false }); * @throws Will throw an error if any required input field is not set (screenId and viewFieldName). * @throws Will throw an error when a component with the passed componentId could not be found. * @throws Will throw an error when the component has no field configured for the given view field name. * @returns {Boolean} This function returns true if the view field is enabled and false if it is disabled. */ CSL.viewField.toggleEnabled = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "screenId": settings.screenId, "viewFieldName": settings.viewFieldName }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.cm, U.enums.sourceType.create, U.enums.sourceType.update], "CSL.viewField.toggleEnabled", settings.screenId); // Try to get the view field configuration var viewField = ViewInfo.getViewFieldByOriginalName(settings.screenId, settings.viewFieldName); throwIfViewFieldNotFound(viewField, settings.screenId, settings.viewFieldName); // Set disabled property if (angular.isDefined(settings.enabled)) viewField.config.disabled = !settings.enabled; else viewField.config.disabled = angular.isDefined(viewField.config.disabled) ? !viewField.config.disabled : true; // Return return !viewField.config.disabled; }; /** @function CSL.viewField.trigger * @alias CSL.viewField.trigger * @memberof! CSL.viewField * @method CSL.viewField.trigger * @description This function executes an event that has been configured on the view field. The passed event can have the "On"-prefix because if it does, it will be cut off. * @param {Object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @param {string} options.viewFieldName - Specify the name of the view field. * @param {Object} options.event - Specify the name of the event. Casing is not important and the "On"-prefix will be cut off. * @example * // Both calls trigger the same event * CSL.viewField.trigger({ screenId: sourceId, viewFieldName: "Product Description", event: "click" }); * CSL.viewField.trigger({ screenId: sourceId, viewFieldName: "Product Description", event: "OnClick" }); * @throws Will throw an error if any required input field is not set (screenId, viewFieldName and event). * @throws Will throw an error when a component with the passed componentId could not be found. * @throws Will throw an error when the component has no field configured for the given view field name. */ CSL.viewField.trigger = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "screenId": settings.screenId, "viewFieldName": settings.viewFieldName, "event": settings.event }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.cm, U.enums.sourceType.create, U.enums.sourceType.update, U.enums.sourceType.display], "CSL.viewField.trigger", settings.screenId); // Try to get the view field configuration var viewField = ViewInfo.getViewFieldByOriginalName(settings.screenId, settings.viewFieldName); throwIfViewFieldNotFound(viewField, settings.screenId, settings.viewFieldName); // Strip "on" from the event if it has been passed if (settings.event.toLowerCase().indexOf("on") === 0) settings.event = settings.event.toLowerCase().replace("on", ""); // Get the control and trigger the event $timeout(function () { var control = viewField.getControl(); if (angular.isDefined(control.element)) control.element.trigger(settings.event.toLowerCase()); else if (angular.isFunction(control.trigger)) control.trigger(settings.event.toLowerCase()); }); }; /** @function CSL.viewField.openDataSource * @alias CSL.viewField.openDataSource * @memberof! CSL.viewField * @method CSL.viewField.openDataSource * @description This function opens the data source for the given view field. This function can only be applied to view fields with a data source and * the data source should be configured as a picker or a dropdownlist. * @param {Object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @param {string} options.viewFieldName - Specify the name of the view field. * @example * CSL.viewField.openDataSource({ screenId: sourceId, viewFieldName: "Product Category ID" }); * @throws Will throw an error if any required input field is not set (screenId and viewFieldName). * @throws Will throw an error when a component with the passed componentId could not be found. * @throws Will throw an error when the component has no field configured for the given view field name. * @throws Will throw an error when the view field has no data source configured. * @throws Will throw an error when a data source is configured on the view field but it is not a picker or dropdown list. */ CSL.viewField.openDataSource = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "screenId": settings.screenId, "viewFieldName": settings.viewFieldName }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.cm, U.enums.sourceType.create, U.enums.sourceType.update], "CSL.viewField.openDataSource", settings.screenId); // Try to get the view field configuration var viewField = ViewInfo.getViewFieldByOriginalName(settings.screenId, settings.viewFieldName); throwIfViewFieldNotFound(viewField, settings.screenId, settings.viewFieldName); // Stop if no data source is configured if (!viewField.config.dataSource.enabled) throw MSG.getMessage("viewFields.dataSourceNotEnabled", [settings.viewFieldName]); $timeout(function () { // Get the control var control = viewField.getControl(); switch (viewField.config.dataSource.displayType) { case U.enums.dataSourceType.picker: var openPickerButton = control.element.closest("o-control").find(".o-picker-nowrap").find("button[ng-click='$ctrl.pickerDialog.open()']"); if (openPickerButton.length) openPickerButton.click(); break; case U.enums.dataSourceType.list: control.open(); break; default: // Only pickers and dropdownlists are allowed throw MSG.getMessage("viewFields.restrictedDataSourceFunction", ["CSL.viewField.openDataSource", settings.viewFieldName, [U.enums.dataSourceType.picker, U.enums.dataSourceType.list].join(", ")]); break; } }); }; var addViewToControl = function (options) { // Defaults var settings = angular.merge({ setOutputAsValue: false }, options); // Load services Controls = $injector.get("OControlService"); ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "screenId": settings.screenId, "viewFieldName": settings.viewFieldName, "object": settings.object, "view": settings.view }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.cm, U.enums.sourceType.create, U.enums.sourceType.update, U.enums.sourceType.display], "CSL.viewField.addViewToControl", settings.screenId); // Try to get the view field configuration var viewField = ViewInfo.getViewFieldByOriginalName(settings.screenId, settings.viewFieldName); throwIfViewFieldNotFound(viewField, settings.screenId, settings.viewFieldName); Controls.setControlView(settings); }; /** @function CSL.viewField.addCreateViewToControl * @alias CSL.viewField.addCreateViewToControl * @memberof! CSL.viewField * @method CSL.viewField.addCreateViewToControl * @description Adds an image to the control with the possibility to open an insert view. The default icon is the plus icon from font-awesome. * @param {Object} options - Specify the options for this function. * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.viewFieldName - Specify the name of the view field to add the icon to. * @param {String} options.object - Specify the name of the object. * @param {String} options.view - Specify the name of the view. * @param {String[]} [options.customClasses] - Specify optionally extra css classes for the icon. * @param {String} [options.iconUrl] - Specify optionally the url of the icon. This can be a font-awesome class, a url, or the name of an asset. * @param {Boolean} [options.setOutputAsValue=false] - Specify optionally if you want to set the first returned record as the value for the view field. */ CSL.viewField.addCreateViewToControl = function (options) { options = options || {}; var R = $injector.get("ORestCallService"); options.viewType = U.enums.sourceType.create; options.iconUrl = options.iconUrl || "fa-plus-circle"; options.callbacks = {}; options.callbacks.afterSave = function (response) { if (angular.isDefined(options.setOutputAsValue) && options.setOutputAsValue) { var screen = Screens.getScreen(options.screenId); var viewField = ViewInfo.getViewField(options.screenId, R.getViewFieldInternalName(options.screenId, options.viewFieldName)); if (viewField.config.dataSource.enabled) { // The key should be taken var keyAndDisplay = U.interpretKeyAndDisplayFormat({ rows: response.data[0].Results, keyColumns: viewField.config.dataSource.keyColumns, keyFormat: viewField.config.dataSource.keyFormat, displayColumns: viewField.config.dataSource.displayColumns, displayFormat: viewField.config.dataSource.displayFormat, updateFormFieldsAfterSelection: viewField.config.dataSource.updateFormFieldsAfterSelection.viewFields }); viewField.setControlValue(keyAndDisplay[0].key); } else { // The value of the current field should be taken var fieldValue = response.data[0].Results[0][options.viewFieldName]; if (angular.isDefined(fieldValue)) viewField.setControlValue(fieldValue); } } } addViewToControl(options); }; /** @function CSL.viewField.addSingleRecordViewToControl * @alias CSL.viewField.addSingleRecordViewToControl * @memberof! CSL.viewField * @method CSL.viewField.addSingleRecordViewToControl * @description Adds an image to the control with the possibility to open a single record view. The default icon is the info icon from font-awesome. * @param {Object} options - Specify the options for this function. * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.viewFieldName - Specify the name of the view field to add the icon to. * @param {String} options.object - Specify the name of the object. * @param {String} options.view - Specify the name of the view. * @param {String[]} [options.customClasses] - Specify optionally extra css classes for the icon. * @param {String} [options.iconUrl] - Specify optionally the url of the icon. This can be a font-awesome class, a url, or the name of an asset. */ CSL.viewField.addSingleRecordViewToControl = function (options) { options.viewType = U.enums.sourceType.display; options.iconUrl = options.iconUrl || "fa-info-circle"; addViewToControl(options); }; /** @function CSL.viewField.addUpdateViewToControl * @alias CSL.viewField.addUpdateViewToControl * @memberof! CSL.viewField * @method CSL.viewField.addUpdateViewToControl * @description Adds an image to the control with the possibility to open an update view. The default icon is the info icon from font-awesome. * @param {Object} options - Specify the options for this function. * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.viewFieldName - Specify the name of the view field to add the icon to. * @param {String} options.object - Specify the name of the object. * @param {String} options.view - Specify the name of the view. * @param {String[]} [options.customClasses] - Specify optionally extra css classes for the icon. * @param {String} [options.iconUrl] - Specify optionally the url of the icon. This can be a font-awesome class, a url, or the name of an asset. */ CSL.viewField.addUpdateViewToControl = function (options) { options.viewType = U.enums.sourceType.update; options.iconUrl = options.iconUrl || "fa-pencil-square"; addViewToControl(options); }; /** @function CSL.viewField.addValidationRule * @alias CSL.viewField.addValidationRule * @memberof! CSL.viewField * @method CSL.viewField.addValidationRule * @description This function adds a validation rule to view field. This validation rule should be a function because this is how kendo implements validation. * This function will test the rule as well by retrieving the o-control element of the view field and passing it to the function. If the result of this test * is not true or false, the rule is invalid and will not be applied. * @param {Object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @param {string} options.viewFieldName - Specify the name of the view field. * @param {Function} options.rule - Specify the rule to add. * @param {string} options.ruleName - Specify the name of the rule to add. All rules should have a unique name. * @param {string} options.ruleMessage - Specify the message to show when the rule is invalid. * @throws Will throw an error if any required input field is not set (screenId, viewFieldName, rule, ruleName and ruleMessage). * @throws Will throw an error when a component with the passed componentId could not be found. * @throws Will throw an error when the component has no field configured for the given view field name. * @throws Will throw an error if the specified rule didn't return a boolean. * @returns {String} This function returns the unique identifier for the added rule. This identifier should be used for removing the custom rule again. */ CSL.viewField.addValidationRule = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "screenId": settings.screenId, "viewFieldName": settings.viewFieldName, "rule": settings.rule, "ruleName": settings.ruleName, "ruleMessage": settings.ruleMessage }); settings.ruleName = settings.ruleName.toLowerCase(); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.cm, U.enums.sourceType.create, U.enums.sourceType.update], "CSL.viewField.addValidationRule", settings.screenId); // Try to get the view field configuration var viewField = ViewInfo.getViewFieldByOriginalName(settings.screenId, settings.viewFieldName); throwIfViewFieldNotFound(viewField, settings.screenId, settings.viewFieldName); // Get the control var control = viewField.getControl(); var oControl = viewField.getOControl(); var ngModel = oControl.getNgModelController(); // Test the rule var testResult = settings.rule(control.element || control); if (typeof testResult == "boolean") { var element = control.element || control; oControl.validatorMessages[settings.ruleName] = settings.ruleMessage; ngModel.$validators[settings.ruleName] = function () { return settings.rule(element); } $timeout(function () { ngModel.$validate(); }); } else { throw MSG.getMessage("viewFields.customRuleReturnsNoBoolean", [settings.ruleName]); }; return settings.ruleName; }; /** @function CSL.viewField.removeValidationRule * @alias CSL.viewField.removeValidationRule * @memberof! CSL.viewField * @method CSL.viewField.removeValidationRule * @description This function removes a validation rule of a write screen. * @param {Object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @param {string} options.viewFieldName - Specify the name of the view field. * @param {string} options.ruleName - Specify the name of the rule to add. All rules should have a unique name. * @throws Will throw an error if any required input field is not set (screenId, viewFieldName and ruleName). * @throws Will throw an error when a component with the passed componentId could not be found. */ CSL.viewField.removeValidationRule = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); checkRequiredInput({ "screenId": settings.screenId, "viewFieldName": settings.viewFieldName, "ruleName": settings.ruleName }); // Try to get the view field configuration var viewField = ViewInfo.getViewFieldByOriginalName(settings.screenId, settings.viewFieldName); throwIfViewFieldNotFound(viewField, settings.screenId, settings.viewFieldName); $timeout(function () { // Get the control var control = viewField.getControl(); var oControl = viewField.getOControl(); var ngModel = oControl.getNgModelController(); delete ngModel.$validators[settings.ruleName]; delete oControl.validatorMessages[settings.ruleName]; ngModel.$setValidity(settings.ruleName, true); ngModel.$validate(); }); }; /** @private * @function addViewFieldCondition * @description This function adds a condition to the view field on which it should perform an action. The action will be performed if the condition returns true. In this condition, * the values of the current form and the source system context can be used. If the field has had the action performed and the condition results to false, the field undo the action. * @param {Object} options - Specify the options for this function. * @param {String} options.conditionType - Specify the type of condition: "hide", "disable", "class". * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.viewFieldName - Specify the name of the view field to add the condition to. * @param {String} options.conditionName - Specify the unique name for the condition. A condition cannot be added if the name is not unique. * @param {Function} options.condition - Specify a function that checks whether the view field should be hidden. Return false if the view field should not be hidden. * @throws Will throw an error if a condition with the same name already exists on the view field. */ var addViewFieldCondition = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "screenId": settings.screenId, "viewFieldName": settings.viewFieldName, "conditionName": settings.conditionName, "condition": settings.condition }); var addMethod; switch (options.conditionType) { case "required": addMethod = ViewInfo.addViewFieldRequiredCondition; break; case "hide": addMethod = ViewInfo.addViewFieldHideCondition; break; case "disable": addMethod = ViewInfo.addViewFieldDisabledCondition; break; case "class": addMethod = ViewInfo.addViewFieldClassCondition; checkRequiredInput({ "classes or styles": settings.classes || settings.styles }); break; } // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); // Get the actual id on which the view field is registered. If the view field is in inline editing, we should take that id. var viewFieldInfoId = Grids.isInEditMode(settings.screenId) ? component.views.update.inlineEditing.componentId : settings.screenId; // Try to get the view field configuration var viewField = ViewInfo.getViewFieldByOriginalName(viewFieldInfoId, settings.viewFieldName); throwIfViewFieldNotFound(viewField, viewFieldInfoId, settings.viewFieldName); addMethod(viewFieldInfoId, settings.viewFieldName, settings.conditionName, settings.condition, settings.classes, settings.styles); }; /** @private * @function removeViewFieldCondition * @description This function removes a condition from the view field. * @param {Object} options - Specify the options for this function. * @param {String} options.conditionType - Specify the type of condition: "hide", "disable", "class". * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.viewFieldName - Specify the name of the view field to add the condition to. * @param {String} options.conditionName - Specify the unique name for the condition. A condition cannot be added if the name is not unique. */ var removeViewFieldCondition = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "screenId": settings.screenId, "viewFieldName": settings.viewFieldName, "conditionName": settings.conditionName }); var removeMethod; switch (options.conditionType) { case "hide": removeMethod = ViewInfo.removeViewFieldHideCondition; break; case "disable": removeMethod = ViewInfo.removeViewFieldDisabledCondition; break; case "class": removeMethod = ViewInfo.removeViewFieldClassCondition; break; } // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); // Get the actual id on which the view field is registered. If the view field is in inline editing, we should take that id. var viewFieldInfoId = CSL.viewField.isInlineEditing({ componentId: settings.screenId, viewFieldName: settings.viewFieldName }) ? component.views.update.inlineEditing.componentId : settings.screenId; // Try to get the view field configuration var viewField = ViewInfo.getViewFieldByOriginalName(viewFieldInfoId, settings.viewFieldName); throwIfViewFieldNotFound(viewField, viewFieldInfoId, settings.viewFieldName); removeMethod(viewFieldInfoId, settings.viewFieldName, settings.conditionName); }; /** @function CSL.viewField.addRequiredCondition * @alias CSL.viewField.addRequiredCondition * @memberof! CSL.viewField * @method CSL.viewField.addRequiredCondition * @description This function adds a condition to the view field to make it required. The view field will be required if the condition returns true. In this condition, * the values of the current form and the source system context can be used. If the field has been hidden and the condition results to false, the field will no longer be * required. * @param {Object} options - Specify the options for this function. * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.viewFieldName - Specify the name of the view field to add the condition to. * @param {String} options.conditionName - Specify the unique name for the condition. A condition cannot be added if the name is not unique. * @param {Function} options.condition - Specify a function that checks whether the view field should be hidden. Return false if the view field should not be hidden. * @example * // When the field Include Lunch (YesNo) is checked, the Lunch Menu field should be required * CSL.viewField.addRequiredCondition({ * screenId: sourceId, * viewFieldName: "Lunch menu", * conditionName: "RequireLunchMenuWhenLunchChecked", * condition: function(rowData){ return rowData["Include Lunch"]; } * }); * @throws Will throw an error if any required input field is not set (screenId and ruleName). * @throws Will throw an error when a component with the passed componentId could not be found. * @throws Will throw an error if the view field was not found on the view. * @throws Will throw an error if a condition with the same name already exists on the view field. */ CSL.viewField.addRequiredCondition = function (options) { options = options || {}; options.conditionType = "required"; addViewFieldCondition(options); }; /** @function CSL.viewField.removeRequiredCondition * @alias CSL.viewField.removeRequiredCondition * @memberof! CSL.viewField * @method CSL.viewField.removeRequiredCondition * @description This function removes a required condition on a view field. * @param {Object} options - Specify the options for this function. * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.viewFieldName - Specify the name of the view field to add the condition to. * @param {String} options.conditionName - Specify the unique name for the condition. A condition cannot be added if the name is not unique. * @example * CSL.viewField.removeRequiredCondition({ screenId: sourceId, viewFieldName: "Lunch menu", conditionName: "RequireLunchMenuWhenLunchChecked" }); * @throws Will throw an error if any required input field is not set (screenId and ruleName). * @throws Will throw an error when a component with the passed componentId could not be found. * @throws Will throw an error if the view field was not found on the view. */ CSL.viewField.removeRequiredCondition = function (options) { options = options || {}; options.conditionType = "required"; removeViewFieldCondition(options); }; /** @function CSL.viewField.addHideCondition * @alias CSL.viewField.addHideCondition * @memberof! CSL.viewField * @method CSL.viewField.addHideCondition * @description This function adds a condition to the view field on which it could be hidden. The view field will be hidden if the condition returns true. In this condition, * the values of the current form and the source system context can be used. If the field has been hidden and the condition results to false, the field will be * shown again. * @param {Object} options - Specify the options for this function. * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.viewFieldName - Specify the name of the view field to add the condition to. * @param {String} options.conditionName - Specify the unique name for the condition. A condition cannot be added if the name is not unique. * @param {Function} options.condition - Specify a function that checks whether the view field should be hidden. Return false if the view field should not be hidden. * @example * // When the field Include Lunch (YesNo) is not checked, the Lunch Menu field should be hidden * CSL.viewField.addHideCondition({ * screenId: sourceId, * viewFieldName: "Lunch menu", * conditionName: "HideLunchMenuWhenLunchNotChecked", * condition: function(rowData){ return !rowData["Include Lunch"]; } * }); * @throws Will throw an error if any required input field is not set (screenId and ruleName). * @throws Will throw an error when a component with the passed componentId could not be found. * @throws Will throw an error if the view field was not found on the view. * @throws Will throw an error if a condition with the same name already exists on the view field. */ CSL.viewField.addHideCondition = function (options) { options = options || {}; options.conditionType = "hide"; addViewFieldCondition(options); }; /** @function CSL.viewField.removeHideCondition * @alias CSL.viewField.removeHideCondition * @memberof! CSL.viewField * @method CSL.viewField.removeHideCondition * @description This function removes a hide condition on a view field. * @param {Object} options - Specify the options for this function. * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.viewFieldName - Specify the name of the view field to add the condition to. * @param {String} options.conditionName - Specify the unique name for the condition. A condition cannot be added if the name is not unique. * @example * CSL.viewField.removeHideCondition({ screenId: sourceId, viewFieldName: "Lunch menu", conditionName: "HideLunchMenuWhenLunchNotChecked" }); * @throws Will throw an error if any required input field is not set (screenId and ruleName). * @throws Will throw an error when a component with the passed componentId could not be found. * @throws Will throw an error if the view field was not found on the view. */ CSL.viewField.removeHideCondition = function (options) { options = options || {}; options.conditionType = "hide"; removeViewFieldCondition(options); }; /** @function CSL.viewField.addDisableCondition * @alias CSL.viewField.addDisableCondition * @memberof! CSL.viewField * @method CSL.viewField.addDisableCondition * @description This function adds a condition to the view field on which it could be disabled. The view field will be disabled if the condition returns true. In this condition, * the values of the current form and the source system context can be used. If the field has been disabled and the condition results to false, the field will be * shown again. * @param {Object} options - Specify the options for this function. * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.viewFieldName - Specify the name of the view field to add the condition to. * @param {String} options.conditionName - Specify the unique name for the condition. A condition cannot be added if the name is not unique. * @param {Function} options.condition - Specify a function that checks whether the view field should be hidden. Return false if the view field should not be hidden. * @example * // When the field Include Lunch (YesNo) is not checked, the Lunch Menu field should be disabled * CSL.viewField.addDisableCondition({ * screenId: sourceId, * viewFieldName: "Lunch menu", * conditionName: "DisableLunchMenuWhenLunchNotChecked", * condition: function(rowData){ return !rowData["Include Lunch"]; } * }); * @throws Will throw an error if any required input field is not set (screenId and ruleName). * @throws Will throw an error when a component with the passed componentId could not be found. * @throws Will throw an error if the view field was not found on the view. * @throws Will throw an error if a condition with the same name already exists on the view field. */ CSL.viewField.addDisableCondition = function (options) { options = options || {}; options.conditionType = "disable"; addViewFieldCondition(options); }; /** @function CSL.viewField.removeDisableCondition * @alias CSL.viewField.removeDisableCondition * @memberof! CSL.viewField * @method CSL.viewField.removeDisableCondition * @description This function removes a disable condition on a view field. * @param {Object} options - Specify the options for this function. * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.viewFieldName - Specify the name of the view field to add the condition to. * @param {String} options.conditionName - Specify the unique name for the condition. A condition cannot be added if the name is not unique. * @example * CSL.viewField.removeDisableCondition({ screenId: sourceId, viewFieldName: "Lunch menu", conditionName: "DisableLunchMenuWhenLunchNotChecked" }); * @throws Will throw an error if any required input field is not set (screenId and ruleName). * @throws Will throw an error when a component with the passed componentId could not be found. * @throws Will throw an error if the view field was not found on the view. */ CSL.viewField.removeDisableCondition = function (options) { options = options || {}; options.conditionType = "disable"; removeViewFieldCondition(options); }; /** @function CSL.viewField.addClassCondition * @alias CSL.viewField.addClassCondition * @memberof! CSL.viewField * @method CSL.viewField.addClassCondition * @description This function adds a condition to the view field for adding classes and inline styles. The view field will receive the styles if the condition returns true. In this condition, * the values of the current form and the source system context can be used. If the field has recieved the styles and the condition results to false, the field will be * stripped of the styles again. * @param {Object} options - Specify the options for this function. * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.viewFieldName - Specify the name of the view field to add the condition to. * @param {String} options.conditionName - Specify the unique name for the condition. A condition cannot be added if the name is not unique. * @param {Function} options.condition - Specify a function that checks whether the view field should be hidden. Return false if the view field should not be hidden. * @param {String} options.classNames - Specify the names of the classes seperated by " ". * @param {String} options.styles - Specify the inline styles. Be sure to use ';' at the end of every definition. * @example * // When the field Product Stock has a value smaller than 15, the background color should be red and the field should receive the class .low-stock * CSL.viewField.addClassCondition({ * screenId: sourceId, * viewFieldName: "Product Stock", * conditionName: "ProductStockRedBackground", * classNames: "low-stock", * styles: "background-color: red;", * condition: function(rowData){ return rowData["Product Stock"] < 15; } * }); * @throws Will throw an error if any required input field is not set (screenId and ruleName). * @throws Will throw an error when a component with the passed componentId could not be found. * @throws Will throw an error if the view field was not found on the view. * @throws Will throw an error if a condition with the same name already exists on the view field. */ CSL.viewField.addClassCondition = function (options) { options = options || {}; options.conditionType = "class"; addViewFieldCondition(options); }; /** @function CSL.viewField.removeClassCondition * @alias CSL.viewField.removeClassCondition * @memberof! CSL.viewField * @method CSL.viewField.removeClassCondition * @description This function removes a class condition from the view field. * @param {Object} options - Specify the options for this function. * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.viewFieldName - Specify the name of the view field to add the condition to. * @param {String} options.conditionName - Specify the unique name for the condition. A condition cannot be added if the name is not unique. * @example * CSL.viewField.removeClassCondition({ screenId: sourceId, viewFieldName: "Product Stock", conditionName: "ProductStockRedBackground" }); * @throws Will throw an error if any required input field is not set (screenId and ruleName). * @throws Will throw an error when a component with the passed componentId could not be found. * @throws Will throw an error if the view field was not found on the view. */ CSL.viewField.removeClassCondition = function (options) { options = options || {}; options.conditionType = "class"; removeViewFieldCondition(options); }; /** @function CSL.viewField.isInlineEditing * @alias CSL.viewField.isInlineEditing * @memberof! CSL.viewField * @method CSL.viewField.isInlineEditing * @description Checks whether the view field is being used in inline editing. * @param {Object} options - Specify the options for this function. * @param {string} options.componentId - Specify the id of the screen or grid. * @param {string} options.viewFieldName - Specify the name of the view field. * @example * var isInlineEditing = CSL.viewField.isInlineEditing({ componentId: sourceId, viewFieldName: "Product Name" }); * @throws Will throw an error if any required input field is not set (componentId and viewFieldName). * @throws Will throw an error if the view field was not found on the view. * @returns {boolean} True if the view field is used in inline editing, false if not. */ CSL.viewField.isInlineEditing = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "componentId": settings.componentId, "viewFieldName": settings.viewFieldName }); // Try to get the component var component = getComponent(settings.componentId); // Try to get the view definition var viewDefinition = ViewInfo.getViewDefinition(settings.componentId); // Try to get the view field configuration var viewField = ViewInfo.getViewFieldByOriginalName(settings.componentId, settings.viewFieldName); throwIfViewFieldNotFound(viewField, settings.componentId, settings.viewFieldName); // If the component is undefined but the view definition is defined, we can conclude that // the view field is active in inline editing because the view definition is saved, but it // is neither a screen, grid or context manager. return angular.isUndefined(component) && angular.isDefined(viewDefinition); }; /** @function CSL.viewField.editCell * @alias = CSL.viewField.editCell * @memberof! CSL.viewField * @method CSL.viewField.editCell * @description Enters a cell of the current row when inline editing is set to Batch or RecordRowLeave * @param {Object} options - Specify the options for this function. * @param {string} options.componentId - Specify the id of the screen or grid. * @param {string} options.rowKey - Specify the unique identifier of the row. * @param {string} options.viewFieldName - Specify the name of the view field. * @example * CSL.viewField.editCell({ componentId: sourceId, rowKey: myGridRowKey, viewFieldName: 'Stock Value' }); * @throws Will throw an error if any required input field is not set (componentId, rowKey, viewFieldName) * @throws Will throw an error if the inline editing mode is not set to Batch or RecordRowLeave */ CSL.viewField.editCell = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "componentId": settings.componentId, "rowKey": settings.rowKey, "viewFieldName": settings.viewFieldName }); // Try to get the component var component = getComponent(settings.componentId); throwIfComponentNotFound(component, settings.componentId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.viewField.editCell", settings.componentId); var allowedInlineEditModes = [U.enums.inlineEditing.batch, U.enums.inlineEditing.recordRowLeave]; if (allowedInlineEditModes.indexOf(component.views.update.inlineEditing.mode) === -1) throw MSG.getMessage("CSL.grid.wrongInlineEditMode", ["CSL.viewField.editCell", settings.componentId, allowedInlineEditModes.join(", ")]); // Get the controller scope var kendoGrid = Grids.getKendoGrid(settings.componentId); var viewField = ViewInfo.getViewFieldByOriginalName(settings.componentId, settings.viewFieldName); var columnToEdit = kendoGrid.columns.filter(function (c) { return c.viewField.config.originalName === settings.viewFieldName; })[0]; if (columnToEdit) { setTimeout(function () { kendoGrid.editCell(kendoGrid.tbody.find("tr[data-uid=" + settings.rowKey + "] td[aria-describedby=" + columnToEdit.headerAttributes.id + "]")); }, 10); } } /** @function CSL.viewField.leaveCell * @alias = CSL.viewField.leaveCell * @memberof! CSL.viewField * @method CSL.viewField.leaveCell * @description Forces the user out of the cell if inline editing is set to Batch or RecordRowLeave * @param {Object} options - Specify the options for this function. * @param {string} options.componentId - Specify the id of the screen or grid. * @example * CSL.viewField.leaveCell({ componentId: sourceId }); * @throws Will throw an error if any required input field is not set (componentId) * @throws Will throw an error if the inline editing mode is not set to Batch or RecordRowLeave */ CSL.viewField.leaveCell = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "componentId": settings.componentId }); // Try to get the component var component = getComponent(settings.componentId); throwIfComponentNotFound(component, settings.componentId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.viewField.leaveCell", settings.componentId); var allowedInlineEditModes = [U.enums.inlineEditing.batch, U.enums.inlineEditing.recordRowLeave]; if (allowedInlineEditModes.indexOf(component.views.update.inlineEditing.mode) === -1) throw MSG.getMessage("CSL.grid.wrongInlineEditMode", ["CSL.viewField.leaveCell", settings.componentId, allowedInlineEditModes.join(", ")]); var kendoGrid = Grids.getKendoGrid(settings.componentId); kendoGrid.closeCell(); }; /*---------------------------------- * * VIEWS * *--------------------------------*/ /** * Contains all the methods for custom scripting on a screen * @memberof CSL * @namespace CSL.screen * @name CSL.screen * @type {object} */ CSL.screen = {}; /** * @function CSL.screen.progress * @alias CSL.screen.progress * @memberof! CSL.screen * @method CSL.screen.progress * @description Shows or hides the progress indicator on the screen. * @example * CSL.screen.progress({ screenId: sourceId }); * @example * CSL.screen.progress({ screenId: sourceId, progress: false }); * @param {object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @param {boolean} [options.progress=true] - Specify whether the progress indicator should be shown or hidden. */ CSL.screen.progress = function (options) { // Defaults var settings = angular.merge({ progress: true }, options); checkRequiredInput({ screenId: settings.screenId }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.create, U.enums.sourceType.edit, U.enums.sourceType.display], "CSL.screen.progress", settings.screenId); kendo.ui.progress(component.element, settings.progress); } /** @function CSL.screen.addScreen * @alias CSL.screen.addScreen * @memberof! CSL.screen * @method CSL.screen.addScreen * @descriptionAdd a new screen to the screen array of the controller. * @param {Object} options - Specify an options object. * @param {string} options.componentId - Specify the id of the component to add the screen to * @param {Object} options.grid - Specify the source grid that opened the screen. * @param {string} options.object - Specify the object. * @param {string} options.view - Specify the view. * @param {Object[]} [options.viewDefinition] - Specify the view definition object. This can be used to override the default viewDefinition of a view. * @param {Object[]} [options.viewFields] - Specify the viewField configurations you want to use in the screen. This can be used to override the default viewFields of a view. * @param {String} [options.parentScreenId] - Specify the id of the parent screen. * @param {Object[]} [options.dataItem] - Specify the context data items from the update, display or grid. * @param {bool} [options.prepareView=false] - Specify if the screen should make a prepareView request. * @return {String} The unique identifier of the newly created screen */ CSL.screen.addScreen = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services settings.isWindow = true; settings.prepareView = true; checkRequiredInput({ "componentId": settings.componentId, "sourceType": settings.sourceType, "object": settings.object, "view": settings.view }); // Try to get the component var component = getComponent(settings.componentId); throwIfComponentNotFound(component, settings.componentId); var screenId = Screens.addScreen(settings); return screenId; }; /** @function CSL.screen.close * @alias CSL.screen.close * @memberof! CSL.screen * @method CSL.screen.close * @description This function closes the given screen. Be aware that this does not save the screen. * @param {Object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @example * CSL.screen.close({ screenId: sourceId }); * @throws Will throw an error if any required input field is not set (screenId). * @throws Will throw an error when a component with the passed screenId could not be found. */ CSL.screen.close = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); checkRequiredInput({ "screenId": settings.screenId }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.create, U.enums.sourceType.update, U.enums.sourceType.display], "CSL.screen.close", settings.screenId); Screens.closeScreen(settings.screenId); }; /** @function CSL.screen.validate * @alias CSL.screen.validate * @memberof! CSL.screen * @method CSL.screen.validate * @description This function validates the given screen if it is an insert or update screen. No error handling on validation is necessary because if the view field is invalid * the error will be set on the view field. * @param {Object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @example * CSL.screen.validate({ screenId: sourceId }).then(function(){ * // We're valid * }).catch(function(){ * // We're invalid or an error occurred in the .then callback * }) * @throws Will throw an error if any required input field is not set (screenId). * @throws Will throw an error when a component with the passed screenId could not be found. * @returns {Promise} A promise for the validation process. If the promise is resolved, the form is valid. */ CSL.screen.validate = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); checkRequiredInput({ "screenId": settings.screenId }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.cm, U.enums.sourceType.create, U.enums.sourceType.update], "CSL.screen.validate", settings.screenId); Screens.validateScreen(settings.screenId); }; /** @function CSL.screen.save * @alias CSL.screen.save * @memberof! CSL.screen * @method CSL.screen.save * @description This function saves the given screen if it is an insert or update screen. The form will be validated before the actual save request is performed. * @param {Object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @example * CSL.screen.save({ screenId: sourceId }); * @throws Will throw an error if any required input field is not set (screenId). * @throws Will throw an error when a component with the passed screenId could not be found. * @returns {Promise} A promise for the saving process. If the promise is resolved, the form has been saved. */ CSL.screen.save = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); checkRequiredInput({ "screenId": settings.screenId }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.create, U.enums.sourceType.update], "CSL.screen.save", settings.screenId); Screens.submitScreen(settings.screenId); }; /** @function CSL.screen.values * @alias CSL.screen.values * @memberof! CSL.screen * @method CSL.screen.values * @description This function gets or sets the given screen values. If the values parameter is passed, the values will be set if the view field is found on the screen. * @param {Object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @example * var formValues = CSL.screen.values({ screenId: souceId }); * @throws Will throw an error if any required input field is not set (screenId). * @throws Will throw an error when a component with the passed screenId could not be found. * @returns {Object} The values of the screen. */ CSL.screen.values = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "screenId": settings.screenId }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.cm, U.enums.sourceType.display, U.enums.sourceType.create, U.enums.sourceType.update], "CSL.screen.values", settings.screenId); if (angular.isDefined(settings.values)) Screens.setScreenContext(settings.screenId, settings.values); return Screens.getScreenContext({ screenId: settings.screenId }); }; /** @function CSL.screen.addButton * @alias CSL.screen.addButton * @memberof! CSL.screen * @method CSL.screen.addButton * @description Adds a custom button to the screen * @param {object} options - Specify the options for this method. * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.buttonName - Specify the unique name for the button. * @param {String} [options.iconUrl="defaultFunction"] - Specify the url of the icon. * @param {String} options.label - Specify the text to show on the button. * @param {Function} options.onClick - Specify the script to execute when the button is clicked. * @example * CSL.screen.addButton({ * screenId: sourceId, * buttonName: "Go to Google", * iconUrl: "fa-google", * label: "Go to Google", * onClick: function(){ window.open("//google.com"); } * }) * @throws Will throw an error if any required input field is not set (screenId, buttonName, label, onClick) * @throws Will throw an error when a component with the passed screenId could not be found. * @returns {String} The name of the button. */ CSL.screen.addButton = function (options) { // Defaults var settings = angular.merge({ iconUrl: "defaultFunction" }, options); checkRequiredInput({ "screenId": settings.screenId, "buttonName": settings.buttonName, "label": settings.label, "onClick": settings.onClick }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.display, U.enums.sourceType.create, U.enums.sourceType.update], "CSL.screen.addButton", settings.screenId); return Screens.addCustomButton(settings); }; /** @function CSL.screen.hasButton * @alias CSL.screen.hasButton * @memberof! CSL.screen * @method CSL.screen.hasButton * @description Checks whether the screen has a custom button with the given name. * @param {Object} options - Specify the options for this method. * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.buttonName - Specify the unique name for the button. * @example * var buttonExists = CSL.screen.hasButton({ screenId: sourceId, buttonName: "Go to Google" }); * @throws Will throw an error if any required input field is not set (screenId, buttonName) * @throws Will throw an error when a component with the passed screenId could not be found. * @returns {Boolean} True if a button already exists, false if not. */ CSL.screen.hasButton = function (options) { // Defaults var settings = angular.merge({ }, options); checkRequiredInput({ "screenId": settings.screenId, "buttonName": settings.buttonName }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.display, U.enums.sourceType.create, U.enums.sourceType.update], "CSL.screen.hasButton", settings.screenId); return Screens.hasCustomButton(settings.screenId, settings.buttonName); }; /** @function CSL.screen.removeButton * @alias CSL.screen.removeButton * @memberof! CSL.screen * @method CSL.screen.removeButton * @description Removes a custom button on the screen with the given name. * @param {Object} options - Specify the options for this method. * @param {String} options.screenId - Specify the id of the screen. * @param {String} options.buttonName - Specify the unique name for the button. * @example * CSL.screen.removeButton({ screenId: sourceId, buttonName: "Go to Google" }); * @throws Will throw an error if any required input field is not set (screenId, buttonName) * @throws Will throw an error when a component with the passed screenId could not be found. */ CSL.screen.removeButton = function (options) { // Defaults var settings = angular.merge({ }, options); checkRequiredInput({ "screenId": settings.screenId, "buttonName": settings.buttonName }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.display, U.enums.sourceType.create, U.enums.sourceType.update], "CSL.screen.removeButton", settings.screenId); $timeout(function () { Screens.removeCustomButton(settings.screenId, settings.buttonName); }); }; /** @function CSL.screen.openCreate * @alias CSL.screen.openCreate * @memberof! CSL.screen * @method CSL.screen.openCreate * @description This function opens the create view of a screen if there's one configured. * @param {Object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @example * var screenConfig = CSL.screen.openCreate({ screenId: sourceId }); * @throws Will throw an error if any required input field is not set (screenId). * @throws Will throw an error when a component with the passed screenId could not be found. * @throws Will throw an error when there's no create view configured on the screen. * @returns {Object} The screen configuration of the newly opened create screen. */ CSL.screen.openCreate = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "screenId": settings.screenId }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.display], "CSL.screen.openCreate", settings.screenId); var viewDefinition = ViewInfo.getViewDefinition(settings.screenId); if (!viewDefinition.views.create.enabled) throw MSG.getMessage("views.createNotEnabled", [settings.gridId]); return Screens.updateScreen({ componentId: component.componentId, screenId: component.screenId, prepareView: component.isWindow ? false : true, isWindow: component.isWindow, sourceType: U.enums.sourceType.create, object: viewDefinition.object, view: viewDefinition.views.create.name, dataItem: component.dataItem }); }; /** @function CSL.screen.openUpdate * @alias CSL.screen.openUpdate * @memberof! CSL.screen * @method CSL.screen.openUpdate * @description This function opens the update view of a screen if there's one configured. * @param {Object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @example * var screenConfig = CSL.screen.openUpdate({ screenId: sourceId }); * @throws Will throw an error if any required input field is not set (screenId). * @throws Will throw an error when a component with the passed screenId could not be found. * @throws Will throw an error when there's no update view configured on the screen. * @returns {Object} The screen configuration of the newly opened update screen. */ CSL.screen.openUpdate = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "screenId": settings.screenId }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.display], "CSL.screen.openUpdate", settings.screenId); var viewDefinition = ViewInfo.getViewDefinition(settings.screenId); if (!viewDefinition.views.update.enabled) throw MSG.getMessage("views.updateNotEnabled", [settings.screenId]); return Screens.updateScreen({ componentId: component.componentId, screenId: component.screenId, prepareView: component.isWindow ? false : true, isWindow: component.isWindow, sourceType: U.enums.sourceType.update, object: viewDefinition.object, view: viewDefinition.views.update.name, dataItem: component.dataItem }); }; /** @function CSL.screen.deleteRecord * @alias CSL.screen.deleteRecord * @memberof! CSL.screen * @method CSL.screen.deleteRecord * @description This function triggers the delete function of a view if there is one configured. * @param {Object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @example * var deletePromise = CSL.screen.deleteRecord({ screenId: sourceId }); * @throws Will throw an error if any required input field is not set (screenId). * @throws Will throw an error when a component with the passed screenId could not be found. * @returns {Promise} A promise because REST calls are being made. Is resolved when the function completed successfully. */ CSL.screen.deleteRecord = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "screenId": settings.screenId }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.display], "CSL.screen.deleteRecord", settings.screenId); var viewDefinition = ViewInfo.getViewDefinition(settings.screenId); if (viewDefinition.views.delete.enabled) { var theFunction = viewDefinition.functions.filter(function (fn) { return fn.name === viewDefinition.views.delete.name; }); if (theFunction.length) { theFunction = theFunction[0]; return Screens.executeFunction({ screenId: settings.screenId, functionId: theFunction.internalName }); } } else { throw MSG.getMessage("views.deletionNotEnabled", [settings.screenId]); } }; /** @function CSL.screen.executeFunction * @alias CSL.screen.executeFunction * @memberof! CSL.screen * @method CSL.screen.executeFunction * @description This function executes the given function on the screen. * @param {Object} options - Specify the options for this function. * @param {string} options.screenId - Specify the unique identifier of the screen. * @param {string} options.functionName - Specify the name of the function. * @example * CSL.screen.executeFunction({ screenId: sourceId, functionName: "Copy" }); * @throws Will throw an error if any required input field is not set (screenId and functionName). * @throws Will throw an error when a component with the passed screenId could not be found. * @throws Will throw an error if the passed in function could not be found on the screen. * @returns {Promise} A promise because REST calls are being made. Is resolved when the function completed successfully. */ CSL.screen.executeFunction = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Controls = $injector.get("OControlService"); ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "screenId": settings.screenId, "functionName": settings.functionName }); // Try to get the component var component = getComponent(settings.screenId); throwIfComponentNotFound(component, settings.screenId); checkAllowedComponents(component, [U.enums.sourceType.display], "CSL.screen.executeFunction", settings.screenId); var viewDefinition = ViewInfo.getViewDefinition(settings.screenId); var theFunction = viewDefinition.functions.filter(function (fn) { return fn.name === settings.functionName; }); if (theFunction.length) { theFunction = theFunction[0]; return Screens.executeFunction({ screenId: settings.screenId, functionId: theFunction.internalName }); } else { return Screens.executeFunction({ screenId: settings.screenId, functionId: "" }); } }; /*---------------------------------- * * GRID * *--------------------------------*/ /** * Contains all the methods for custom scripting on a grid * @memberof CSL * @namespace CSL.grid * @name CSL.grid * @type {object} */ CSL.grid = {}; /** * @function CSL.grid.export * @alias CSL.grid.export * @memberof! CSL.grid * @method CSL.grid.export * @description Triggers the export functionality of a grid * @example * CSL.grid.export({ gridId: sourceId }) * @param {object} options - Specify the options for this function. * @param {string} options.gridId - Specify the unique identifier of the grid. * @returns {Promise} A promise that is resolved when exporting has finished. */ CSL.grid.export = function (options) { // Defaults var settings = angular.merge({}, options); checkRequiredInput({ gridId: settings.gridId }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.export", settings.gridId); var outputDirs = Grids.getOutputDirectories(settings.gridId); return Grids.export(settings.gridId, outputDirs); } /** * @function CSL.grid.progress * @alias CSL.grid.progress * @memberof! CSL.grid * @method CSL.grid.progress * @description Shows or hides the progress indicator on the grid. * @example * CSL.grid.progress({ gridId: sourceId }) * @example * CSL.grid.progress({ gridId: sourceId, progress: false }) * @param {object} options - Specify the options for this function. * @param {string} options.gridId - Specify the unique identifier of the grid. * @param {boolean} [options.progress=true] - Specify whether the progress indicator should be shown or hidden. */ CSL.grid.progress = function (options) { // Defaults var settings = angular.merge({ progress: true }, options); checkRequiredInput({ gridId: settings.gridId }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.progress", settings.gridId); var kendoGrid = Grids.getKendoGrid(settings.gridId); kendoGrid._progress(settings.progress); } /** * @function CSL.grid.getSelectedItems * @alias CSL.grid.getSelectedItems * @memberof! CSL.grid * @method CSL.grid.getSelectedItems * @description Gets the selected items for the given grid. * @param {object} options - Specify the options for this function. * @param {string} options.gridId - Specify the unique identifier of the grid. * @param {boolean} [options.raw=false] - Specify whether the raw keys should be used. The raw keys are the internal field names instead of the labels. * @example * var selectedItems = CSL.grid.getSelectedItems({ gridId: sourceId, raw: false }); * @returns {object[]} Returns an array of selected rows. */ CSL.grid.getSelectedItems = function (options) { // Defaults var settings = angular.merge({ raw: false }, options); // Load services Context = $injector.get("OContextService"); checkRequiredInput({ "gridId": settings.gridId }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.getSelectedItems", settings.gridId); var selectedItems = Grids.getSelectedItems(settings.gridId); // If the raw data source rows should be resolved into readable context rows var contextRows = []; angular.forEach(selectedItems, function (item) { if (settings.raw) { contextRows.push(item); } else { contextRows.push(Context.getContextByDataItem(settings.gridId, item)[0]); } }); return contextRows; } /** @function CSL.grid.mode * @alias = CSL.grid.mode * @memberof! CSL.grid * @method CSL.grid.mode * @description Gets the current mode of the grid. This is either "display" or "editing". "display" is used when the grid is just showing the data, * "editing" describes the situation where the grid is in inline edit mode * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @example * var gridMode = CSL.grid.mode({ gridId: sourceId }); * @throws Will throw an error if any required input field is not set (gridId). * @throws Will throw an error when a component with the passed gridId could not be found. * @returns {string} "display" when the grid is showing data, "editing" when the grid is in inline edit mode. */ CSL.grid.mode = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "gridId": settings.gridId }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.mode", settings.gridId); return Grids.isInEditMode(settings.gridId) ? "editing" : "display"; }; /** @function CSL.grid.select * @alias CSL.grid.select * @memberof! CSL.grid * @method CSL.grid.select * @description This functions selects the given record(s) in the multirecord view. Only records of the current page can be selected. A $scope.$apply() is needed! * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @param {Integer} options.rowNumber - Specify the row number of the row(s) to select. The first row is 1, the second row is 2, ... Can be an array. * @param {String} options.rowKey - Specify the row key of the row(s) to select. This is the unique key value. Can be an array. * @example * var allSelectedItems = CSL.grid.select({ gridId: sourceId, rowNumber: [1, 3], rowKey: "P00-1" }); * @throws Will throw an error if any required input field is not set (gridId). * @throws Will throw an error when a component with the passed gridId could not be found. * @returns {Object} Returns the currently selected items in the grid. */ CSL.grid.select = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "gridId": settings.gridId }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.select", settings.gridId); // Select the row numbers if (U.isDefined(settings.rowNumber)) { settings.rowNumber = U.ensureArray(settings.rowNumber); angular.forEach(settings.rowNumber, function (number, index) { Grids.selectRow(settings.gridId, number - 1); }); } // Select the row keys if (U.isDefined(settings.rowKey)) { var pageData = CSL.grid.getPageData({ gridId: settings.gridId }); settings.rowKey = U.ensureArray(settings.rowKey); angular.forEach(pageData, function (dataItem, index) { if (settings.rowKey.indexOf(dataItem.key) > -1) Grids.selectRow(settings.gridId, index); }); } return Grids.getSelectedItems(settings.gridId); }; /** @function CSL.grid.selectAll * @alias CSL.grid.selectAll * @memberof! CSL.grid * @method CSL.grid.selectAll * @description This function selects all rows in the current page of the grid. A $scope.$apply() is needed! * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @example * var selectedItems = CSL.grid.selectAll({ gridId: sourceId }); * @throws Will throw an error if any required input field is not set (gridId). * @throws Will throw an error when a component with the passed gridId could not be found. * @returns {Object} Returns the currently selected items in the grid. */ CSL.grid.selectAll = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "gridId": settings.gridId }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.selectAll", settings.gridId); // Trigger the select all method Grids.selectAllRows(settings.gridId); return Grids.getSelectedItems(settings.gridId); }; /** @function CSL.grid.unselect * @alias CSL.grid.unselect * @memberof! CSL.grid * @method CSL.grid.unselect * @description This functions unselects the given record(s) in the multirecord view. Only records of the current page can be unselected. A $scope.$apply() is needed! * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @param {Integer} options.rowNumber - Specify the row number of the row(s) to select. The first row is 1, the second row is 2, ... Can be an array. * @param {String} options.rowKey - Specify the row key of the row(s) to select. This is the unique key value. Can be an array. * @example * var allSelectedItems = CSL.grid.unselect({ gridId: sourceId, rowNumber: [3], rowKey: "P00-1" }); * @throws Will throw an error if any required input field is not set (gridId). * @throws Will throw an error when a component with the passed gridId could not be found. * @returns {Object} Returns the currently selected items in the grid. */ CSL.grid.unselect = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "gridId": settings.gridId }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.unselect", settings.gridId); // Select the row numbers if (U.isDefined(settings.rowNumber)) { settings.rowNumber = U.ensureArray(settings.rowNumber); angular.forEach(settings.rowNumber, function (number, index) { Grids.unselectRow(settings.gridId, number); }); } // Select the row keys if (U.isDefined(settings.rowKey)) { var pageData = Grids.getPageData(settings.gridId); settings.rowKey = U.ensureArray(settings.rowKey); angular.forEach(pageData, function (dataItem, index) { if (settings.rowKey.indexOf(dataItem.key) > -1) Grids.unselectRow(settings.gridId, index + 1); }); } return Grids.getSelectedItems(settings.gridId); }; /** @function CSL.grid.unselectAll * @alias CSL.grid.unselectAll * @memberof! CSL.grid * @method CSL.grid.unselectAll * @description This function unselects all rows in the current page of the grid. A $scope.$apply() is needed! * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @example * var selectedItems = CSL.grid.unselectAll({ gridId: sourceId }); * @throws Will throw an error if any required input field is not set (gridId). * @throws Will throw an error when a component with the passed gridId could not be found. * @returns {Object} Returns the currently selected items in the grid. */ CSL.grid.unselectAll = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "gridId": settings.gridId }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.unselectAll", settings.gridId); // Trigger the select all method Grids.unselectAllRows(settings.gridId); return Grids.getSelectedItems(settings.gridId); }; /** @function CSL.grid.openInlineEditing * @alias CSL.grid.openInlineEditing * @memberof! CSL.grid * @method CSL.grid.openInlineEditing * @description Puts the grid in inline edit mode if it isn't already. If it is already in edit mode, nothing will happen. * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * CSL.grid.openInlineEditing({ gridId: sourceId }); * @throws Will throw an error if any required input field is not set (gridId). * @throws Will throw an error when a component with the passed gridId could not be found. */ CSL.grid.openInlineEditing = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "gridId": settings.gridId }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.openInlineEditing", settings.gridId); var kendoGrid = Grids.getKendoGrid(settings.gridId); // Trigger the select all method if (!Grids.isInEditMode(settings.gridId)) kendoGrid.$angular_scope.$parent.$ctrl.editList(); }; /** @function CSL.grid.openCreate * @alias CSL.grid.openCreate * @memberof! CSL.grid * @method CSL.grid.openCreate * @description This function opens the create view that is configured on the grid. * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @example * var screenId = CSL.grid.openCreate({ gridId: sourceId }); * @throws Will throw an error if any required input field is not set (gridId). * @throws Will throw an error when a component with the passed gridId could not be found. * @throws Will throw an error when the grid has no create view configured. * @returns {String} Returns the unique identifier of the opened screen. */ CSL.grid.openCreate = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "gridId": settings.gridId }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.openCreate", settings.gridId); if (!component.views.create.enabled) throw MSG.getMessage("views.createNotEnabled", [settings.gridId]); return Grids.openScreen.create(settings.gridId); }; /** @function CSL.grid.openSingleRecord * @alias CSL.grid.openSingleRecord * @memberof! CSL.grid * @method CSL.grid.openSingleRecord * @description This function opens the single record view that is configured on the grid for the passed in row. If both options.rowNumber and options.rowKey are set, options.rowNumber will be taken. * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @param {Integer} options.rowNumber - Specify the number of the row. The first row is 1, the second row is 2, ... * @param {String} options.rowKey - Specify the row key. This is the unique value of the row. * @example * var screenId = CSL.grid.openSingleRecord({ gridId: sourceId, rowNumber: 1 }); * @throws Will throw an error if any required input field is not set (gridId). * @throws Will throw an error when a component with the passed gridId could not be found. * @throws Will throw an error when the grid has no single record view configured. * @returns {String} Returns the unique identifier of the opened screen. */ CSL.grid.openSingleRecord = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "gridId": settings.gridId, "rowNumber or rowKey": settings.rowNumber || settings.rowKey }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.openSingleRecord", settings.gridId); if (!component.views.read.enabled) throw MSG.getMessage("views.singleRecordNotEnabled", [settings.gridId]); // Get the data item var dataItem; var pageData = Grids.getPageData(settings.gridId); if (U.isDefined(settings.rowNumber)) { if (angular.isDefined(pageData[settings.rowNumber - 1])) dataItem = pageData[settings.rowNumber - 1]; else return null; } else if (U.isDefined(settings.rowKey)) { angular.forEach(pageData, function (di, index) { if (di.key == settings.rowKey) dataItem = di; }); } if (angular.isDefined(dataItem)) return Grids.openScreen.read(settings.gridId, dataItem.uid); else return null; }; /** @function CSL.grid.openUpdate * @alias CSL.grid.openUpdate * @memberof! CSL.grid * @method CSL.grid.openUpdate * @description This function opens the update view that is configured on the grid for the passed in row. If both options.rowNumber and options.rowKey are set, options.rowNumber will be taken. * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @param {Integer} options.rowNumber - Specify the number of the row. The first row is 1, the second row is 2, ... * @param {String} options.rowKey - Specify the row key. This is the unique value of the row. * @example * var screenId = CSL.grid.openSingleRecord({ gridId: sourceId, rowNumber: 1 }); * @throws Will throw an error if any required input field is not set (gridId). * @throws Will throw an error when a component with the passed gridId could not be found. * @throws Will throw an error when the grid has no update view configured. * @returns {String} Returns the unique identifier of the opened screen. */ CSL.grid.openUpdate = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "gridId": settings.gridId, "rowNumber or rowKey": settings.rowNumber || settings.rowKey }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.openUpdate", settings.gridId); if (!component.views.update.enabled) throw MSG.getMessage("views.updateNotEnabled", [settings.gridId]); // Get the data item var dataItem; var pageData = Grids.getPageData(settings.gridId); if (U.isDefined(settings.rowNumber)) { if (angular.isDefined(pageData[settings.rowNumber - 1])) dataItem = pageData[settings.rowNumber - 1]; else return null; } else if (U.isDefined(settings.rowKey)) { angular.forEach(pageData, function (di, index) { if (di.key == settings.rowKey) dataItem = di; }); } if (angular.isDefined(dataItem)) return Grids.openScreen.update(settings.gridId, dataItem.uid); else return null; }; /** @function CSL.grid.saveInlineEditChanges * @alias = CSL.grid.saveInlineEditChanges * @memberof! CSL.grid * @method CSL.grid.saveInlineEditChanges * @description Checks if there are changes in inline editing. If there are, they will be saved. When all records have been saved successfully, * it optionally closes the inline edit mode. Only applies for grids that have Batch editing. * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @param {boolean} [options.stayInEditMode=true] - Specify wheter inline edit mode should remain active after saving. * @example * CSL.grid.saveInlineEditChanges({ gridId: sourceId, stayInEditMode: false }); * @throws Will throw an error if any required input field is not set (gridId and rowNumber or rowKey). * @throws Will throw an error when a component with the passed gridId could not be found. */ CSL.grid.saveInlineEditChanges = function (options) { // Defaults var settings = angular.merge({ stayInEditMode: true }, options); // Load services checkRequiredInput({ "gridId": settings.gridId, }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.saveInlineEditChanges", settings.gridId); var allowedInlineEditModes = [U.enums.inlineEditing.batch]; if (allowedInlineEditModes.indexOf(component.views.update.inlineEditing.mode) === -1) throw MSG.getMessage("CSL.grid.wrongInlineEditMode", ["CSL.grid.saveInlineEditChanges", settings.componentId, allowedInlineEditModes.join(", ")]); if (Grids.hasPendingChanges(settings.gridId)) Grids.saveChanges(settings.gridId, settings.stayInEditMode); else if (!settings.stayInEditMode) { var kendoGrid = Grids.getKendoGrid(settings.gridId); Grids.stopEditList(settings.gridId, kendoGrid.$angular_scope.$parent.$ctrl.$scope); } }; /** @function CSL.grid.cancelInlineEdit * @alias = CSL.grid.cancelInlineEdits * @memberof! CSL.grid * @method CSL.grid.cancelInlineEdit * @description Checks if there are changes in inline editing. If there are, they will be canceled. * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @example * CSL.grid.cancelInlineEdit({ gridId: sourceId }); * @throws Will throw an error if any required input field is not set (gridId and rowNumber or rowKey). * @throws Will throw an error when a component with the passed gridId could not be found. */ CSL.grid.cancelInlineEdit = function (options) { // Defaults var settings = angular.merge({ stayInEditMode: true }, options); // Load services checkRequiredInput({ "gridId": settings.gridId, }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.cancelInlineEdit", settings.gridId); var allowedInlineEditModes = [U.enums.inlineEditing.batch, U.enums.inlineEditing.recordButtons, U.enums.inlineEditing.recordRowLeave]; if (allowedInlineEditModes.indexOf(component.views.update.inlineEditing.mode) === -1) throw MSG.getMessage("CSL.grid.wrongInlineEditMode", ["CSL.grid.cancelInlineEdit", settings.componentId, allowedInlineEditModes.join(", ")]); Grids.cancelEditList(settings.gridId) }; /** @function CSL.grid.closeInlineEdit * @alias = CSL.grid.closeInlineEdit * @memberof! CSL.grid * @method CSL.grid.closeInlineEdit * @description Stops inline editing on the grid. If there are pending changes and closing is not forced, the cancel flow is used which shows a popup requesting * what you want to do with the pending changes. * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @param {boolean} [options.force=true] - Specify whether you want to force closing when there are pending changes. * @example * CSL.grid.closeInlineEdit({ gridId: sourceId, force: false }); * @throws Will throw an error if any required input field is not set (gridId). * @throws Will throw an error when a component with the passed gridId could not be found. */ CSL.grid.closeInlineEdit = function (options) { // Defaults var settings = angular.merge({ force: true }, options); // Load services checkRequiredInput({ "gridId": settings.gridId, }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.closeInlineEdit", settings.gridId); var allowedInlineEditModes = [U.enums.inlineEditing.batch, U.enums.inlineEditing.recordButtons, U.enums.inlineEditing.recordRowLeave]; if (allowedInlineEditModes.indexOf(component.views.update.inlineEditing.mode) === -1) throw MSG.getMessage("CSL.grid.wrongInlineEditMode", ["CSL.grid.closeInlineEdit", settings.componentId, allowedInlineEditModes.join(", ")]); if (Grids.hasPendingChanges(settings.gridId) && !settings.force) Grids.cancelEditList(settings.gridId) else Grids.stopEditList(settings.gridId, Grids.getKendoGrid(settings.gridId).$angular_scope.$parent.$ctrl.$scope) }; /** @function CSL.grid.setCellValue * @alias CSL.grid.setCellValue * @memberof! CSL.grid * @method CSL.grid.setCellValue * @description Sets the value for a cell in a grid. If no rowKey or rowNumber is specified, the current editable record is taken. * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @param {String} options.viewFieldName - Specify the name of the view field. * @param {*} options.value - The value to set. * @param {Integer} [options.rowNumber] - Specify the number of the row. The first row is 1, the second row is 2, ... * @param {String} [options.rowKey] - Specify the row key. This is the unique value of the row. * @example * // Sets the value of 1 for the current record * CSL.grid.setCellValue({ gridId: sourceId, viewFieldName: "Product Category Id", value: 1); * @throws Will throw an error if any required input field is not set (gridId and rowNumber or rowKey). * @throws Will throw an error when a component with the passed gridId could not be found. */ CSL.grid.setCellValue = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services var Grids = $injector.get("OGridService"); var ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "gridId": settings.gridId }); // Get the controller scope var kendoGrid = Grids.getKendoGrid(settings.gridId); var gridController = kendoGrid.$angular_scope.$parent.$ctrl; var viewDefinition = ViewInfo.getViewDefinition(settings.gridId); // Try to get the view field configuration var viewField = ViewInfo.getViewFieldByOriginalName(CSL.grid.mode({ gridId: settings.gridId }) === "editing" ? viewDefinition.views.update.inlineEditing.componentId : settings.gridId, settings.viewFieldName); throwIfViewFieldNotFound(viewField, settings.gridId, settings.viewFieldName); var column = gridController.kendoGrid.columns.filter(function (column) { return column.field === viewField.config.methodOutputField; })[0]; var updateCell = function (di, col) { // Set the value in the cell directly when updating var cell = gridController.kendoGrid.tbody.find('tr[data-uid=' + di.uid + '] td[aria-describedby=' + col.headerAttributes.id + ']'); var formattingOptions = null; if (viewField.config.fieldType.toLowerCase() === "link") { formattingOptions = { parseAsTag: Grids.isInEditMode(settings.gridId), context: Context.getContextByDataItem(viewField.gridId, di)[0] }; } var formattedValue = viewField.runtime.toCultureString(settings.value, formattingOptions); $fw(cell).html("<span class='k-dirty'></span>" + formattedValue); } if (U.isUndefined(settings.rowNumber) && U.isUndefined(settings.rowKey) && U.isDefined(gridController.editableDataItem)) { if (angular.isDefined(gridController.updateViewFields[viewField.config.internalName].setControlValue)) gridController.updateViewFields[viewField.config.internalName].setControlValue(settings.value); else { if (Grids.isInEditMode(settings.gridId)) { var InlineEditing = $injector.get("OInlineEditingService"); InlineEditing.recordValue(settings.gridId, gridController.editableDataItem.key, viewField.config.methodOutputField, settings.value); } else gridController.editableDataItem.set(viewField.config.methodOutputField, settings.value); } updateCell(gridController.editableDataItem, column); return settings.value; } else if (U.isDefined(settings.rowNumber) || U.isDefined(settings.rowKey)) { // Get the data item var dataItem; var pageData = Grids.getPageData(settings.gridId); if (U.isDefined(settings.rowNumber)) { if (angular.isDefined(pageData[settings.rowNumber - 1])) dataItem = pageData[settings.rowNumber - 1]; else return null; } else if (U.isDefined(settings.rowKey)) { angular.forEach(pageData, function (di, index) { if (di.key == settings.rowKey) dataItem = di; }); } updateCell(dataItem, column); if (Grids.isInEditMode(settings.gridId)) { var InlineEditing = $injector.get("OInlineEditingService"); InlineEditing.recordValue(settings.gridId, dataItem.key, viewField.config.methodOutputField, settings.value); } else { dataItem.set(viewField.config.methodOutputField, settings.value); } return dataItem[viewField.config.methodOutputField]; } }; /** @function CSL.grid.render * @alias CSL.grid.render * @memberof! CSL.grid * @method CSL.grid.render * @description This function renders all the rows of the grid. When a value is being changed through custom scripting, this method should be called. * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @example * // Sets the value of the field YesNo to true for all the records * var pageData = CSL.grid.getPageData({ gridId: window.sourceId }); * * for(var i = 0; i < pageData.length; i++){ * CSL.grid.setCellValue({ * rowKey: pageData[i].key, * viewFieldName: "YesNo", * gridId: sourceId * }); * } * * CSL.grid.render({ gridId: sourceId }); * @throws Will throw an error if any required input field is not set (gridId). * @throws Will throw an error when a component with the passed gridId could not be found. */ CSL.grid.render = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services var Grids = $injector.get("OGridService"); checkRequiredInput({ "gridId": settings.gridId }); // Get the controller scope var kendoGrid = Grids.getKendoGrid(settings.gridId); if (angular.isDefined(kendoGrid)) kendoGrid.refresh(); }; /** @function CSL.grid.deleteRecord * @alias CSL.grid.deleteRecord * @memberof! CSL.grid * @method CSL.grid.deleteRecord * @description This function triggers the delete function for a row on the grid. * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @param {Integer} options.rowNumber - Specify the number of the row. The first row is 1, the second row is 2, ... * @param {String} options.rowKey - Specify the row key. This is the unique value of the row. * @example * CSL.grid.deleteRecord({ gridId: sourceId, rowNumber: 1 }); * @throws Will throw an error if any required input field is not set (gridId and rowNumber or rowKey). * @throws Will throw an error when a component with the passed gridId could not be found. * @throws Will throw an error if the specified function was not found. * @returns {Promise} Returns the promise of the OFunctionService for executing the function. This promise receives notifications about the execution step. If you * want to show these notifications on the grid, it is your responsibility to add/change a notification. */ CSL.grid.deleteRecord = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "gridId": settings.gridId, "rowNumber or rowKey": settings.rowNumber || settings.rowKey }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.deleteRecord", settings.gridId); // Get the data item var dataItem; var pageData = Grids.getPageData(settings.gridId); if (U.isDefined(settings.rowNumber)) { if (angular.isDefined(pageData[settings.rowNumber - 1])) dataItem = pageData[settings.rowNumber - 1]; else return null; } else if (U.isDefined(settings.rowKey)) { angular.forEach(pageData, function (di, index) { if (di.key == settings.rowKey) dataItem = di; }); } return CSL.grid.executeFunction({ gridId: settings.gridId, functionName: "Delete", dataItems: dataItem }); }; /** @function CSL.grid.executeFunction * @alias CSL.grid.executeFunction * @memberof! CSL.grid * @method CSL.grid.executeFunction * @description This function executes a list item function on the grid * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @param {String} options.functionName - Specify the name of the function you want to execute. * @param {Object} options.dataItems - Specify the data item or array of data items you want to use for the execution of the function. Can be an array. * @example * CSL.grid.executeFunction({ gridId: sourceId, functionName: "Copy", dataItems: [....] }); * @throws Will throw an error if any required input field is not set (gridId, functionName). * @throws Will throw an error when a component with the passed gridId could not be found. * @throws Will throw an error if the specified function was not found. * @returns {Promise} Returns the promise of the OFunctionService for executing the function. This promise receives notifications about the execution step. If you * want to show these notifications on the grid, it is your responsibility to add/change a notification. */ CSL.grid.executeFunction = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "gridId": settings.gridId, "functionName": settings.functionName }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.executeFunction", settings.gridId); var kendoGrid = Grids.getKendoGrid(settings.gridId); return Grids.executeListItemFunction({ functionId: settings.functionName, ctrl: kendoGrid.$angular_scope.$ctrl, dataItems: settings.dataItems, gridId: settings.gridId }); }; /** @function CSL.grid.getPageData * @alias CSL.grid.getPageData * @memberof! CSL.grid * @method CSL.grid.getPageData * @description This function gets the data from the current page in the grid. * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @param {Boolean} [options.returnNames=false] - If false, page data is returned with the view field internal names as keys.. If true, page data is returned with the view field names as keys. * @example * var pageData = CSL.grid.getPageData({ gridId: sourceId, returnNames: true }); * pageDate.forEach(function(pageRow){ ...... }) * @throws Will throw an error if any required input field is not set (gridId). * @throws Will throw an error when a component with the passed gridId could not be found. * @returns {Object[]} Returns the current page data objects. */ CSL.grid.getPageData = function (options) { // Defaults var settings = angular.merge({ returnNames: false }, options); // Load services checkRequiredInput({ "gridId": settings.gridId }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.getPageData", settings.gridId); return Grids.getPageData(settings.gridId, settings.returnNames); }; /** @function CSL.grid.getCellValue * @alias CSL.grid.getCellValue * @memberof! CSL.grid * @method CSL.grid.getCellValue * @description Gets the value of a cell in a row. If no row number is defined, the distinct cell values are returned. * @param {Object} options - Specify the options for this function. * @param {String} options.gridId - Specify the unique identifier of the grid. * @param {String} options.viewFieldName - Specify the name of the view field to get the value from. * @param {Integer} [options.rowIndex] - Specify the index of the row to get the value from. * @example * var stockValue = CSL.grid.getCellValue({ gridId: sourceId, viewFieldName: "Product Stock", rowIndex: 3 }); * @returns {*} The value of the cell or an array of cell values. */ CSL.grid.getCellValue = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services ViewInfo = $injector.get("OViewInfoService"); checkRequiredInput({ "gridId": settings.gridId, "viewFieldName": settings.viewFieldName }); var pageData = CSL.grid.getPageData({ gridId: settings.gridId, returnNames: true }); if (angular.isDefined(settings.rowIndex)) { if (angular.isDefined(pageData[settings.rowIndex])) { return pageData[settings.rowIndex][settings.viewFieldName]; } } else { var returnValues = []; angular.forEach(pageData, function (rowData) { if (returnValues.indexOf(rowData[settings.viewFieldName]) === -1) returnValues.push(rowData[settings.viewFieldName]); }); return returnValues; } }; /** @function CSL.grid.addActionCondition * @alias CSL.grid.addActionCondition * @memberof! CSL.grid * @method CSL.grid.addActionCondition * @description This function adds a condition to an action that can be done on the grid. If one of the conditions has failed, the user is not allowed to * execute the action and the button/icon/... will be hidden if defined otherwise. Be aware that keeping the button/icon/... shown will not block the functionallity! * @param {Object} options - Specify the options for this method. * @param {String} options.gridId - Specify the id of the grid. * @param {String} options.name - Specify the unique name of the condition. * @param {actionEnum} options.action - Specify a value from the actions enumeration: openCreate, openUpdate, openSingleRecord, setRowAsContext, executeFunction, editList * @param {Function} options.condition - Specify a function that checks whether the action is allowed. * @param {String} [options.functionName] - Specify the name of the function if the action is execute function. * @param {Boolean} [options.triggerExecution=false] - Specify whether execution of the conditions should be triggered immediately. Default is false. * @param {Boolean} [options.hideRowIcon=true] - Specify whether the row icon of the icon should be hidden if possible. Default is true. * @param {Boolean} [options.hideToolbarButton=true] - Specify whether the toolbar button should be hidden if possible. Default is true. * @example * CSL.grid.addActionCondition({ * gridId: sourceId, * name: "DisableEditForLockedRecords", * action: "openUpdate", * condition: function(rowData){ return !rowData["Locked"]; }, * triggerExecution: true, * hideRowIcon: true, * hideToolbarButton: true * }); * @throws Will throw an error if any required input field is not set (gridId, functionName). * @throws Will throw an error when a component with the passed gridId could not be found. * @throws Will throw an error if you try to add a condition with a name that already exists for that action. */ CSL.grid.addActionCondition = function (options) { // Defaults var settings = angular.merge({ triggerExecution: false, hideRowIcon: true, hideToolbarButton: true }, options); var newFunction = function (gridData) { return !settings.condition(gridData) } if (settings.hideRowIcon) { CSL.grid.setListItemFunctionHideCondition({ gridId: settings.gridId, functionNames: [settings.action], condition: newFunction }); } if (settings.hideToolbarButton) { CSL.grid.setToolbarButtonHideCondition({ gridId: settings.gridId, functionNames: [settings.action], initialValue: true, condition: newFunction }); } }; /** @function CSL.grid.removeActionCondition * @alias CSL.grid.removeActionCondition * @memberof! CSL.grid * @method CSL.grid.removeActionCondition * @description Removes a condition from a specific action * @param {Object} options - Specify the options for this method * @param {String} options.gridId - Specify the id of the grid * @param {actionEnum} options.action - Specify an enumeration value from the actions enumeration: openCreate, openUpdate, openSingleRecord, setRowAsContext, executeFunction, editList * @param {String} options.name - Specify the name of the action * @param {Boolean} [options.triggerExecution=false] - Specify whether execution of the conditions should be triggered immediately. Default is false. * @example * CSL.grid.removeActionCondition({ gridId: sourceId, action: "openCreate", name: "DisableEditForLockedRecords" }) */ CSL.grid.removeActionCondition = function (options) { // Defaults var settings = angular.merge({ triggerExecution: false }, options); // Load services checkRequiredInput({ "gridId": settings.gridId, "name": settings.name, "action": settings.action }); // Try to get the component var component = getComponent(settings.gridId); throwIfComponentNotFound(component, settings.gridId); checkAllowedComponents(component, [U.enums.sourceType.grid], "CSL.grid.removeActionCondition", settings.gridId); Grids.removeActionCondition({ gridId: settings.gridId, name: settings.name, action: settings.action, triggerExecution: settings.triggerExecution }); }; /** @function CSL.grid.setRowStyling * @alias CSL.grid.setRowStyling * @memberof! CSL.grid * @method CSL.grid.setRowStyling * @description Set the styling (color, background color, ...) of a row based on a condition. The condition will be executed for each row. * @param {Object} options - Specify the options for this method * @param {String} options.gridId - Specify the id of the grid * @param {Function} options.condition - Specify a function condition that returns an object or string of CSS styling. The first parameter of the function is rowData. This contains the data of the row where the key is the name of the view field * @param {Boolean} [options.returnPromise=false] - Specify whether a promise is returned. You typically return a promise when doing asynchronous actions. By doing so the performance will decrease (approx. 150 - 250ms for 100 rows). * @example * // Sets the value of the product name context field to Bubble gum. * CSL.grid.setRowStyling({ * gridId: sourceId, * condition: function(rowData) { * if (rowData["Product Active"] === "True") { * // Object return example. * return { "background-color": "green", color: "white" }; * } else if (rowData["Product Active"] === "False") { * // String return example. * return "background-color:green; color:white"; * } * } * }); */ CSL.grid.setRowStyling = function (options) { var settings = angular.merge({ returnPromise: false }, options); checkRequiredInput({ "gridId": settings.gridId, "condition": settings.condition }); if (!Grids) Grids = $injector.get("OGridService"); Grids.executeRowStylingCondition({ gridId: settings.gridId, condition: settings.condition, returnPromise: settings.returnPromise }); } /** * @function CSL.grid.setFieldStyling * @param {object} options - The options to set styling on fields in a grid. * @param {options.gridId} - The id of the grid to find the fields on. * @param {options.fieldNames} - The field names to set the styling on. * @param {options.condition} - the style condition that returns a style object or style string. * @example * CSL.grid.setFieldStyling({ * gridId: sourceId, * fieldNames: ['productName', 'productStock'], * condition: function (rowData) { * if (parseInt(rowData["productStock"]) >= 0) { * return { "background-color": "green", color: "white" }; * } else { * return {"background-color": "red", "color": "white"}; * } * } * }); */ CSL.grid.setFieldStyling = function (options) { var settings = angular.merge({ returnPromise: false }, options); checkRequiredInput({ "gridId": settings.gridId, "condition": settings.condition }); if (!Grids) Grids = $injector.get("OGridService"); Grids.executeFieldStylingCondition({ gridId: settings.gridId, viewFields: settings.fieldNames, condition: settings.condition, returnPromise: settings.returnPromise }); } /** @function CSL.grid.setListItemFunctionStyling * @memberof! CSL.grid * @description Set the styling (color, background color, ...) of a listItemFunction field based on a condition. The condition will be executed for each row. * @param {Object} options - Specify the options for this method * @param {String} options.gridId - Specify the id of the grid * @param {String[]} options.functionNames - The names of the functions to style. * @param {Function} options.condition - Specify a function condition that returns an object or string of CSS styling. The first parameter of the function is rowData. This contains the data of the row where the key is the name of the view field * @param {Boolean} [options.returnPromise=false] - Specify whether a promise is returned. You typically return a promise when doing asynchronous actions. By doing so the performance will decrease (approx. 150 - 250ms for 100 rows). * @example * CSL.grid.setListItemFunctionStyling({ * gridId: sourceId, * functionNames: ['AddToStock'], * condition: function (rowData) { * if (parseInt(rowData["productStock"]) >= 0) { * return "background-color:green;color:white"; * } else { * return "background-color:red;color:white"; * } * } * }); */ CSL.grid.setListItemFunctionStyling = function (options) { var settings = angular.merge({ returnPromise: false }, options); checkRequiredInput({ "gridId": settings.gridId, "condition": settings.condition, "functionNames": settings.functionNames }); if (!Grids) Grids = $injector.get("OGridService"); Grids.executeLifStylingCondition({ gridId: settings.gridId, condition: settings.condition, functionNames: settings.functionNames, returnPromise: settings.returnPromise }); } /** @function CSL.grid.setListItemFunctionHideCondition * @memberof! CSL.grid * @description Set the condition to hide a ListItemFunction in the grid. * @param {Object} options - Specify the options for this method * @param {String} options.gridId - Specify the id of the grid * @param {String[]} options.functionNames - The names of the functions to style. * @param {Function} options.condition - Specify a function condition that returns a boolean. The first parameter of the function is rowData. This contains the data of the row where the key is the name of the view field * @param {Boolean} [options.returnPromise=false] - Specify whether a promise is returned. You typically return a promise when doing asynchronous actions. By doing so the performance will decrease (approx. 150 - 250ms for 100 rows). * @example * CSL.grid.setListItemFunctionHideCondition({ * gridId: sourceId, * functionNames: ['AddToStock'], * condition: function (rowData) { * if (parseInt(rowData["productStock"]) >= 0) { * return true; * } else { * return false; * } * } * }); */ CSL.grid.setListItemFunctionHideCondition = function (options) { var settings = angular.merge({ returnPromise: false, }, options); checkRequiredInput({ "gridId": settings.gridId, "condition": settings.condition, "functionNames": settings.functionNames }); if (!Grids) Grids = $injector.get("OGridService"); Grids.executeLifHideCondition({ gridId: settings.gridId, condition: settings.condition, functionNames: settings.functionNames, returnPromise: settings.returnPromise }); } /** @function CSL.grid.setToolbarButtonStyleCondition * @memberof! CSL.grid * @description Set the condition to hide a ListItemFunction in the grid. * @param {Object} options - Specify the options for this method * @param {String} options.gridId - Specify the id of the grid * @param {String[]} options.functionNames - The names of the functions to style. * @param {string | Object} initialValue - The initial value to set on the toolbar button. * @param {Function} options.condition - Specify a function condition that returns a boolean. The first parameter of the function is rowData. This contains the data of the row where the key is the name of the view field * @param {Boolean} [options.returnPromise=false] - Specify whether a promise is returned. You typically return a promise when doing asynchronous actions. By doing so the performance will decrease (approx. 150 - 250ms for 100 rows). * @example * CSL.grid.setToolbarButtonStyleCondition({ * gridId: sourceId, * functionNames: ['AddToStock'], * initialValue: {'background-color': 'red'}, * condition: function (gridData) { * if (gridData.length > 10) { * return {'background-color': 'red'}; * } else { * return {'background-color': 'green'}; * } * } * }); */ CSL.grid.setToolbarButtonStyleCondition = function (options) { var settings = angular.merge({ returnPromise: false, initialValue: {} }, options); checkRequiredInput({ "gridId": settings.gridId, "condition": settings.condition, "functionNames": settings.functionNames }); if (!Grids) Grids = $injector.get("OGridService"); Grids.executeToolbarButtonStyleCondition({ gridId: settings.gridId, functionNames: settings.functionNames, returnPromise: settings.returnPromise, condition: settings.condition, initialValue: settings.initialValue, useInitialValue: true }); } /** @function CSL.grid.setToolbarButtonHideCondition * @memberof! CSL.grid * @description Set the condition to hide a ListItemFunction in the grid. * @param {Object} options - Specify the options for this method * @param {String} options.gridId - Specify the id of the grid * @param {String[]} options.functionNames - The names of the functions to style. * @param {Function} options.condition - Specify a function condition that returns a boolean. The first parameter of the function is rowData. This contains the data of the row where the key is the name of the view field * @param {Boolean} [options.returnPromise=false] - Specify whether a promise is returned. You typically return a promise when doing asynchronous actions. By doing so the performance will decrease (approx. 150 - 250ms for 100 rows). * @example * CSL.grid.setToolbarButtonHideCondition({ * gridId: sourceId, * functionNames: ['AddToStock'], * initialValue: true, * condition: function (gridData) { * if (gridData.length > 10) { * return true; * } else { * return false; * } * } * }); */ CSL.grid.setToolbarButtonHideCondition = function (options) { var settings = angular.merge({ returnPromise: false, initialValue: true }, options); checkRequiredInput({ "gridId": settings.gridId, "condition": settings.condition, "functionNames": settings.functionNames }); if (!Grids) Grids = $injector.get("OGridService"); Grids.executeToolbarButtonHideCondition({ gridId: settings.gridId, functionNames: settings.functionNames, returnPromise: settings.returnPromise, condition: settings.condition, initialValue: settings.initialValue, useInitialValue: true }); } /*---------------------------------- * * CONTEXT MANAGER * *--------------------------------*/ /** * Contains all the methods for custom scripting on a context manager * @memberof CSL * @namespace CSL.contextManager * @name CSL.contextManager * @type {object} */ CSL.contextManager = {}; /** @function CSL.contextManager.search * @alias CSL.contextManager.search * @memberof! CSL.contextManager * @method CSL.contextManager.search * @description Triggers the search functionallity of a context manager. * @param {Object} options - Specify the options for this function. * @param {String} options.componentId - Specify the id of the context manager. * @example * CSL.contextManager.search({ componentId: sourceId }); */ CSL.contextManager.search = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "componentId": settings.componentId }); // Try to get the component var component = getComponent(settings.componentId); throwIfComponentNotFound(component, settings.componentId); checkAllowedComponents(component, [U.enums.sourceType.cm, U.enums.sourceType.create, U.enums.sourceType.update, U.enums.sourceType.display], "CSL.contextManager.search", settings.componentId); Context.submitContextManager(settings.componentId); }; /** @function CSL.contextManager.clear * @alias CSL.contextManager.clear * @memberof! CSL.contextManager * @method CSL.contextManager.clear * @description Triggers the clear functionallity of a context manager. * @param {Object} options - Specify the options for this function. * @param {String} options.componentId - Specify the id of the context manager. * @example * CSL.contextManager.clear({ componentId: sourceId }); */ CSL.contextManager.clear = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services checkRequiredInput({ "componentId": settings.componentId }); // Try to get the component var component = getComponent(settings.componentId); throwIfComponentNotFound(component, settings.componentId); checkAllowedComponents(component, [U.enums.sourceType.cm, U.enums.sourceType.create, U.enums.sourceType.update, U.enums.sourceType.display], "CSL.contextManager.clear", settings.componentId); Context.clearContextManager(componentId); }; /** @function CSL.contextManager.getFullContext * @alias CSL.contextManager.getFullContext * @memberof! CSL.contextManager * @method CSL.contextManager.getFullContext * @description Retrieves all the context that has been set. * @example * var allContext = CSL.contextManager.getFullContext(); * @returns {Object} Returns an object that is a key-value pair of fields with their values. */ CSL.contextManager.getFullContext = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services Context = $injector.get("OContextService"); return Context.extendWithContextManagerContext({}); }; /** @function CSL.contextManager.getContextValue * @alias CSL.contextManager.getContextValue * @memberof! CSL.contextManager * @method CSL.contextManager.getContextValue * @description Retrieves the value for a context field. * @param {Object} options - Specify the options for this function. * @param {String} options.fieldName - Specify the name of the field. * @example * var productId = CSL.contextManager.getContextValue({ fieldName: "Product Id" }); * @returns {*} Returns the value for that field or undefined if it was not found in the context. */ CSL.contextManager.getContextValue = function (options) { // Defaults var settings = angular.merge({ fieldName: "" }, options); // Load services return CSL.contextManager.getFullContext()[settings.fieldName]; }; /** @function CSL.contextManager.setContextValue * @memberof! CSL.contextManager * @method CSL.contextManager.setContextValue * @description Sets one or more context fields. * @param {Object} options - Specify the options for this function. * @param {Object} options.context - Specify a context object. The key should be the name of the view field. The value is the value to set as context. * @example * // Sets the value of the product name context field to Bubble gum. * CSL.contextManager.setContextValue({ * context: { * "product name": "Bubble gum" * } * }); */ CSL.contextManager.setContextValue = function (options) { // Default var settings = angular.merge({ context: {} }, options); checkRequiredInput({ "context": settings.context }); // Load services Context = $injector.get("OContextService"); Context.setContextManagerContext(settings.context); } /*---------------------------------- * * COMPONENT * *--------------------------------*/ /** * Contains all the methods for custom scripting on a context manager * @memberof CSL * @namespace CSL.component * @name CSL.component * @type {object} */ CSL.component = {}; /** * @function CSL.component.getAll * @alias CSL.component.getAll * @memberof! CSL.component * @method CSL.component.getAll * @description Gets all the components on the page. * @example * CSL.component.getAll(); * @example * CSL.component.getAll({ getOriginalState: true }); * @param {object} options - Specify the options for this function. * @param {boolean} [options.getOriginalState=false] - Return the original states of the component instead of the current state. * @param {boolean} [options.pickersOnly=false] - Return only the picker sources. * @returns {object[]} An array of objects containing the id, object name and view name of a component. */ CSL.component.getAll = function (options) { // Defaults var settings = angular.merge({ getOriginalState: false, pickersOnly: false }, options); // Get all the sources var sources = F.getSources(); // Loop through the sources for the data var allComponents = []; angular.forEach(sources, function (source) { var state = settings.getOriginalState ? source.original : source.current; allComponents.push({ id: source.componentId, object: state.object, view: state.view, picker: source.picker }); }); if (settings.pickersOnly) { return allComponents.filter(function (component) { return component.picker && component.picker.exists; }); } else { return allComponents; } }; /** * @function CSL.component.getByName * @alias CSL.component.getByName * @memberof! CSL.component * @method CSL.component.getByName * @description Gets a single component on the page by its object and view name. * @example * CSL.component.getByName({ object: "PurchaseOrderHeader", view: "Get All Purchase Order Headers"}); * @param {object} options - Specify the options for this function. * @param {string} options.object - Specify the object name. * @param {string} options.view - Specify the view name. * @param {boolean} [options.getOriginalState=false] - Return the original states of the component instead of the current state. * @param {boolean} [options.pickersOnly=false] - Return only the picker sources. * @returns {object[]} An array of objects containing the id, object name and view name of the component if found. */ CSL.component.getByName = function (options) { // Defaults var settings = angular.merge({ getOriginalState: false, pickersOnly: false }, options); checkRequiredInput({ "object": settings.object, "view": settings.view }); // Get all the components var allComponents = CSL.component.getAll(settings); // Search for the provided object and view var foundComponents = []; angular.forEach(allComponents, function (current) { if (current.object === settings.object && current.view === settings.view) { foundComponents.push(current); } }); return foundComponents; }; /** @function CSL.component.reload * @alias CSL.component.reload * @memberof! CSL.component * @method CSL.component.reload * @description Reloads the component * @param {object} options - Specify the options for this function. * @param {string} [options.componentId] - Specify the id of the component(s) to reload. Can be an array. * @param {object} [options.componentConfig] - Specify the configuration for a component. Can be an array. * @param {string} [options.componentConfig.object] - Specify the object that contains the view. * @param {string} [options.componentConfig.view] - Specify the name of the view. * @exclude * var components = CSL.component.getAll(); * components.forEach(function(component){ * CSL.component.reload({ componentId: component.componentId }); * }); */ CSL.component.reload = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services ADM = $injector.get("OAdmService"); checkRequiredInput({ "componentId or componentConfig": settings.componentId || settings.componentConfig }); var sources = F.getSources(); var sourceComponentIds = sources.map(function (s) { return s.componentId; }); var sourceComponentConfigs = sources.map(function (s) { return { componentId: s.componentId, original: { object: s.original.object, view: s.original.view }, current: { object: s.current.object, view: s.current.view } } }); var componentsToReload = []; if (angular.isDefined(settings.componentId)) { settings.componentId = U.ensureArray(settings.componentId); angular.forEach(settings.componentId, function (id) { if (sourceComponentIds.indexOf(id) > -1) componentsToReload.push(id); }); } if (angular.isDefined(settings.componentConfig)) { settings.componentConfig = U.ensureArray(settings.componentConfig); angular.forEach(sources, function (s) { angular.forEach(settings.componentConfig, function (config) { if ( (config.object === s.original.object && config.view === s.original.view) || (config.object === s.current.object && config.view === s.current.view) ) componentsToReload.push(s.componentId); }); }); } ADM.reloadAdm(componentsToReload); }; /*---------------------------------- * * UTILITY * *--------------------------------*/ /** * Contains all the utility methods for custom scripting * @memberof CSL * @namespace CSL.utility * @name CSL.utility * @type {object} */ CSL.utility = {}; /** @function CSL.utility.getRestUrl * @alias CSL.utility.getRestUrl * @memberof! CSL.utility * @method CSL.utility.getRestUrl * @description Returns the current REST Service url from the utility service. * @returns {String} Returns the current REST Service url. */ CSL.utility.getRestUrl = function () { return U.getRestUrl(); }; /** @function * @alias CSL.utility.randomString * @memberof! CSL.utility * @method CSL.utility.randomString * @description This function creates a random string for a given amount of characters. By default, 5 characters are used. * @param {Object} options - Specify the options for this method. * @param {Integer} options.stringLength - Specify the amount of characters to use. * @returns {String} Returns the randomly generated string. */ CSL.utility.randomString = function (options) { // Defaults var settings = angular.merge({ length: 5 }, options); // Load services return U.newId(settings.length); }; /** @function CSL.utility.isUndefined * @alias CSL.utility.isUndefined * @memberof! CSL.utility * @method CSL.utility.isUndefined * @description This function checks whether the passed variable is undefined. Shorthand version for a typeof check. * @param {Object} options - Specify the options for this method. * @param {*} options.variable - Specify the variable you want to check. * @returns {Boolean} Returns a boolean indicating whether the variable is undefined. */ CSL.utility.isUndefined = function (options) { return U.isUndefined(options.variable); }; /** @function CSL.utility.isUndefinedOrEmpty * @alias CSL.utility.isUndefinedOrEmpty * @memberof! CSL.utility * @method CSL.utility.isUndefinedOrEmpty * @description This function checks whether the passed variable is undefined or empty. A variable is empty when it is null or an empty string. * @param {Object} options - Specify the options for this method. * @param {*} options.variable - Specify the variable you want to check. * @returns {Boolean} Returns a boolean indicating whether the variable is undefined or empty. */ CSL.utility.isUndefinedOrEmpty = function (options) { return U.isUndefinedOrEmpty(options.variable); }; /** @function CSL.utility.isDefined * @alias CSL.utility.isDefined * @memberof! CSL.utility * @method CSL.utility.isDefined * @description This function checks whether the passed variable is defined. A variable is defined when it's not undefined or null. * @param {Object} options - Specify the options for this method. * @param {*} options.variable - Specify the variable you want to check. * @returns {Boolean} Returns a boolean indicating whether the variable is defined. */ CSL.utility.isDefined = function (options) { return U.isDefined(options.variable); }; /** @function CSL.utility.getFile * @alias CSL.utility.getFile * @memberof! CSL.utility * @method CSL.utility.getFile * @description This function receives the url of a file and tries to get the file with the $http service from Angular. The file contents are returned in the response. * @param {Object} options - Specify the options for this method. * @param {*} options.url - Specify the url of the file. * @param {bool} options.cache - Specify if you want to cache the file in the session storage. If the file is large (> 50 000 bytes) we do not recommend it to cache the file. * @returns {Promise} Returns a promise for receiving the file. */ CSL.utility.getFile = function (options) { // Defaults var settings = angular.merge({ url: "", cache: false }, options); return U.getFile(settings.url, settings.cache); }; /** @function CSL.utility.cleanArray * @alias CSL.utility.cleanArray * @memberof! CSL.utility * @method CSL.utility.cleanArray * @description This function removes items from an array. Typically used for removing empty items. * @param {Object} options - Specify the options for this method. * @param {*} options.array - Specify the array to clean. * @param {*} options.valueToRemove - Specify the value to remove from the array. * @returns {*} Returns a cleaned array. Items that equaled the provided value to remove are no longer in the array. */ CSL.utility.cleanArray = function (options) { return U.cleanArray(options.array, options.valueToRemove); }; /** @function CSL.utility.format * @alias CSL.utility.format * @memberof! CSL.utility * @method CSL.utility.format * @description This function formats the specified text to add dynamic arguments. The string can contain placeholders like C#: {0}, {1}, ... * @param {Object} options - Specify the options for this method. * @param {String} options.text - Specify the unformatted string. * @param {*} options.values - Specify an array of values. The item at index 0 will replace {0} and so on. * @returns {String} Returns the formatted string. */ CSL.utility.format = function (options) { return U.format(options.text, options.values); }; /** @function CSL.utility.getDescendantProp * @alias CSL.utility.getDescendantProp * @memberof! CSL.utility * @method CSL.utility.getDescendantProp * @description This function searches an object for a property based on a dot notation. * @param {Object} options - Specify the options for this method. * @param {Object} options.data - Specify the object to look in. * @param {string} options.property - Specify the property you want to receive the value from. This is specified in a dot notation like a normal JavaScript object. * @returns REturns the value of the property or undefined if nothing was found. */ CSL.utility.getDescendantProp = function (options) { return U.getDescendantProp(options.data, options.property); }; CSL.utility.enums = U.enums; /*---------------------------------- * * REST SERVICE * *--------------------------------*/ /** * Contains all the methods for calling the REST service with custom scripting * @memberof CSL * @namespace CSL.rest * @name CSL.rest * @type {object} */ CSL.rest = {}; /** @function CSL.rest.prepareView * @alias CSL.rest.prepareView * @memberof! CSL.rest * @method CSL.rest.prepareView * @description Calls the prepareView endpoint of the REST call service for the given object and view. Request options can be passed as well. Request options that will be set by default * are CurrentUser, SourceSystem, SourceIdentifier and LocaleId. * @param {Object} options - Specify the options for this method. * @param {string} options.object - Specify the name of the object of the view to prepare. * @param {string} options.view - Specify the name of the view to prepare. * @param {Object} [options.requestOptions] - Specify the request options for this method. * @param {Object} [options.requestOptions.Context] - Specify the context records to send to the REST service. Can be an array. * @param {string[]} [options.requestOptions.RowKeys] - Specify a unique identifier for each record of the Context property. * @param {Object} [options.requestOptions.QueryOptions] - Specify the options for the query that prepares the view. * @param {integer} [options.requestOptions.QueryOptions.FirstItem] - Specify the index of the first item that has to be fetched. * @param {Integer} [options.requestOptions.QueryOptions.PageSize] - Specify the amount of records to fetch. * @param {Object} [options.requestOptions.QueryOptions.Expression] - Specify a filter object that is returned from the CSL.filter.parseFilterExpression method. * @param {Object} [options.requestOptions.QueryOptions.OrderByFields] - Specify a sort object that is returned from the CSL.filter.parseSortExpression method. * @throws Will throw an error if any required input field has not been set. * @returns {Promise} A promise that is resolved when the call is successfully executed. If the call failed, the promise is rejected. */ CSL.rest.prepareView = function (options) { // Defaults var settings = angular.merge({ requestOptions: {} }, options); // Load services var R = $injector.get("ORestCallService"); checkRequiredInput({ "object": settings.object, "view": settings.view }); var controller = getComponentScope(); return R.prepareView({ object: settings.object, view: settings.view, requestOptions: settings.requestOptions, scope: controller }); }; /** @function CSL.rest.executeView * @alias CSL.rest.executeView * @memberof! CSL.rest * @method CSL.rest.executeView * @description Calls the executeView endpoint of the REST call service for the given object and view. Request options can be passed as well. Request options that will be set by default * are CurrentUser, SourceSystem, SourceIdentifier and LocaleId. * @param {Object} options - Specify the options for this method. * @param {string} options.object - Specify the name of the object of the view to execute. * @param {string} options.view - Specify the name of the view to execute. * @param {Object} [options.requestOptions] - Specify the request options for this method. * @param {Object} [options.requestOptions.Context] - Specify the context records to send to the REST service. Can be an array. * @param {string[]} [options.requestOptions.RowKeys] - Specify a unique identifier for each record of the Context property. * @param {Object} [options.requestOptions.QueryOptions] - Specify the options for the query that prepares the view. * @param {integer} [options.requestOptions.QueryOptions.FirstItem] - Specify the index of the first item that has to be fetched. * @param {Integer} [options.requestOptions.QueryOptions.PageSize] - Specify the amount of records to fetch. * @param {Object} [options.requestOptions.QueryOptions.Expression] - Specify a filter object that is returned from the CSL.filter.parseFilterExpression method. * @param {Object} [options.requestOptions.QueryOptions.OrderByFields] - Specify a sort object that is returned from the CSL.filter.parseSortExpression method. * @throws Will throw an error if any required input field has not been set. * @returns {Promise} A promise that is resolved when the call is successfully executed. If the call failed, the promise is rejected. */ CSL.rest.executeView = function (options) { // Defaults var settings = angular.merge({ requestOptions: {} }, options); // Load services var R = $injector.get("ORestCallService"); checkRequiredInput({ "object": settings.object, "view": settings.view }); return R.executeView({ object: settings.object, view: settings.view, requestOptions: settings.requestOptions }); }; /** @function CSL.rest.executeMethod * @alias CSL.rest.executeMethod * @memberof! CSL.rest * @method CSL.rest.executeMethod * @description Calls the executeMethod endpoint of the REST call service for the given object and method. Request options can be passed as well. Request options that will be set by default * are CurrentUser, SourceSystem, SourceIdentifier and LocaleId. * @param {Object} options - Specify the options for this method. * @param {string} options.object - Specify the name of the object of the method to execute. * @param {string} options.method - Specify the name of the method to execute. * @param {string} options.profile - Specify the profile to execute the method on. * @param {Object} [options.requestOptions] - Specify the request options for this method. * @param {Object} [options.requestOptions.Context] - Specify the context records to send to the REST service. Can be an array. * @param {string[]} [options.requestOptions.RowKeys] - Specify a unique identifier for each record of the Context property. * @param {Object} [options.requestOptions.QueryOptions] - Specify the options for the query that prepares the view. * @param {integer} [options.requestOptions.QueryOptions.FirstItem] - Specify the index of the first item that has to be fetched. * @param {Integer} [options.requestOptions.QueryOptions.PageSize] - Specify the amount of records to fetch. * @param {Object} [options.requestOptions.QueryOptions.Expression] - Specify a filter object that is returned from the CSL.filter.parseFilterExpression method. * @param {Object} [options.requestOptions.QueryOptions.OrderByFields] - Specify a sort object that is returned from the CSL.filter.parseSortExpression method. * @throws Will throw an error if any required input field has not been set. * @returns {Promise} A promise that is resolved when the call is successfully executed. If the call failed, the promise is rejected. */ CSL.rest.executeMethod = function (options) { // Defaults var settings = angular.merge({ requestOptions: {} }, options); // Load services var R = $injector.get("ORestCallService"); checkRequiredInput({ "object": settings.object, "method": settings.method, "profile": settings.profile }); return R.executeMethod({ object: settings.object, method: settings.method, profile: settings.profile, requestOptions: settings.requestOptions }); }; /** @function CSL.rest.executeMultiRecord * @alias CSL.rest.executeMultiRecord * @memberof! CSL.rest * @method CSL.rest.executeMultiRecord * @description Calls the executeMultiRecord endpoint of the REST call service for the given object and multi record view. Request options can be passed as well. Request options that will be set by default * are CurrentUser, SourceSystem, SourceIdentifier and LocaleId. * @param {Object} options - Specify the options for this method. * @param {string} options.object - Specify the name of the object of the multi record view to execute. * @param {string} options.view - Specify the name of the multi view to execute. * @param {Object} [options.requestOptions] - Specify the request options for this method. * @param {Object} [options.requestOptions.Context] - Specify the context records to send to the REST service. Can be an array. * @param {string[]} [options.requestOptions.RowKeys] - Specify a unique identifier for each record of the Context property. * @param {Object} [options.requestOptions.QueryOptions] - Specify the options for the query that prepares the view. * @param {integer} [options.requestOptions.QueryOptions.FirstItem] - Specify the index of the first item that has to be fetched. * @param {Integer} [options.requestOptions.QueryOptions.PageSize] - Specify the amount of records to fetch. * @param {Object} [options.requestOptions.QueryOptions.Expression] - Specify a filter object that is returned from the CSL.filter.parseFilterExpression method. * @param {Object} [options.requestOptions.QueryOptions.OrderByFields] - Specify a sort object that is returned from the CSL.filter.parseSortExpression method. * @throws Will throw an error if any required input field has not been set. * @returns {Promise} A promise that is resolved when the call is successfully executed. If the call failed, the promise is rejected. */ CSL.rest.executeMultiRecord = CSL.rest.executeView; /** @function CSL.rest.getFilterValues * @alias CSL.rest.getFilterValues * @memberof! CSL.rest * @method CSL.rest.getFilterValues * @description Calls the getFilterValues endpoint of the REST call service for the given object, view and view field. Request options can be passed as well. Request options that will be set by default * are CurrentUser, SourceSystem, SourceIdentifier and LocaleId. * @param {Object} options - Specify the options for this method. * @param {string} options.object - Specify the name of the object of the multi record view. * @param {string} options.view - Specify the name of the multi record view to execute. * @param {string} options.viewFieldName - Specify the name of the view field in the multi record view. * @param {Object} [options.requestOptions] - Specify the request options for this method. * @param {Object} [options.requestOptions.Context] - Specify the context records to send to the REST service. Can be an array. * @param {string[]} [options.requestOptions.RowKeys] - Specify a unique identifier for each record of the Context property. * @param {Object} [options.requestOptions.QueryOptions] - Specify the options for the query that prepares the view. * @param {integer} [options.requestOptions.QueryOptions.FirstItem] - Specify the index of the first item that has to be fetched. * @param {Integer} [options.requestOptions.QueryOptions.PageSize] - Specify the amount of records to fetch. * @param {Object} [options.requestOptions.QueryOptions.Expression] - Specify a filter object that is returned from the CSL.filter.parseFilterExpression method. * @param {Object} [options.requestOptions.QueryOptions.OrderByFields] - Specify a sort object that is returned from the CSL.filter.parseSortExpression method. * @throws Will throw an error if any required input field has not been set. * @returns {Promise} A promise that is resolved when the call is successfully executed. If the call failed, the promise is rejected. */ CSL.rest.getFilterValues = function (options) { // Defaults var settings = angular.merge({ requestOptions: {} }, options); // Load services var R = $injector.get("ORestCallService"); checkRequiredInput({ "object": settings.object, "view": settings.view, "viewFieldName": settings.viewFieldName }); return R.getFilterValues({ object: settings.object, view: settings.view, viewField: settings.viewFieldName, requestOptions: settings.requestOptions }); }; /** @function CSL.rest.validateValue * @alias CSL.rest.validateValue * @memberof! CSL.rest * @method CSL.rest.validateValue * @description Calls the validateValue endpoint of the REST call service for the given object, view and validation values. Request options can be passed as well. Request options that will be set by default * are CurrentUser, SourceSystem, SourceIdentifier and LocaleId. * @param {Object} options - Specify the options for this method. * @param {string} options.object - Specify the name of the object of the multi record view. * @param {string} options.view - Specify the name of the multi record view to execute. * @param {Object} options.requestOptions - Specify the request options for this method. * @param {Object} options.requestOptions.ValuesToValidate - Specify the values to validate. The key is the name of the view field, the value an array of values to validate. * @param {Object} [options.requestOptions.Context] - Specify the context records to send to the REST service. Can be an array. * @param {string[]} [options.requestOptions.RowKeys] - Specify a unique identifier for each record of the Context property. * @param {Object} [options.requestOptions.QueryOptions] - Specify the options for the query that prepares the view. * @param {integer} [options.requestOptions.QueryOptions.FirstItem] - Specify the index of the first item that has to be fetched. * @param {Integer} [options.requestOptions.QueryOptions.PageSize] - Specify the amount of records to fetch. * @param {Object} [options.requestOptions.QueryOptions.Expression] - Specify a filter object that is returned from the CSL.filter.parseFilterExpression method. * @param {Object} [options.requestOptions.QueryOptions.OrderByFields] - Specify a sort object that is returned from the CSL.filter.parseSortExpression method. * @throws Will throw an error if any required input field has not been set. * @returns {Promise} A promise that is resolved when the call is successfully executed. If the call failed, the promise is rejected. */ CSL.rest.validateValue = function (options) { // Defaults var settings = angular.merge({ requestOptions: {} }, options); // Backwards compatibility: it could be possible that validationValues is still used instead of ValuesToValidate if (angular.isDefined(settings.requestOptions.validationValues) && angular.isUndefined(settings.requestOptions.ValuesToValidate)) settings.requestOptions.ValuesToValidate = settings.requestOptions.validationValues; // Load services var R = $injector.get("ORestCallService"); checkRequiredInput({ "object": settings.object, "view": settings.view, "requestOptions.ValuesToValidate": settings.requestOptions.ValuesToValidate }); // Make sure that all passed values are in an array angular.forEach(settings.ValuesToValidate, function (value, key) { value = U.ensureArray(value); }); return R.validateValue({ object: settings.object, view: settings.view, requestOptions: settings.requestOptions }); }; /** @function CSL.rest.getViewFieldDataSourceOutput * @alias CSL.rest.getViewFieldDataSourceOutput * @memberof! CSL.rest * @method CSL.rest.getViewFieldDataSourceOutput * @description Calls the getViewFieldDataSourceOutput endpoint of the REST call service for the given object and view. Request options can be passed as well. Request options that will be set by default * are CurrentUser, SourceSystem, SourceIdentifier and LocaleId. The output directories have to be specified in the requestOptions.Context property. * @param {Object} options - Specify the options for this method. * @param {string} options.object - Specify the name of the object of the multi record view. * @param {string} options.view - Specify the name of the multi record view to execute. * @param {Object} options.requestOptions - Specify the request options for this method. * @param {Object} options.requestOptions.Context - Specify the context records to send to the REST service. Can be an array. * @param {string[]} [options.requestOptions.RowKeys] - Specify a unique identifier for each record of the Context property. * @param {Object} [options.requestOptions.QueryOptions] - Specify the options for the query that prepares the view. * @param {integer} [options.requestOptions.QueryOptions.FirstItem] - Specify the index of the first item that has to be fetched. * @param {Integer} [options.requestOptions.QueryOptions.PageSize] - Specify the amount of records to fetch. * @param {Object} [options.requestOptions.QueryOptions.Expression] - Specify a filter object that is returned from the CSL.filter.parseFilterExpression method. * @param {Object} [options.requestOptions.QueryOptions.OrderByFields] - Specify a sort object that is returned from the CSL.filter.parseSortExpression method. * @throws Will throw an error if any required input field has not been set. * @returns {Promise} A promise that is resolved when the call is successfully executed. If the call failed, the promise is rejected. */ CSL.rest.getViewFieldDataSourceOutput = function (options) { // Defaults var settings = angular.merge({ requestOptions: {} }, options); // Load services var R = $injector.get("ORestCallService"); // Backwards compatibility: it could be possible that validationValues is still used instead of ValuesToValidate if (angular.isDefined(settings.requestOptions.Context) && angular.isUndefined(settings.requestOptions.FieldsWithOutputIds)) settings.requestOptions.FieldsWithOutputIds = settings.requestOptions.Context; checkRequiredInput({ "object": settings.object, "view": settings.view, "requestOptions": settings.requestOptions, "requestOptions.FieldsWithOutputIds": settings.requestOptions.FieldsWithOutputIds }); return R.getViewFieldDataSourceOutput({ object: settings.object, view: settings.view, requestOptions: settings.requestOptions }); }; /** @function CSL.rest.getViewFieldNameOfMethodField * @alias CSL.rest.getViewFieldNameOfMethodField * @memberof! CSL.rest * @method CSL.rest.getViewFieldNameOfMethodField * @description Returns the view field name of the given method output field * @param {Object} options - Specify the options for this method. * @param {string} options.id - Specify the unique identifier of the screen or grid * @param {string} options.methodField - Specify the method output field * @returns {string} The name of the view field */ CSL.rest.getViewFieldNameOfMethodField = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services var R = $injector.get("ORestCallService"); checkRequiredInput({ "id": settings.id, "methodField": settings.methodField }); return R.getViewFieldNameOfMethodField(settings.id, settings.methodField); }; /** @function CSL.rest.getViewFieldInternalName * @alias CSL.rest.getViewFieldInternalName * @memberof! CSL.rest * @method CSL.rest.getViewFieldInternalName * @description Get the internal name (the client safe id) of the view field name. * @param {Object} options - Specify the options for this method. * @param {string} options.id - Specify the id of the screen or grid. * @param {String} options.viewFieldName - The original name of the view field. * @returns {String} The internal name (a guid which always begins with a letter) of the view field. */ CSL.rest.getViewFieldInternalName = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services var R = $injector.get("ORestCallService"); checkRequiredInput({ "id": settings.id, "viewFieldName": settings.viewFieldName }); return R.getViewFieldInternalName(settings.id, settings.viewFieldName); }; /** @function CSL.rest.getViewFieldNameByInternalName * @alias CSL.rest.getViewFieldNameByInternalName * @memberof! CSL.rest * @method CSL.rest.getViewFieldNameByInternalName * @description Get the original name of the view field internal name. * @param {Object} options - Specify the options for this method. * @param {string} options.id - Specify the id of the screen or grid. * @param {String} options.viewFieldInternalName - The internal name of the view field. * @returns {String} The original name of the view field. */ CSL.rest.getViewFieldNameByInternalName = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services var R = $injector.get("ORestCallService"); checkRequiredInput({ "id": settings.id, "viewFieldInternalName": settings.viewFieldInternalName }); return R.getViewFieldNameByInternalName(settings.id, settings.viewFieldInternalName); }; /** @function CSL.rest.getViewFieldInternalNameByMethodFieldId * @alias CSL.rest.getViewFieldInternalNameByMethodFieldId * @memberof! CSL.rest * @method CSL.rest.getViewFieldInternalNameByMethodFieldId * @description Get the internal name (the client safe id) of the view field for the given method output field. * @param {Object} options - Specify the options for this method. * @param {string} options.id - Specify the id of the screen or grid. * @param {String} options.methodField - The internal name of the method output field. * @returns {String} The internal name (a guid which always begins with a letter) of the corresponding view field. */ CSL.rest.getViewFieldInternalNameByMethodFieldId = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services var R = $injector.get("ORestCallService"); checkRequiredInput({ "id": settings.id, "methodField": settings.methodField }); return R.getViewFieldInternalNameByMethodFieldId(settings.id, settings.methodField); }; /** @function CSL.rest.getMethodFieldIdByViewFieldName * @alias CSL.rest.getMethodFieldIdByViewFieldName * @memberof! CSL.rest * @method CSL.rest.getMethodFieldIdByViewFieldName * @description Get the internal name (the client safe id) by the original view field name. * @param {Object} options - Specify the options for this method. * @param {string} options.id - Specify the id of the screen or grid. * @param {String} options.viewFieldName - The original name of the view field. * @returns {String} The internal name (a guid which always begins with a letter). */ CSL.rest.getMethodFieldIdByViewFieldName = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services var R = $injector.get("ORestCallService"); checkRequiredInput({ "id": settings.id, "viewFieldName": settings.viewFieldName }); return R.getMethodFieldIdByViewFieldName(settings.id, settings.viewFieldName); }; /** @function CSL.rest.createViewFieldMappings * @alias CSL.rest.createViewFieldMappings * @memberof! CSL.rest * @method CSL.rest.createViewFieldMappings * @description Creates the view field mappings for each screen or grid. * @param {Object} options - Specify the options for this method. * @param {string} options.id - Specify the id of the screen or grid. * @param {Object} options.viewFields - Specify the view field collection. */ CSL.rest.createViewFieldMappings = function (options) { // Defaults var settings = angular.merge({ }, options); // Load services var R = $injector.get("ORestCallService"); checkRequiredInput({ "id": settings.id, "viewFields": settings.viewFields }); return R.createViewFieldMappings(settings.id, settings.viewFields); }; /*---------------------------------- * * KENDO OVERRIDES * *--------------------------------*/ /** * Contains all the methods for overruling kendo stuff with custom scripting * @memberof CSL * @namespace CSL.kendo * @name CSL.kendo * @type {object} */ CSL.kendo = {}; /** * @function CSL.kendo.removeGridBorders * @alias CSL.kendo.removeGridBorders * @memberof! CSL.kendo * @method CSL.kendo.removeGridBorders * @description Removes the css borders of the grid * @param {Object} options - Specify the options for this method. * @param {string} options.gridId - Specify the id of the grid. * @deprecated - Removal of the grid borders is default behaviour. Delete this function in your custom scripting. * @example * CSL.kendo.removeGridBorders({ gridId: sourceId }); */ CSL.kendo.removeGridBorders = function (options) { console.log("The CSL.kendo.removeGridBorders function is deprecated and is no longer supported. Remove this line in your custom scripting."); } /*---------------------------------- * * RETURN * *--------------------------------*/ return CSL; }; angular.module("o.core").factory("OCustomScriptingLibrary", ["$injector", "$q", "$rootScope", "$timeout", CustomScriptingLibrary]); })();