Kendo UI Builder 2.0 introduces a new project structure.

This project structure new has a scripts/extensions folder than can be used to add custom AngularJS modules (app/src/scripts/extensions).

A service define in the custom folder can then be accessed from controller.public.js to provide access to custom code.

Developers using Kendo UI Builder can use a custom module to create their own high level APIs to encapsulate code and re-use it from multiple views. Also, a high level API can be used to minimize the impact on migrating to new versions of Kendo UI Builder.

The usage is of the functionality has three general steps:
Example:
var myService = $injector.get('myService');
Steps

The following steps show the configuration of the files involved on this configuration.

See Documents section for a sample project containing the files:

https://community.progress.com/community_groups/openedge_kendo_ui_builder/m/documents/3361

Files:

  • index.js (scripts/extensions): Add import and reference to custom module in the scripts/extensions/index.js file.
'use strict';

import angular from 'angular';

import myModule from './my-module.js';

export default angular.module('app.extensions.module', [
    'myModule'
]).name;
  • my-module.js (scripts/extensions): Add import and registration of custom service in the module.
  • Note: Service can also be defined in same .js file as module.
'user strict';

import myService from './my-service.js';

var myModule = angular.module('myModule', []);
myModule.service('myService', myService);
  • my-service.js (scripts/extensions): Service definition. Create service instance with methods for high-level API.
  • This example shows APIs: getElement(), getDS() and createLookupColumn().

'user strict';

function service() {
    function MyService() {}

    MyService.prototype = {
        getElement: function (controller, name) {
            return controller.$components[name];
        },        
        getDS: function (controller, name, options) {
            if (controller.$ds[name]) {
                return controller.$ds[name];
            } else {
                return new kendo.data.DataSource(options);
            }
        },
        createLookupColumn: function (controller, grid, options) {
            var columns,
                i,
                column;

            // Find column
            if (controller.$components
                && controller.$components[grid]) {
                columns = controller.$components[grid].options.columns;
            } else {
                columns = controller.$model.options.columns;
            }
            if (columns) {
                for (i = 0; i < columns.length; i += 1) {
                    if (columns[i].field === options.field) {
                        column = columns[i];
                    }
                }
            }

            // Set template and editor properties
            if (column) {
                column.template = function(dataItem) {
                    options.dataSource.filter(
                        {field: options.field, operation: "eq", value: dataItem[options.field]}
                    );
                    var view = options.dataSource.view();
                    if (view.length === 0) {
                        return "<span></span>"
                    } else {
                        return "<span>" + kendo.htmlEncode(view[0][options.displayField]) + "</span>";
                    }
                };

                column.editor = function(container, options1) {
                    var input = $("<input/>");
                    input.attr("name", options1.field);

                    // Clear filter to ensure that all values are shown
                    options.dataSource.filter({});
                    
                    input.appendTo(container);
                    input.kendoDropDownList({
                        dataSource: options.dataSource,
                        dataTextField: options.displayField,
                        dataValueField: options.field,
                    })
                };
            }
        }
    };

    return new MyService();
}

export default service;
  • controller.public.js (module/view folder): This screenshot shows the usage of the custom service "myService" from within the constructor in controller.public.js.
    The code obtains a data source associated with the view and creates a "lookup" column.
    The implementation of the service then executes the appropriate code to set the template and editor properties for the corresponding column in the grid.
import BaseController from './controller.js'

class Module1CustomerViewCtrl extends BaseController {
    constructor($scope, $injector, stateData, myService) {
        super($scope, $injector);

		var controller = this,
            salesrepDS = myService.getDS(controller, 'SalesrepDS');
        
        salesrepDS.read();

        myService.createLookupColumn(controller, 'grid0', {
            dataSource: salesrepDS,
            field: 'SalesRep',
            displayField: 'RepName'
        });
    }

    // Fired when custom html section is loaded
    includeContentLoaded() {

    }

    // Fired when custom html section loading failed
    includeContentError(e) {

    }

    // Fired when view content is loaded
    onShow($scope) {
    }
}

Module1CustomerViewCtrl.$inject = ['$scope', '$injector', 'stateData', 'myService'];

export default Module1CustomerViewCtrl