Please refer to the source code of this page for boilerplates (F12 for console).

1. Wiring up



Notes:
Completely standalone. No extra libraries required (jquery, underscore etc.).
It is recommended to add local fallback version of the library if you use it in production (click "download" on the right).
We bear no responsibility for possible reachability interruption of directly linked components, they are useful to cold start your project and set up testing.

For extended APIs concerning SharePoint and Persistence go to "theobald.ecs" (tEcs+)


If you are experiencing problems with version 5 (removed jQuery prerequisite), please try version 4 (tEcs)

2. Core APIs

tEcs.executeXql()

Example:
{
    data: "SELECT TOP 10 MATNR, MAKTX FROM MAKT"
}



tEcs.executeFunction()

Example:
{
    name: 'Z_ECS_GET_STOCK_INFO',
    data: {
        exports: {
            MATNR: '100-100'
        }
    }
}



tEcs.executeInScope()

Example (same for two functions):
{
    functions: [
        {
            name: "Z_PREPARE_REQ",
            data: {
                PARAMONE: "SOMEVALUE"
            }
        },
        {
            name: "Z_EXEC_REQ",
            data: function(){
                return parametersSapCheck;
            }
        }
    ]
}

3. Usage and configuration

3.1 Start using the library

Use ecs.micro, when it has been initialized:
theobald.ready(function(){
    alert(theobald.ecs.version);
});

3.2 Configuration parameters

"connection" parameter should be passed to each of the above functions!
For ECS on premise this parameter is optional and ecs.micro will be working with defaults out of the box.
var connection = {
    ecs: {
        // ECSCore model, must be "true" for ECSCore
        core: true,
        coreApiKey: "E370FB721AFA4EB2A86CC624E4B6890C",
        // serviceApplication (or "instance"). Context dependent (small/capital symbols)!
        //serviceApplication: "ec2",
        // url to ECSCore
        url: "https://yourecscore.com:8080/ecs",
        // NOTE: For the Azure Relay use postfix "WS"
        //url: "https://[namespace].servicebus.windows.net/ecs/ws"
        // NOTE: To call deployed webservices use postfix "CUSTOM"
        // url: "https://yourecscore.com:8080/ecs/custom/"
        // OR for Azure Relay:
        // url: "https://[SERVICEBUSNAME].servicebus.windows.net/ecs/ws/custom/"
        // OPTIONAL - "withMetadata" - delivers function result with SAP metadata, such as structure sizes, headers, columns.
        // withMetadata: true, // default false
    }
};
Optionally "done" and "fail" handlers could be passed to execute custom actions with result or error.
{
    connection: connection,
    done: function(data) {
        alert('Everything as planned!');
    },
    fail: function(data) {
        alert('Something broke :(');
    }
};
Full example of call executeFunction():
tEcs.executeFunction({
    connection: {
        ecs: {
            core: true,
            coreApiKey: "E370FB721AFA4EB2A86CC624E4B6890C",
            serviceApplication: "ec4",
            url: "https://ecscore.mydomain.com"
        }
    },
    data: {
        exports: {
            MATNR: '100-100'
        }
    },
    done: function(data) {
        alert('Everything as planned!');
    },
    fail: function(data) {
        alert('Something broke :(');
    },
    name: 'Z_ECS_GET_STOCKS'
});
Full example of call executeInScope():
var FUNCTION_TWO_PARAMETERS = {
    exports: {
        PARAMX: 'VALX'
    }
};

tEcs.executeInScope({
    // out of the box commit will be added after given functions
    // commit: true,
    connection: {
        ecs: {
            core: true,
            coreApiKey: "E370FB721AFA4EB2A86CC624E4B6890C",
            serviceApplication: "ec4",
            url: "https://ecscore.mydomain.com"
        }
    },
    // these "done" and "fail" will be executed when all functions are executed
    done: function(data) {
        alert('All funcitons executed!');
    },
    fail: function(data) {
        alert('Something broke :(');
    },
    functions: [
        {
            name: "FUNCTION_ONE",
            data: {
                PARAMONE: "SOMEVALUE"
            },
            // SET VALUES FOR THE NEXT FUNCTION
            done: function(data){
                // updating parameters of next function!
                FUNCTION_TWO_PARAMETERS.exports.PARAMTWO = data.imports.PARAMY;
            }
        },
        {
            name: "FUNCTION_TWO",
            // note, data is a function!
            data: function(){
                return FUNCTION_TWO_PARAMETERS;
            }
        }
    ],
});

4. Extended APIs

4.1. SOAP Calls

Get SOAP XML, calling a WSD-Service from inside of SharePoint:
tEcs.callSoapService({
    //
    // REQUIRED: Name of deployed service
    serviceName: 'SAPCustomerWebService',
    //
    // OPTIONAL: can be put explicitly. If not, then '/_vti_bin/' + serviceName is used
    url: '/_vti_bin/SAPCustomerWebService.svc',
    //
    // Name of action. If not specified, tests the service connection
    actionName: 'GetCustomersByName',
    //
    // JSON of input paramters, OPTIONAL (if no input)
    data: { name: '%' },
    //
    // OPTIONAL: success handler
    done: function(data, status, xhr){ alert('COMPLETED!'); },
    //
    // OPTIONAL: error handler
    fail: function(xhr, status, thrownError){ alert('ERROR!'); },
    // OPTIONAL: will be always executed (on success AND error)
    always: function (data, statusText, errorThrown) { console.log('%o', data); },
    // OPTIONAL: direct overrides of jquery ajax
    ajax: { url: 'http://someserver.com/service.svc', contentType: 'text' //... }
});
Example:
tEcs.callSoapService({
    serviceName: 'GetPersonalDataWebService',
    actionName: 'GetPersonalData',
    data: {
        name: '%',
        surname: 'T*',
        date: '20141230'
    },
    always: function (data, statusText, errorThrown) {
        console.log('GetPersonalDataWebService/GetPersonalData: %o', data);
    }
});

4.2. Testing SAP Connection

tEcs.testSapConnection()

Example:
tEcs.testSapConnection({
    connection: {
        ecs: {
            core: true,
            coreApiKey: "E370FB721AFA4EB2A86CC624E4B6890C",
            serviceApplication: "ec4",
            url: "https://ecscore.mydomain.com"
        }
    }
});

4.3 Live Test of the SAP Connection on YOUR ECSCore installation


To test your own ECS Core Installation and it's SAP Connection on the fly, use the fields below:





4.4. "Live combobox" (loading data in real time)

tEcs.initializeLiveCombobox()

Example:
tEcs.initializeLiveCombobox({
    controls: {
        // for typing
        inputId: input1,
        // dropdown for selection
        selectId: combo1,
        // text field where ID is saved on dropdown select
        outputId: output1,
        // text field where Description is saved on dropdown select
        descriptionId: outputd1
    },
    tableSettings: {
        tableName: "MAKT",
        idField: "MATNR",
        textField: "MAKTX",
        language: "EN"
    },
    // optional
    searchOptions: {
        // default: true.
        useUppercaseValuesForQueries: true,
        removeLeadingZerosFromNumbers: false,
        // custom xql, if you want to build it yourself.
        xql: "SELECT TOP 10 MAKTX FROM MAKT WHERE (MAKTX LIKE '"+ myValue + "')",
        // custom format xql. The parameter "{0}" will be replace by the value typed.
        xqlFormat: "SELECT TOP 10 KUNNR, NAME1 FROM KNA1 WHERE (KUNNR LIKE 'VIP_%' OR NAME1 LIKE '%{0}%') AND SPRAS = 'DE' ",
        // custom messages
        strings: { 
            loading: 'Loading...',
            matches: ' matches',
            noMatchText: 'No direct match!',
            noMatches: 'No matches',
            errComm: 'Communication error, please see console',
            select: 'Please select',
            type: 'Start typing in the input above'
        },
        // use german strings "Wird geladen..." etc.
        german: true
    },
    // optional
    connection: {
        ecs: {
            ...
        }
    }
});

5. ECS Core Management APIs

tEcs.AddCredentialToSecureStore()

Example:
tEcs.AddCredentialToSecureStore({
    connection: {
        ecs: {
            coreApiKey: 'A1E2B883AC3141E29917F41CC92AE82B',
            url: 'https://myservicebus.servicebus.windows.net/ecs/ws'
        }
    },
    SecureStoreName: 'MySecureStore',
    UserOrGroup: 'MYDOMAIN\\MYUSER',
    // sap user
    Username: 'MYSAPUSER',
    // sap password
    Password: 'MYSAPPASSWORD'
});

tEcs.DeleteCredentialFromSecureStore()

Example:
tEcs.DeleteCredentialFromSecureStore({
    connection: {
        ecs: {
            coreApiKey: 'A1E2B883AC3141E29917F41CC92AE82B',
            url: 'https://myservicebus.servicebus.windows.net/ecs/ws'
        }
    },
    SecureStoreName: 'MySecureStore',
    // Secure Store user
    UserOrGroup: 'MYDOMAIN\\MYUSER'
});

tEcs.CheckCredentialInSecureStore()

Example:
tEcs.CheckCredentialInSecureStore({
    connection: {
        ecs: {
            coreApiKey: 'A1E2B883AC3141E29917F41CC92AE82B',
            url: 'https://myservicebus.servicebus.windows.net/ecs/ws'
        }
    },
    SecureStoreName: 'MySecureStore',
    // Secure Store user
    UserOrGroup: 'MYDOMAIN\\MYUSER',
    done: function(checkedOk){
        if(checkedOk){
            alert('Legit user!');
        }
    }
});

All functions return deferred. Done/Fail as parameters supported:
done: function(response){
    if (response === "OK") {
        alert('ALL GOOD!');
    }else{
        console.log(response);
    }
},
fail: function(response){
    console.log(response);
    alert(response.error.message);
}
                    

Live Manage of YOUR ECS Core SecureStore


Try to manage your own ECS Core Installation on the fly, use the fields below:

Connection:



Secure Store parameters:



Required for Add:



6. Typical usage patterns

6.1. Scalar Parameter

to SAP (exports): DELIV_DATE
from SAP (imports): ORDER_NUM
tEcs.executeFunction({
    //connection: {}
    name: 'BAPI_PO_CREATE',
    data: {
        exports: {
            // to SAP
            DELIV_DATE: "20141022"
        },
        done: function(data){
            // from SAP
            alert(data.imports.ORDER_NUM);
        }
    }
});
//
// use an empty object to prepare parameters
var exports = {},
    sapDeliveryDateParameter = "20141022";
//
// set parameters values
exports.DELIV_DATE = sapDeliveryDateParameter;
//
// execute function with parameters
tEcs.executeFunction({
    //connection: {}
    name: 'BAPI_PO_CREATE',
    data: {
        exports: exports
    },
    done: function(data){
        // input scalar parameter
        alert(data.imports.ORDER_NUM);
    }
});

6.2 Vector Parameter

to SAP (exports): PO_HEADER
from SAP (imports): PO_CHECKED
tEcs.executeFunction({
    //connection: {}
    name: 'BAPI_PO_CREATE',
    data: {
        exports: {
            PO_HEADER: {
                    PO_ITEM: "1",
                    DELIV_DATE: "20141022",
                    QUANTITY: 10
            }
        }
    }
});
//
// use an object to prepare a vector parameter
var po_header;
po_header.DOC_TYPE = "NB";
po_header.PURCH_ORG = "1000";
po_header.PUR_GROUP = "010";
po_header.VENDOR = "0000001070";

tEcs.executeFunction({
    //connection: {}
    name: 'BAPI_PO_CREATE',
    data: {
        exports: {
            PO_HEADER: po_header
        }
    },
    done: function(data){
        // read when function is executed
        var po_checked = data.imports.PO_CHECKED;
        // field of the vector parameter
        alert(po_checked.QUANTITY);
    }
});

6.3 Table Parameter

to SAP (exports): PO_ITEM_SCHEDULES
from SAP (imports): PO_ITEM_CHECKED
tEcs.executeFunction({
    //connection: {}
    name: 'BAPI_PO_CREATE',
    data: {
        exports: {
            PO_ITEM_SCHEDULES: [{
                    PO_ITEM: "1",
                    DELIV_DATE: "20141022",
                    QUANTITY: 10
                }
            ]
        }
    }
});
//
// use an array to fill a table
var po_item_schedules = [];
po_item_schedules.push({
    PO_ITEM: "1",
    DELIV_DATE: "20141022",
    QUANTITY: 10
});

tEcs.executeFunction({
    //connection: {}
    name: 'BAPI_PO_CREATE',
    data: {
        tables: {
            PO_ITEM_SCHEDULES: po_item_schedules
        }
    },
    done: function(data){
        // shortcut to array
        var po_item_checked = data.imports.PO_ITEM_CHECKED;
        // first element
        alert(po_item_checked[0]);
    }
});

6.4 Parameters between functions in scope

output first function: VENDORS
input second function (exports): PROVIDERS
// local variable to store required parameters
var parameters_Z_EXEC_REQ = {
    exports: {
        SOME_CONSTANT_PARAMETER: 3
    }
};
tEcs.executeInScope({
    functions: [
        {
            name: "Z_PREPARE_REQ",
            data: {
                PARAMONE: "SOMEVALUE"
            },
            done: function(data){
                // set required for the next function parameter
                parameters_Z_EXEC_REQ.exports.PROVIDERS = data.exports.VENDORS;
            }
        },
        {
            name: "Z_EXEC_REQ",
            // function returns "dynamic" value of parameters, when they were set/updated after first function
            data: function(){
                return parameters_Z_EXEC_REQ;
            }
        }
    ]
})

6.5 Parameters between functions in scope (embedded syncObject)

output first function: VENDORS
input second function (exports): PROVIDERS
//variable to automatically handle in/out parameters
var syncObject = {};
//
tEcs.executeInScope({
    syncObject: syncObject,
    functions: [
        {
            name: "Z_PREPARE_REQ",
            data: {
                PARAMONE: "SOMEVALUE"
            },
            // no "done", nothing special should be made
        },
        {
            name: "Z_EXEC_REQ",
            // function returns "dynamic" value of parameters, when they were set/updated after first function
            data: function(data){
                // when first function is executed,
                // system variable syncObject is set with RESULT from this executed function,
                // so we have access to it through "syncObject" plus executed function name, e.g. "Z_PREPARE_REQ":
                var second_function_parameters = {
                    exports: {
                        PROVIDERS: syncObject.Z_PREPARE_REQ.exports.VENDORS
                    }
                };

                return second_function_parameters;
            }
        }
    ]
})

6.6 Scope commit

tEcs.executeInScope({
    // executes BAPI_TRANSACTION_COMMIT when all functions are executed
    commit: true,
    done: function(data){
        alert('Function chain completed (with Commit)');
    },
    fail: function(data){
        alert(JSON.stringify(data));
    },
    functions: [
        {
            name: "Z_PREPARE_REQ",
            data: {
                PARAMONE: "SOMEVALUE"
            },
            done: function(data){
                alert('Custom action after first function!');
            }
        }
    ]
})

6.7 Composing functions

//executes asynchroneously SAP-function and XQL-Query
// when both are executed, print results
theobald.Deferred.when(
    tEcs.executeFunction({ name: "Z_GET_MY_USERNAME" },
    tEcs.executeXql({query: "SELECT TOP 10 MAKTX FROM MAKT"}))
.then(function(result1, result2){
    // prints my username
    console.log(result1.exports.USR_NAME);
    // prints materials
    console.log(result2)
})

6.8 Requesting function metadata

tEcs.createSapFunction({
    name: 'Z_PREPARE_REQ',
    done: function(data){
        // data contains all structures and metadata
        window.mySapFunctionMetadata = data;
        console.log(data);
    },
    fail: function(data){
        console.log(data);
    }
})

You can then manually set all required parameters and pass them to tEcs.executeSapFunction:
tEcs.executeSapFunction({
    data: window.mySapFunctionMetadata,
    done: function(data){
        // data contains all structures and metadata after execution
        console.log(data);
    },
    fail: function(data){
        console.log(data);
    }
})

If you require metadata after execution, set "withMetadata" parameter of tEcs.executeFunction:
tEcs.executeFunction({
    func: 'Z_PREPARE_REQ',
    data: {
        exports: {
            MYPARAM1: 'value1'
        }
    },
    withMetadata: true,
    done: function(data){
        // data contains all structures and metadata after execution
        console.log(data);
    },
    fail: function(data){
        console.log(data);
    }
})

7. String Helpers

7.1 Between JavaScript Date object and SAP Date string "yyyyMMdd"

tEcs.dateToString(new Date()) // output: "20160131"
tEcs.stringToDate('20150131'); // output (may vary on browser and version): Sat Jan 31 2015 00:00:00 GMT+0100 (W. Europe Standard Time)

7.2 Padding/filling a string with a given amount of characters.

For example padding on the left with leading zeros "1234" to "00001234"
tEcs.padLeft()
// Extend string '1234' to 8 digits with character '0'
tEcs.padLeft('1234', 8, '0'); // output: '00001234'
// Convert number 1234 to string and extend it to 10 digits with default character - space ' '
tEcs.padLeft(1234, 10); // output: '      1234'

Padding on the right, if required "1234" to "1234 "
tEcs.padRight()

7.3 Trimming result string from SAP.

For example " AAAA" to "AAAA"
tEcs.ltrim("    AAAA"); // output: "AAAA"
// trimming on the right
tEcs.rtrim("AAAA    "); // output: "AAAA"
// trimming both on the right and left
tEcs.trim("     AAAA    "); // output: "AAAA"

7.4 Formatting a string (as in C#).

tEcs.format() has 2 signatures:
// I. first parameter - format string
// next parameters - actual parameters to be put into the format string
//
tEcs.format('my first parameter: {0}; my second parameter: {1}', 'The Former', 'The Latter');
// output: 'my first parameter: The Former; my second parameter: The Latter'
//
//
// II. first parameter - format string with named parameters
// second parameter object of named parameters {parameter1: 'x', parameter2: 'y'}
//
tEcs.format('my {which} parameter', {which: 'awesome'});
// output: 'my awesome parameter'

7.5 Deep Extending an object

First parameter will be mutated.
tEcs._extend()
//
var extendedObj = tEcs._extend({}, {a: {b: 2}}, {a: {c: 3}});
// extendedObj == {a: {b:2, c: 3}}
//
//
var obj1 = {a: {b: 2}};
tEcs._extend(obj1, {a: {c: 3}});
// obj1 == {a: {b:2, c: 3}}

8. Changelog.

5.7 "abortRunningRequest(deferred)"-API and no console traces by default
5.6 new API for "Live Combobox" (supported e.g. in Nintex Forms)
5.5 conformant Apikey header (supporting ECS Core 2)
5.4 added utils for often used string operations e.g. tEcs.util.ltrim('000A', '0'), tEcs.util.padLeft('A', 8, '0'), (rtrim, padRight, trim), tEcs.util.guid()
5.3 "callSoapService" updated to be conformant with new ajax calls
5.2 "callSoapService" added as a synonym function for "wsdSoapQuery"
5.1 added withMetadata request parameter, which delivers function result with SAP metadata, such as structure sizes, headers, columns. Updated SOAP call to use non-jquery ajax call.
5.0 deferreds and ajax without jquery, renamed tEcs to theobald.ecs.micro
4.12 deferreds upgrades, added paragraph 6.7 with combining function requests
4.11 improved support for deferreds in executeFunction, executeInScope and executeChain
4.10 fixed wrong extend function causing ajax parameters set to incorrect values when custom jQuery is on the page
4.9 serviceApplication parameter for consistency (synonym for "instance")
4.8 Support for SecureStore Management APIs
4.7 Support for Scope and Instances (Service Applications) in ExecuteXQL queries
4.6 Proper Xhr aborting on user abort
4.5 Added functions to test connection
– Implemented recognition mechanism for SharePoint Online
– Implemented beta support without jQuery
– Added Support for XQL-Queries inside the scope
– Modified Authorization behavior, support for ECSCore 1.1.158+
4.1 Added "coreApiKey" field to use with new Api-Mechanism (ECS Core APIKEY header)