.
Eloquence WEBDLG2 contact contact

Documentation / WEBDLG2 / Plugin API documentation

Plugin API documentation

 
.
  Document revision: 2024-10-28
Refers to WEBDLG2 version: B0840 2409-1


Table of contents


The plugin interface allows to extend WEBDLG2 with customized user interface controls. A plugin consists of JavaScript code (functionality) and optional CSS rules (visual appearance).

Plugins need to be registered by name. A plugin name must follow a defined naming scheme:

  • The name must start with an upper case letter (A-Z).
  • The remaining part of the name must consist only of lower case letters (a-z) or digits (0-9) or the underscore character (_).

Plugin DLG objects are then instantiated with DLG NEW using the "plugin." DLG class name prefix, for example:

DLG NEW "main.bigone","plugin.Snowball"
This instantiates the "main.bigone" DLG object of the "Snowball" plugin class.

When registered, the plugin class implementation is installed in the web browser main thread, and an associated proxy DLG class is created in the application's eloqwebd2 session. The proxy class is used to handle DLG GET and DLG SET requests from the application and to synchronize attribute values from/to the plugin DLG objects instantiated in the web browser.

As a reference, we recommend the plugin examples which demonstrate working implementations of various WEBDLG2 plugin use cases along with documented source code.


The eq.plugin() JavaScript API is used to register a plugin. It takes two arguments, both are required. The first argument is the plugin name as described above. The second argument is the plugin class descriptor which is an object providing the plugin properties and its implementation.

For example:

eq.plugin("Snowball", {
   // Attribute descriptor.
   atr : [
      [ "weight",   eq.atrGET|eq.atrSET|eq.atrSTR|eq.atrPRI ],
      [ "diameter", eq.atrGET|eq.atrSET|eq.atrSTR|eq.atrPRI ]
   ],

   // Class properties.
   prp : {
      minVersion  : 3,
      classList   : 'snowball',
      changeEvent : 'input',
      actionEvent : 'click',
      border      : true
   },

   // API: Constructor.
   apiInit : function(dlg, el) {
      // this - plugin instance
      // dlg  - Dlg dialog instance
      // el   - plugin object DIV container element

      // Set up the instance members variables.
      this.weight = 0.0;
      this.diameter = 0.0;

      // Set up the DOM elements …
   },

   // API: Set attribute value.
   apiSetAttr : function(dlg, id, el, atr, idx, val) {
      // this - plugin instance
      // dlg  - Dlg dialog instance
      // id   - plugin object DOM identifier
      // el   - plugin object DIV container element
      // atr  - attribute name
      // idx  - attribute index string or null
      // val  - value, val.i (integer) or val.s (string)

      switch (atr) {
         case 'weight':
            this.weight = parseFloat(val.s);
            break;

         case 'diameter':
            this.diameter = parseFloat(val.s);
            break;
      }
   },

   // API: Change event occurred.
   apiOnChange : function(dlg, id, el, e) {
      // this - plugin instance
      // dlg  - Dlg dialog instance
      // id   - plugin object DOM identifier
      // el   - plugin object DIV container element
      // e    - Event object

      // Handle the 'input' changeEvent ...
   },

   // Static methods.
   // ---------------
   static : {

      // Static API: Class installation.
      install : function() {
         // this - plugin class
         console.log(this.name + " plugin installed.");
      }

   }
});

This is an incomplete example of a "Snowball" plugin class providing the GET/SET string attributes "weight" and "diameter". The apiSetAttr() method is invoked as necessary to synchronize the attribute values as set by the application.

When instantiated, a DIV container DOM element is created, attributed with the "snowball" class name and a border, then the apiInit() constructor method is invoked to allow setting up the plugin object as well as the DOM element.

The input DOM event is recognized as change event, as such it causes invocation of the apiOnChange() method provided in the implementation. The click DOM event is recognized as action event, as such it may cause a rule submission.

The install() method is invoked when the plugin has been installed. This is a static method, i.e., it does not operate on an instance but on the class. The static object allows to define static methods and/or class variables.

The class is defined in the eq.c namespace with a "plg" prefix in the web browser main thread. For example:

"Snowball" plugin class
defined as: eq.c.plgSnowball
super class: eq.c.DlgPlugin
base class: eq.c.DlgElement
static install() method
defined as: eq.c.plgSnowball.install()
apiInit() instance method
defined as: eq.c.plgSnowball.prototype.apiInit()

A plugin registration as shown above is typically contained in a text file having the plugin name plus the .js extension, for example Snowball.js. If necessary, the associated CSS rules to define the visual appearance are typically contained in an accompanying .css file, for example Snowball.css.

To use the plugin, configure an URI in the eloqwebd2.uri file for the directory containing the plugin files, for example:

[/plugin]
Path = /directory/in/web/server/document/hierarchy

This configuration associates the /plugin URI with the plugin directory in the file system. Now the application can be configured to load the plugin by setting PluginURL as shown below:

PluginURL = /plugin/Snowball.js
PluginURL = /plugin/Snowball.css

Alternatively, the plugin files may be integrated into the HTML documents. This is necessary when using an external web server.

For example:

<script async
        src="/path/to/Snowball.js">
</script>
<link href="/path/to/Snowball.css"
      rel="stylesheet" type="text/css">

As shown here, using the <script async> attribute is recommended to avoid that the script potentially delays loading the document (1).


The plugin class descriptor is expected to define the atr property providing the attribute descriptor, for example:
atr : [
   [ "weight",   eq.atrGET|eq.atrSET|eq.atrSTR|eq.atrPRI ],
   [ "diameter", eq.atrGET|eq.atrSET|eq.atrSTR|eq.atrPRI ]
]

The attribute descriptor is an array of one or more attribute items. Each attribute item defines one plugin attribute as an array of two items. The first item specifies the attribute name. The second item consists of a combination of attribute flags which control how the eloqwebd2 proxy class handles the associated attribute values.

Flags affecting the access method:

eq.atrGET
attribute supports DLG GET
eq.atrSET
attribute supports DLG SET
eq.atrGET | eq.atrSET
attribute supports both DLG GET and DLG SET

Flags affecting the data type:

eq.atrINT
data type is integer
eq.atrINT | eq.atrIDX
data type is integer, may be indexed
eq.atrSTR
data type is string
eq.atrSTR | eq.atrIDX
data type is string, may be indexed
eq.atrINT | eq.atrSTR
data type is either integer or string
eq.atrINT | eq.atrSTR | eq.atrIDX
data type is either integer or string, may be indexed

Flags affecting the behavior:

eq.atrPRI
attribute has priority
eq.atrNOC
attribute values are not cached
eq.atrLST
attribute values are stored as list
eq.atrSYN
attribute values are synchronized immediately

The eq.atrIDX flag specifies that attribute values may be indexed, i.e., the attribute name may have an optional […] suffix.

The apiSetAttr() and apiGetAttr() methods take an idx argument which is an index string (the suffix string between the first [ and the last ]), or null if the value is not indexed. For example:

// API: Set attribute value.
apiSetAttr : function(dlg, id, el, atr, idx, val) {
   var ix = idx ? idx.split('][') : null;
   …

Here, the resulting ix is an array of index dimensions, or null if the value is not indexed. This way, line[1] as well as cell[2][3] are recognized.

The default behavior is that DLG SET causes attribute values to be cached in the eloqwebd2 proxy object, and DLG GET returns these cached values to the application, or zero or an empty string, respectively, in case a value has not been set.

DLG DO and DLG DRAW synchronize the cached values with the plugin DLG object in the web browser by invoking the apiSetAttr() method.

Please note: Attribute values are synchronized only once unless they are modified via DLG SET.

If none of the behavior flags are set, the cached values are synchronized in the order they were set by the application.

If the eq.atrPRI flag is set, attribute values are prioritized on synchronization, i.e., they are synchronized in the order they are specified in the atr attribute descriptor before any other attribute value not having the eq.atrPRI flag set.

For example, consider the atr attribute descriptor of the Editgrid plugin example:

atr : [
   [ 'columns',      eq.atrGET|eq.atrSET          |eq.atrINT|eq.atrPRI ],
   [ 'delim',        eq.atrGET|eq.atrSET          |eq.atrSTR|eq.atrPRI ],
   [ 'activecolumn', eq.atrGET|eq.atrSET          |eq.atrINT ],
   [ 'activeline',   eq.atrGET|eq.atrSET          |eq.atrINT ],
   [ 'cx',           eq.atrGET|eq.atrSET          |eq.atrINT ],
   [ 'cy',           eq.atrGET|eq.atrSET          |eq.atrINT ],
   [ 'colreadonly',  eq.atrGET|eq.atrSET|eq.atrIDX|eq.atrINT ],
   [ 'colwidth',     eq.atrGET|eq.atrSET|eq.atrIDX|eq.atrINT ],
   [ 'header',       eq.atrGET|eq.atrSET|eq.atrIDX|eq.atrSTR ],
   [ 'add',                    eq.atrSET|eq.atrLST|eq.atrSTR|eq.atrNOC ],
   [ 'cell',         eq.atrGET|eq.atrSET|eq.atrIDX|eq.atrSTR|eq.atrNOC ],
   [ 'clear',                  eq.atrSET          |eq.atrINT
                                                  |eq.atrSTR|eq.atrNOC ],
   [ 'content',      eq.atrGET|eq.atrSET          |eq.atrSTR|eq.atrNOC ],
   [ 'del',                    eq.atrSET|eq.atrIDX|eq.atrINT|eq.atrNOC ],
   [ 'insert',                 eq.atrSET|eq.atrIDX|eq.atrSTR|eq.atrNOC ],
   [ 'line',         eq.atrGET|eq.atrSET|eq.atrIDX|eq.atrSTR|eq.atrNOC ]
]
Regardless in which order the attribute values were set by the application, synchronization affects first the "columns" value and then the "delim" value before any other value is synchronized.

The Editgrid plugin example uses this to ensure that the number of columns and the column delimiter are known before any content or headers are synchronized.

The other attribute values need to be synchronized in the order they were set by the application because they may depend on each other. A typical example would be that first the old content is cleared, then the new content is set, and finally the active line and column are specified.

As shown above, the Editgrid plugin example sets the eq.atrNOC flag on all attributes which affect the content, to specify that these attribute values are not cached.

The Editgrid plugin example provides several methods to modify the content such as setting or clearing it all at once, or adding to existing content, or modifying or inserting or deleting a line. The application always expects to DLG GET a consistent result, regardless of how the content has been set.

For example, the application might DLG SET the entire content and then DLG GET a specific cell content. The eloqwebd2 proxy object does not have any means to derive a "cell" value from a cached "content" value. Instead, the DLG GET needs to be forwarded to the plugin DLG object in the web browser by invoking the apiGetAttr() method.

In the eloqwebd2 proxy object, a DLG SET on an attribute having the eq.atrNOC flag set invalidates all cached values of any other eq.atrNOC attributes. In the above example, setting a "content" value invalidates a previously cached "cell" value. The following DLG GET will not find a valid "cell" value. Also, the "cell" attribute has the eq.atrNOC flag set. As a consequence, a synchronization takes place, and the apiGetAttr() method is invoked on the plugin DLG object in the web browser to obtain the "cell" value requested by the application.

Please note: In case of the Editgrid plugin example, this is necessary to ensure correct behavior. However, this kind of DLG GET synchronization is considered expensive regarding application performance.

The eq.atrLST flag may be set to specify that multiple DLG SET invocations need to be stored as list. On synchronization, the list is transferred to the plugin DLG object in the web browser by invoking the apiSetAttr() method for each DLG SET invocation.

The Editgrid plugin example sets the eq.atrLST flag for the "add" attribute which allows repeated DLG SET invocations to add to the existing content line-by-line.

Please note: eq.atrLST attributes must not be indexed, i.e., the eq.atrIDX and eq.atrLST flags are mutually exclusive.

In certain cases it might be necessary to set the eq.atrSYN flag to always enforce immediate synchronization on both DLG GET and DLG SET, i.e., to go beyond the eq.atrNOC behavior.

The Filetransfer plugin example uses the eq.atrSYN flag along with the eq.atrNOC flag to implement the "select" and "upload" and "download" and "transfer" and "close" attributes because they require immediate action in the application user interface.

Please note: A synchronous DLG SET does not automatically take place when the eq.atrSYN flag is set. As mentioned in the DLG v2 protocol documentation, the application in addition needs to assign a status return variable, such as:
DLG SET "Main.file.transfer",Buf$;Rc

Regarding the Filetransfer plugin example, please also note how it maintains its state using static class variables to allow that the state's lifetime might span multiple DLG object instantiations.


The plugin class descriptor is expected to define the prp property providing the class properties, for example:
// Class properties.
prp : {
   minVersion  : 3,
   classList   : 'snowball',
   changeEvent : 'input',
   actionEvent : 'click',
   border      : true
},

minVersion
Required, specifies the minimum plugin API version which should be 3 for new plugins, as shown above. If the installed WEBDLG2 is too old so that it does not meet this minimum plugin API version, the plugin is not loaded, and an error message is logged in the web browser console.

classList
Optional, space-separated list of CSS class names which are set on the DIV container element. The eq-plugin and eq-control class names are added, as well as the eq-rule class name if a nonzero rule attribute value is set.

changeEvent
Optional, space-separated list of DOM event types which should trigger a change event, i.e., invoke the apiOnChange() method.

actionEvent
Optional, space-separated list of DOM event types which should trigger an action event, i.e., invoke the apiOnEvent() method if a nonzero rule attribute value is set and, if the event is accepted, invoke the apiOnSubmit() method and submit the rule to the application.

focusable
Optional, needs to be set to false if the plugin object should not be focusable. The default value is true.

border
Optional, needs to be set to true to add a CSS border to the DIV container element. The default value is false.

Please note: If changeEvent includes mousedown to start a move capture, make sure to add the pointerdown event type for touch user interface support, as demonstrated in the Datepicker plugin example.


When the dialog containing the DLG plugin object is not (yet) present in the web browser, DLG GET and DLG SET called on an attribute having the eq.atrNOC and/or eq.atrSYN flags may need to create a temporary object.

In other words, the eq.atrNOC and/or eq.atrSYN flags may require immediate synchronization in a situation where the DLG plugin object's parent dialog has not (yet) been defined in the DOM. This is solved by creating a temporary object to invoke its apiSetAttr() or apiGetAttr() method, after which the temporary object is deleted, i.e., the temporary object never appears in the user interface.

Dlg.temp may be used to avoid unnecessary actions on temporary objects, such as setting CSS properties which never come into effect because the DOM elements never become visible. Similarly, the Dlg.grid properties may be checked whether or not they are undefined, as shown in the Editgrid plugin example.

A plugin using the eq.atrSYN flag might be designed to never appear in the user interface, i.e., it might expect that a temporary object is used for every invocation of its apiSetAttr() or apiGetAttr() method. In such a case, static class variables are typically used to allow that the lifetime of the plugin's state might span multiple DLG object instantiations, as shown in the Filetransfer plugin example.


Any of the methods listed below may be implemented in the static object in the plugin class descriptor. The static methods below operate on the plugin class, i.e., this refers to the class.

Arguments:
this - plugin class

Optional class constructor, invoked when the plugin has been installed, i.e., when the plugin class is defined in the eq.c namespace.

Arguments:
this - plugin class

Optional cleanup method, invoked when the application has ended.

Please note: This is not a class destructor. The plugin class remains defined in the eq.c namespace, i.e., it is not deleted.


Any of the methods listed below may be implemented in the plugin class descriptor.

Arguments:
this - plugin instance
dlg - Dlg dialog instance
el - plugin object DIV container element

Constructor, invoked when a plugin instance is created and the DIV container element has been set up in the DOM. Typically, implementing this method is required to set up the instance and the user interface.

It may also be used to set up static class variables not possible to initialize using the class constructor. For example, the Datepicker plugin example sets up static class variables based on the application locale which is available as soon as the application has started, i.e., which is not available yet when the class constructor is invoked. Similarly, the Editgrid plugin example initializes static class variables based on the strings configuration which might not yet be set up when the class constructor is invoked.

Arguments:
this - plugin instance
dlg - Dlg dialog instance
id - plugin object DOM identifier

Optional destructor, invoked when a plugin instance is deleted.

Please note: Any associated DOM element has already been removed before the destructor is invoked.

Arguments:
this - plugin instance
dlg - Dlg dialog instance
id - plugin object DOM identifier
el - plugin object DIV container element
atr - attribute name
idx - attribute index string or null
val - value, val.i (integer) or val.s (string)

Invoked to set an attribute value. This method is required if DLG SET attributes are defined. Every attribute having the eq.atrSET flag needs to be handled.

For indexed values, idx is the index string, i.e., the attribute name suffix string between the first [ and the last ], or null if the value is not indexed.

The val object has either the i or the s property set, depending on whether an integer or a string value is passed. The other property is undefined.

Arguments:
this - plugin instance
dlg - Dlg dialog instance
id - plugin object DOM identifier
el - plugin object DIV container element
atr - attribute name
idx - attribute index string or null

Invoked to synchronously get an attribute value. This method is required if DLG GET attributes are defined which have the eq.atrNOC and/or eq.atrSYN flags set. Each of these attributes need to be handled.

For indexed values, idx is the index string, i.e., the attribute name suffix string between the first [ and the last ], or null if the value is not indexed.

apiGetAttr() is expected to return either an integer or a string value, or undefined if no value can be returned. If not undefined, an integer is assumed if the returned value's type is number, otherwise a string is assumed.

Alternatively, null may be returned if a value is not available immediately, for example if a promise needs to be fulfilled before a value can be returned. The plugin is expected to invoke DlgPlugin.onUpdateReturn() as soon as the value is available.

Please note: The WEBDLG2 user interface is blocked until a value is returned.
apiSetSensitive(dlg, id, el, sensitive)

Arguments:
this - plugin instance
dlg - Dlg dialog instance
id - plugin object DOM identifier
el - plugin object DIV container element
sensitive - boolean true or false

Invoked when the sensitive aka. enabled state has changed. Typically, this method is required to propagate the sensitive aka. enabled state to INPUT child elements if present.

By default, the eq-disabled CSS class name is added on the container element if the sensitive aka. enabled state is false.

Arguments:
this - plugin instance
dlg - Dlg dialog instance
id - plugin object DOM identifier
el - plugin object DIV container element
e - Event object

Optional event filter, invoked when an action event has been triggered and a nonzero rule attribute value is set.

This method is expected to return true to accept the event, or to return false to discard the event. When accepted, the apiOnSubmit() method is invoked if implemented, then the rule is submitted to the application.

Arguments:
this - plugin instance
dlg - Dlg dialog instance
id - plugin object DOM identifier
el - plugin object DIV container element
e - KeyboardEvent object

Optional key event handler, expected to return:
true - consume event
false - pass event to default handler
null - delegate event to target

The default handler recognizes accelerator keys as well as the focus navigation Tab and Enter and cursor keys. The target is the DOM element where the event originates, e.g., an INPUT element.

This method is typically used to implement plugin specific KeyboardEvent behavior. For example, it might register changed attribute values, or it might submit a rule to the application.

Arguments:
this - plugin instance
dlg - Dlg dialog instance
id - plugin object DOM identifier
el - plugin object DIV container element
key - KeyboardEvent.key

Invoked when the dialog is about to become interactive to process a single type-ahead key stoke. This method is typically required if the key event handler is implemented.

It is expected to return true if the key stroke has been processed, or false to pass the key stroke to the default handler which recognizes the focus navigation Tab and Enter keys.

Please refer to the Datepicker and Editgrid plugin examples about how to implement apiOnTypeAhead() to process INPUT text element type-ahead key stokes.

Arguments:
this - plugin instance
dlg - Dlg dialog instance
id - plugin object DOM identifier
el - plugin object DIV container element
ev - DLG event object

Optional, invoked when the rule is about to be submitted to the application. This method could, for example, be implemented to unconditionally register changed attribute values before the rule is submitted (see also apiChanged() below).

It could also be used to modify the DLG event object, which is used to delegate the rule submission to the associated eloqwebd2 DLG session.

DLG event object properties:
ev.id - the DLG object which has triggered the rule submission (the dialog if not set)
ev.type - the event type which has triggered the rule submission
ev.ev - secondary RuleOverride event if present

For example, the TabBox sets ev.id to the selected tab. This way, the rule of the active tab's GroupBox is submitted.

Arguments:
this - plugin instance
dlg - Dlg dialog instance
id - plugin object DOM identifier
el - plugin object DIV container element
e - Event object

Optional event handler, invoked when a change event has been triggered. It is expected to return true to continue processing the event, relevant if this event type is also registered as action event, or false to stop processing the event.

The event type is internally registered to have been triggered by this DLG object, which causes the apiChanged() method to be invoked the next time a rule is submitted to the application.

This method is typically used to implement plugin specific behavior, except on KeyboardEvent which may be handled by the apiOnKey() method. For example, it might register changed attribute values, or it might submit a rule to the application.

Arguments:
this - plugin instance
dlg - Dlg dialog instance
el - plugin object DIV container element

Required if the focusable DOM element is different from the plugin object DIV container. This method is invoked when the focus is about to be set, it is expected to return the DOM element which should gain the focus.

Arguments:
this - plugin instance
dlg - Dlg dialog instance
ct - DOM control gaining the focus

Optional notification method invoked when the plugin DLG object is about to gain the focus.

Please note: ct is the DOM element returned by the apiFocusElement() method.

Arguments:
this - plugin instance
dlg - Dlg dialog instance
el - plugin object DIV container element

Optional notification method invoked when the plugin DLG object is about to lose the focus.

Arguments:
this - plugin instance
dlg - Dlg dialog instance
id - plugin object DOM identifier
el - plugin object DIV container element
ty - array of change event types which have been triggered

Optional, invoked when the rule is about to be submitted to the application and one or more change event types have been triggered before.

Please note: The apiChanged() method is invoked after the apiOnSubmit() method, if implemented, has been invoked.

This method could, for example, be implemented to register a changed attribute value if the ty array contains a particular event type.

Arguments:
this - plugin instance
dlg - Dlg dialog instance
id - plugin object DOM identifier
el - plugin object DIV container element
atr - attribute name
idx - attribute index string or null

Optional notification method, invoked after apiSetAttr() when an attribute value has been synchronously set.


The apiSetAttr() method is invoked with the "font" attribute name to notify a plugin object that the font properties should be set.

Please note: The "font" attribute must not be specified in the attribute descriptor!

The apiSetAttr() val argument refers to an object containing the properties:
val.font - font object
val.fontRules - font CSS rules or undefined

The font object may be used to invoke DlgElement.setFont() to set the font properties of a specific element, as demonstrated in the Datepicker plugin example.

Alternatively, the font CSS rules may be used to invoke DlgElement.setCssRule(), especially to apply the font properties to multiple elements, as demonstrated in the Editgrid plugin example.

Please note: The val.fontRules property is undefined if the font object does not contain any font properties.


Plugin classes are derived from DlgPlugin, defined in the eq.c namespace as eq.c.DlgPlugin.

Please note: These DlgPlugin instance methods can be invoked when the application is interactive.

Arguments:
id - plugin object DOM identifier
type - change event type
atr - attribute name
idx - attribute index string or null
iv - integer value
sv - string value

These instance methods register changed attribute values to be transferred to the associated proxy DLG object during the next rule submission.

If implemented, the apiChanged() method will then be invoked with the specified type which should, but is not required to, be one of the registered change event types.

DlgPlugin.submit(id, el, type, rule)

Arguments:
id - DLG object DOM identifier
el - DLG object DOM element
type - action event type
rule - rule value, integer or undefined

The DlgPlugin.submit() instance method submits a rule to the application.

The id and el arguments need to specify the same DLG object, which may be any DLG object in the current dialog. The DLG object's rule is submitted if rule is omitted or passed as undefined.

Arguments:
dlg - Dlg dialog instance
id - plugin object DOM identifier
val - integer or string value, or undefined

The DlgPlugin.onUpdateReturn() instance method is used to return a value after apiGetAttr() could not immediately return a value to the associated proxy DLG object.

An integer or a string value is expected to be passed in the val argument, or undefined if no value can be returned. If not undefined, an integer is assumed if the value's type is number, otherwise a string is assumed.

Please note: The plugin implementation needs to save the this plugin instance and the dlg and id arguments passed to the apiGetAttr() method, then later invoke the DlgPlugin.onUpdateReturn() method on the same plugin instance with exactly these arguments, as demonstrated in the Filetransfer plugin example.


DlgElement is the base class for any DLG object class, defined in the eq.c namespace as eq.c.DlgElement.

Arguments:
el - DLG object DOM element
fn - font object

The DlgElement.setFont() instance method sets an element's font properties.

The font object specifies the font family and/or the font size and/or the italic font style and/or the bold font weight. If any is present in the font object, the DOM element's inline style is set appropriately, and the eq-font CSS class name is added.

See also: eq.Dom.setFont()

Arguments:
id - DLG object DOM identifier
type - rule type
rule - rule string, or array of rule strings, or null

The DlgElement.setCssRule() instance method sets, or modifies, or deletes, a dynamic CSS rule. This way, CSS properties may be defined for a DOM element or a group of DOM elements at once. This avoids needing to modify the inline style of multiple elements and works even if the elements don't yet exist.

The type argument should be an integer identifying the specific CSS rule. Plugins should use type values above 100 to ensure unique identifiers.

The type identifier allows to later modify or delete a rule. If the rule argument is passed as null or undefined the rule is deleted. When a DLG object is deleted, the associated rules are deleted as well.

The use of dynamic CSS rules is demonstrated in the Editgrid plugin example which uses different id values to set font and height and width rules, such as (simplified):

apiSetAttr : function(dlg, id, el, atr, idx, val) {
   var cls = this.constructor;
   …
   switch (atr) {
      case 'font': {
         …
         this.setCssRule(id, cls.cssRule.font,
            ">*" + val.fontRules);
         …
         this.setCssRule(id, cls.cssRule.height,
            " .cell>*{height:" + cssHeight + "}");
         …
         this.setCssRule(id, cls.cssRule.width, [
            ">.hdr>.r>*,",
            ">.row>.r>*>*{width:" + cssWidth + "}"
         ]);
         …
      }
   }
},
…
static : {
   …
   cssRule : {
      font   : 101,
      height : 102,
      width  : 110
   }
}

The DlgElement.setCssRule() method prepends all rule strings with the specified DLG object DOM identifier. For example, assuming the eq-i42 identifier, the rules below would be set:

#eq-i42 > * {
  font-family: sans-serif;
  font-size: 13pt;
}


#eq-i42 .cell > * {
  height: 1.5em
}

#eq-i42 > .hdr > .r > *,
#eq-i42 > .row > .r > * > * {
  width: 11.282ch
}

Here, spaces have been added for better readability. In the first rule, the val.fontRules have been expanded. In the second and third rules, the calculated height and width values have been inserted. Also, the third rule demonstrates how both rule strings are separately prepended with the eq-i42 DLG object DOM identifier.


Each dialog has an associated Dlg instance which is passed to the plugin instance methods listed above. The Dlg class is defined in the eq.c namespace as eq.c.Dlg.

The grid instance member represents the dialog raster used for position and size calculations, based on the dialog font or, if the dialog font is not set, the default font.

grid.wr
Number of pixels of the CSS ch relative length unit.
grid.wp
Number of pixels of the letter X width.
grid.wf
Dialog raster width factor. For example, the function below calculates the CSS width in ch units from dialog raster width units passed as w:
var cssWidth = function(dlg, w) {
   if (w)
      return (Math.round(w * dlg.grid.wf * 1000) / 1000) + 'ch';
   return 0;
}
grid.hr
Number of pixels of the CSS em relative length unit.
grid.hp
Number of pixels of the letter X height.
grid.hf
Dialog raster height factor. For example, the function below calculates the CSS height in em units from dialog raster height units passed as h:
var cssHeight = function(dlg, h) {
   if (h)
      return (Math.round(h * dlg.grid.hf * 1000) / 1000) + 'em';
   return 0;
}

Please note: The above grid properties are undefined if the dialog is temporary.

For example, the cssHeight() function above uses grid.hf, consequently it should not be invoked if the dialog is temporary, such as:

if (dlg.grid.hf !== undefined) {
  var height = cssHeight(dlg, 1);
  …
}

The temp instance member is true if the dialog is temporary.

The eds instance member is a Map object containing all DlgElement instances belonging to a dialog.

A DlgElement instance may be obtained by DLG object DOM identifier, such as:

var self = eq.app.currDlg.eds.get(el.id);

This is typically used in static methods where this does not refer to the plugin instance.

Arguments:
el - DOM element

The Dlg.copyFontToElement() instance method copies the dialog font to the specified DOM element. If the dialog font is not set, the default font is copied. If configured, the FontSizeFactor is applied.

See also: eq.Dom.adjustElementFontSize()


The App application class is defined in the eq.c namespace as eq.c.App. The eq.app instance refers to the current application.

Please note: eq.app is a singleton because the current implementation supports one application per web browser window or tab.

The locale instance member is an object specifying the application locale. Its tag property contains the corresponding IETF BCP 47 language tag.

The idle instance member is a boolean indicating whether the application is idle or interactive.

true - application is idle
false - application is interactive

On DLG DO or Dialog.do, eq.app.idle becomes false, the current dialog is set up, and the application becomes interactive.

Outside DLG DO or Dialog.do, eq.app.idle is true, and any user interaction is blocked.

The currDlg instance member refers to the current dialog, i.e., the Dlg dialog instance on which DLG DO or Dialog.do has been called, or null when the application is idle. currDlg refers to the same Dlg dialog instance as passed to the plugin instance methods listed above.

The pendingMouseDown instance member may be used in the apiFocusGained() method to check if it is invoked due to a mousedown event, as demonstrated in the Datepicker and Editgrid plugin examples:

apiFocusGained : function(dlg, ct) {
   // Select on focus except on mouse click or if focus doesn't change.
   if (   eq.app.pendingMouseDown === undefined
       && ct !== document.activeElement) {
      ct.select();
      ct.scrollLeft = ct.scrollWidth;
   }
}

This selects the entire INPUT element content and scrolls it to the right, except when the apiFocusGained() method is invoked due to a mousedown event, or when the INPUT element already has the focus.

The pendingTabMode and pendingTabModeId instance members may be used in the apiFocusElement() method to set the focus to the expected child element during tab navigation.

A forward navigation into the plugin object, for example when pressing the Tab key, is typically expected to set the focus to the first child element, while a backward navigation into the object, for example when pressing the Shift+Tab key combination, is typically expected to set the focus to the last child element.

eq.app.pendingTabMode values:
1 - forward navigation
-1 - backward navigation
undefined - not a tab navigation

When eq.app.pendingTabMode is set, i.e., not undefined, the corresponding eq.app.pendingTabModeId should be checked to match the plugin object DOM identifier, such as:

apiFocusElement : function(dlg, el) {
   var tab = eq.app.pendingTabMode;
   if (tab !== undefined && el.id === eq.app.pendingTabModeId)
      …
}

Please note: This is demonstrated in the Editgrid plugin example.

Arguments:
id - DLG object DOM identifier
el - optional DLG object DOM element

The eq.app.setFocus() instance method sets the focus to the specified DLG object.

Specifying the el argument is optional but saves a document.getElementById() invocation in case the element reference is available anyway.

The method returns true if setting the focus has the side effect of submitting a rule to the application, otherwise it returns false. Potentially, a blur event is triggered by the element losing the focus, which may cause a rule submission.

Nothing happens if the element already has the focus.

The pendingFocus instance member is typically set after eq.app.setFocus() returned true to indicate that a rule is submitted. In this case, pendingFocus schedules an action to execute when the focus is set the next time the application is about to become interactive again.

eq.app.pendingFocus needs to be set to an object having the properties:
id - DLG object DOM identifier
act - action callback function

The action callback function is invoked when the focus is set the next time the application is about to become interactive again, given that the DOM identifier of the focused DOM identifier is the same as the specified id property.

action callback function arguments:
this - the eq.app.pendingFocus object
el - DLG object DOM element

This is demonstrated in the Datepicker plugin example, such as (simplified):

apiOnChange : function(dlg, id, el, e) {
   …
   if (eq.app.setFocus(id, el)) {
      …
      eq.app.pendingFocus = {
         id : id,
         act : function(el) {
            // Execute later after rule has been processed.
         }
      };
      return false;
   }
   …
}

Arguments:
el - owner DOM element
ov - overlay DOM element
onClose - close callback function

The eq.app.makeOverlay() instance method sets up the overlay element so that it becomes a direct body child. Furthermore, its z-index is set to the highest body children z-index plus 1. In addition, the eq-overlay CSS class name is added.

As a result, the overlay visually appears above all elements displayed in the web browser window or tab.

The owner element is passed to the close callback function when the overlay is closed.

An overlay is closed explicitly by invoking the eq.app.closeOverlay() method. It is closed implicitly when a mousedown event is triggered outside the overlay. In both cases, the close callback function is invoked.

close callback function arguments:
this - internal overlay descriptor
el - owner DOM element
ov - overlay DOM element
arg - optional argument or undefined

The close callback function is responsible for removing the overlay element from the body. Usually, this is fulfilled when the overlay element is moved back into the owner element, as described in the next section. The arg argument may be set when explicitly closing the overlay by invoking the eq.app.closeOverlay() method, otherwise arg is undefined.

Typically, the overlay element is a child of the owner element, for example a pulldown menu or a ComboBox list. When the menu or list is opened, eq.app.makeOverlay() is invoked, passing the menu or list as overlay element, which is then detached from the owner element, then becoming a top-level element as described above.

Please note: The Datepicker plugin example demonstrates how to use the overlay functionality to display its calendar popup.

Arguments:
el - optional owner DOM element
arg - optional argument or undefined

The eq.app.closeOverlay() instance method explicitly closes the current overlay. Nothing happens if there is no overlay present.

If the el argument is specified, it must match the owner element specified to open the current overlay. If the arg argument is specified, it is passed to the close callback function.

Arguments:
arg - argument passed to callback functions
onMove - move callback function
onEnd - optional move ended callback function

The eq.app.moveCapture() instance method may be called when the primary pointer is down, typically when the apiOnChange() method is invoked on a mousedown or pointerdown change event.

A move capture is started which invokes the move callback function whenever the pointer is moved. The capture ends on a mouseup or pointerup or pointercancel event, or when the current user interaction is interrupted for whatever reason, for example if the browser window or tab loses focus, or if the application terminates.

The arg argument is passed to the callback functions.

move callback function arguments:
this - internal capture descriptor
e - mousemove or pointermove event object
arg - argument

When specified, the move ended callback function is invoked when the capture ends.

move ended callback function arguments:
this - internal capture descriptor
arg - argument
e - mouseup or pointerup event object or undefined

The move ended callback function e event argument is undefined if invoked due to an interrupted user interaction.

Please note: The Datepicker plugin example demonstrates how to use the move capture functionality when its calendar popup is opened and when the selected day is changed.


The eq.Dom namespace defines a collection of utility functions.

Arguments:
dlg - Dlg dialog instance
el - DLG object DOM element

Scrolls the specified element into view if necessary, i.e., the parent dialog and/or any parent GroupBox objects are scrolled as necessary.

Arguments:
el - DOM element
cn - content string
checkAccel - boolean true or false

Sets the specified element's text or HTML content.

HTML content is assumed if the content string begins with <html>. The DOMParser API is used to parse the content string. An optional </html> at the end is ignored.

If checkAccel is true, accelerator keys are recognized. If text content is specified, a letter or digit prepended with the & character is recognized as accelerator key. If HTML content is specified, a single underlined letter or digit is recognized as accelerator key.

Arguments:
to - DOM element
from - DOM element

Copies text or HTML content from an element to another element.

Arguments:
to - DOM element
from - DOM element

Copies the font family and font size and font style and font weight inline styles from an element to another element.

Arguments:
to - DOM element
from - DOM element

Copies the color and background color inline styles from an element to another element.

Arguments:
el - DOM element
fn - font object

Sets the specified element's font properties.

The font object specifies the font family and/or the font size and/or the italic font style and/or the bold font weight. If any is present in the font object, the DOM element's inline style is set appropriately and true is returned, otherwise false is returned.

See also: DlgElement.setFont()

Arguments:
el - DOM element

If configured, applies the FontSizeFactor to the specified element if its font size inline style is set.

See also: Dlg.copyFontToElement()

Arguments:
el - DOM element

Returns the numeric z-index of the specified element.

Arguments:
el - DOM element

Returns the maximum numeric z-index of all direct children of the specified element.

Arguments:
el - DLG object DOM element

Returns the specified element's DLG control element, i.e., the specified element if it has the eq-control CSS class name set, or the nearest parent element having the eq-control class name set, or null if no DLG control element is found.

Arguments:
el - DLG object DOM element

Returns the specified element's dialog, i.e., the specified element if it has the eq-dialog CSS class name set, or the nearest parent element having the eq-dialog class name set, or null if no dialog is found.

Arguments:
el - DLG object DOM element

Returns the specified element's overlay element, i.e., the specified element if it has the eq-overlay CSS class name set, or the nearest parent element having the eq-overlay class name set, or null if no overlay element is found.

Arguments:
el - DOM element

Returns true if the specified element is a DLG object DOM element, i.e., if it is a dialog root element or a child of a dialog root element.

Arguments:
el - DOM element

Returns the numeric index of the specified element in the children list of the parent element.

Arguments:
el - DOM element
tagName - tag name

Returns the first direct child of the specified element which matches the specified tag name, or null if no such direct child exists.

Arguments:
el - DOM element

Returns the specified element's direct or indirect INPUT child element.

Please note: Throws an error if the specified element does not have exactly one direct or indirect INPUT child element.

Arguments:
e - Event object

Consumes the specified event, i.e., invokes e.preventDefault() and e.stopImmediatePropagation().

Arguments:
cb - callback function
arg - optional argument

Invokes the specified callback function on the next event cycle. The arg argument is passed if specified.

callback function arguments:
this - internal queue item
arg - optional argument or undefined

Arguments:
el - DOM element
qi - queue item

Schedules an action to execute on the next animation frame.

The specified qi queue item is an object expected to contain the cb property referring to a callback function.

The callback function is scheduled to execute once during the next animation frame, regardless how often eq.Dom.onNextFrame() is invoked on the same element and on the same callback function.

callback function arguments:
this - queue item
el - DOM element
qi - queue item, same as this

Please note: The Editgrid plugin example demonstrates how to use eq.Dom.onNextFrame() to synchronize scrolling its column titles.


 
 
 
  Privacy | Webmaster | Terms of use | Impressum Revision: 2024-10-28  
  Copyright © 1995-2024 Marxmeier Software AG