LDAPAdminDownload now


LDAP Admin: Scripts


LdapAdmin template scripts are written using the Javascript language. Alternatively, VBScript language may be used. However, VBScript is not actively supported so not everything may work as you expect it to.

The script may be defined within the contents of the script tag or in an external file by using the src attribute:
<script [type="text/javascript"]>
<script [src="path to file"]/>
The type and src attributes are optional. If the type attribute is omitted, the Javascript language is assumed.

The body within the script tag is interpreted as a plain text and is passed to the scripting engine literally. This allows you to write a code without constrains on the character set, the characters < or > won't break your code.

Although you can use both embedded and external code there is a slight difference between those. The embedded code will be loaded with the template at the application startup but the code itself will be run when the template is activated (when template or property dialogs are executed). The code in the external file will be loaded and executed only upon the template activation.

To interact with the template engine use one of the following global objects: Note that the properties and the methods of global objects are accessible directly, i.e. instead of
host.alert( entry.attributes[i].name )
you can simply write

Global objects

In following, the global objects are explained.
This global object provides some common gadgets such as input or alert dialog. Following methods are available:

alert(message) Displays a dialog with a message and OK button.
prompt(message, default) Simple input box with the given message. A default value is displayed in the text box.
createObject(progID) Creates and returns a reference to a COM object identified by ProgID.
readText(fileName) Reads a text from the file identified by the fileName and returns a string.
writeText(filename, value) Writes a value to the text file identified with the filename. Value must be a string.

The templates in LdapAdmin may appear in variety of places: edit window and various property dialogs. Furthermore, more then one template, grouped in tabs or panels, may appear in a dialog. Therefore, the global form object does not address the host dialogue itself, but rather the immediate parent of the template controls. Technically, this is a panel control (TPanel in VCL terms) on which all other template controls reside. This is also the most important global object as it allows you to interact with all template controls found on the form. To be able to address the controls you should give them unique names. For example, define a control such as:

<control type=text>
Then, you can access it like this:
alert("The content of the edit field is: " + editName.Text)
LdapAdmin is developed in Delphi, hence the template form and the controls on it are components of the Delphi VCL (Visual Component Library). To find out which properties are supported by the controls, consult the Delphi online VCL Reference. You can find the overview of the controls used by template engine at the end of this page. By default, you may access all published properties of the controls. For instance, to change a font color:

editName.Font.Color = 0xff0000;
The session object represents the current server connection. Currently, following methods are supported:

This method returns the next available unique uid number, as defined in the preference dialogue for this session.

Returns the next available unique gid number.

Creates a new entry. Once the entry is created its state is set to create mode. Issuing write() on entry in create mode would create a new LDAP entry with dn path. To read or modify the entry use the read() method. The entry will change to browse mode allowing you to view and modify its attributes and values.

search(filter, base, scope, attributes, noValues)
Use this method to search the current LDAP directory. The method takes following parameters:

filter LDAP query string
base Search base
scope Search scope. Integer value, can take one of the following values:

0Search the base entry only
1Search all entries in the first level below the base-entry, excluding the base-entry
2Search the base entry and all entries in its subtree

attributes List of attributes to return for each matching entry found. Pass empty string to retrieve all attributes
noValues Boolean value indicating whether only attribute types (true) or both attribute types and values are to be returned (false)

This method returns an array of entry objects. One entry object represents a data of a single LDAP entry identified by its dn. For instance, a global entry object is provided for an access to the current template data (current dn). See here for a description of the entry object. As an example, to find all users in a directory and add them to the combo box named cbx:
sr = session.search( 'objectclass = posixAccount', '', 2, 'uid', false );
for (var i=0; i<sr.count; i++) {
  cbx.items.add( sr[i].attributesbyname[ 'uid' ].value );
lookup(base, filter, result, scope)

This function returns a single value for a single attribute within a single entry. It takes the same base, filter and scope parameters as the search function. Additionally, the result parameter defines the attribute whose value should be returned. If more then one entry matches base and filter criteria, the value of the attribute in the first entry is returned. For example, to retrieve the second name of the user identified by the dc=user1,dc=Users,dc=doman,dc=com distinguisched name:
sName = lookup('dc=user1, dc=Users, dc=doman, dc=com', 'objectclass=*', 'sn', 0)
Generally, you should operate on controls rather then on attributes. By accessing the attributes directly, you are bypassing the controls and the changes you make will not be reflected on the form. But if you need to access hidden attributes such as objectclass, you will have to access the attributes directly, through the entry object. Entry object represents the LDAP data of the current template entry. Following properties are available:

dn Current entry dn. Read/Write property. Writing to the dn will rename the entry, changing the value of the entry naming attribute as well.
attributes Array of attribute objects. Use it to iterate through attributes:

(for var i=0; i<attributes.count; i++) {
    memo.lines.add( attributes[i].value ) }
attributesByName Array of attributes accessed by their names. Use it to access specific attribute by its name:

alert("Username: " + attributesByName[ 'userName' ].value)
onRead Event property. Fired immidiately after LDAP read.
onWrite Event property. Fired before data are about to be written to the LDAP directory.

Following methods are available:

Reads the values from LDAP directory.

Writes changes back to LDAP directory if the entry was set to browse mode by previously issuing the read() statement. Otherwise, creates a new entry with a dn path.

For a global entry object, the read() method is automatically called before the template dialog is shown. If user chooses OK, the write() method is called to write the changes to LDAP directory. You should never need to call the read or write methods on the global entry. However, if you are modifying entries returned by search() or createEntry() methods, you will have to call the write() method yourself. To avoid inconsistencies, you should do so from within the global entry OnWrite event which is fired only when user chooses OK in a template dialogue.

Both attributes and attributesByName collections return an attribute object. An attribute object itself has following properties:

valueCount Current number of values for this attribute.
values Array of values.
asString String representation of the first value in the array (values[0]). Use this to retrieve string value of the single value attributes.
value Alias for values[0]. Same as the asString property.

For instance, to form a full name from the first and the second name and place it in the displayName edit box:

displayName.text = attributesByName[ 'firstName' ].value + ', ' + attributesByName[ 'sn' ].value;
Following example iterates through all attributes and all their values and displays them in a text area:

  (for var i=0; i<attributes.count; i++) {
  (for var j=0; j<attributes[i].valuecount, j++) {
       memo.lines.add( attributes[i].name + ': ' + attributes[i].values[j] ); }}
Instead of attributes[i].values[j] you could use a short form attributes[i][j] as well.

Following methods are supported by the attribute object:

addValue(value) Adds a string value to the attribute.
deleteValue(value) Deletes a string value from the attribute.
deleteValue(index) Deletes a value at index position.
indexOf(value) Returns index position of the value or -1 if no such value was found.


In LdapAdmin, different controls may support different events. To find out which events a particular control supports, see here.

There are two ways of defining an event: within the contents of the script tag or within the contents of the event tag inside the control tag.

To define the event within the global script tag, assign a procedure to the event property. The following example assigns the onNameChange procedure to both firstName and sn text fields:

firstName.OnChange = onNameChange;
sn.OnChange = onNameChange;

function onNameChange(sender) {
        var fn = firstName.Text;
        userName.Text = fn.substr(1,1) + '.' + sn.Text;
Every event procedure has at least one parameter, the sender which represents the component which emitted the event. You can use it as you would when accessing the control directly:

function OnKeyDown(sender, key) {
        if (key=13) { sender.text="" };
Some events pass additional parameters, such as key code or a mouse position, as well.

You can also define the event directly within the control body:

<control type=text>
    <event type="onChange"> alert("Content changed!"); </event>
This will only work if the script was globally defined to announce the use of the script events. In this case, the global script tag may, but does not need to contain any code, a simple <script/> tag is sufficient.

As an example, to assign posix user id to a new user you would have to acquire the uid by calling the session getUid() method. The best place to do this is immediately before the data is written to LDAP. This minimizes the chance of the collision (duplicate user id's). To do so, you would define an event procedure and assign it to the onWrite event of the entry object:

entry.OnWrite = entryOnWrite;

function entryOnWrite(Sender) {
        attributesByName[ 'uid' ].value = session.getUid();

Control reference

Delphi VCL controls support a number of different events and event types. Not all of those are supported by the template engine. This list may grow in the future but currently, following events are supported:

Event name Corresponding Delphi event type Javascript declaration
 OnClick TNotifyEvent  function(sender)
 OnDblClick TNotifyEvent  function(sender)
 OnKeyDown TKeyEvent  function(sender, key, shift)
 OnKeyPress TKeyPressEvent  function(sender, key)
 OnKeyUp TKeyEvent  function(sender, key, shift)
 OnMouseDown TMouseEvent  function(sender, button, shift, x, y)
 OnMouseMove TMouseMoveEvent  function(sender, shift, x, y)
 OnMouseUp TMouseEvent  function(sender, button, shift, x, y)
 OnResize TNotifyEvent  function(sender)

Not all controls support all those events so please check the Delphi VCL reference to find out which events are supported by the particular control. The following table establishes a correlation between LdapAdmin template controls and corresponding Delphi VCL Controls:

Template controls Corresponding Delphi control
 checkbox  TCheckBox
 combo, combolist, combolookuplist  TComboBox
 date, time  TDateTimePicker
 edit, integer, number  TMaskEdit
 grid  TStringGrid
 image  TImage
 label  TLabel
 panel  TPanel
 passwordbutton, pickupdlg  TButton
 tabbedpanel  TPageControl
 textarea  TMemo

Note that the DateTime control is a combination of panel, date and time controls, hence it supports their corresponding properties. To access properties of date and time controls use date and time properties:

dateTime.time.format="MMM dd, yyyy"
From the template point of view, although dialogs, PasswordButton and PickupDialog are just a buttons. Therefore, we can only access the properties of the buttons, not those of the running dialogs itself.

Strings collections
As already mentioned, only published properties of Delphi VCL controls can be accessed from within the template script. Normally, all relevant properties are published but there is an important exception. The class TStrings which is a base class for all sorts of string collections in Delphi does not have published properties. Without it, however, you can not access the lines of the textarea (TMemo) or the items of the combo boxes.

For this reason, the functionality of TStrings in LdapAdmin is extended to allow you to access the most important properties of the string collections. Following properties have been implemented:

commaText Lists the all the strings in the TStrings object in a single comma-delimited string.
count Indicates the number of strings in the list.
text Used to get or set all the strings in the TStrings object in a single string delimited by carriage return, line feed pairs.

In addition, the following methods are implemented:

add(value) Adds a string at the end of the list.
delete(index) Remove a specified string. Index gives the position of the string, where 0 is the first string.
insert(index, value) Adds the string to the list at the position specified by index.
indexOf(value) Returns the position of a string in the list.
indexOfName(name) Returns the position of the first name-value pair with the specified name.

Note that the actual implementations of the strings collections are descendents of the TStrings, mostly implemented as TStringList.

Copyright (C) 2012 Tihomir Karlovic & www.ldapadmin.org. All rights reserved.   Design by Alexander Sokoloff. Impressum
LDAP Admin