KWEBAPP-JAVASCRIPT(1)

NAME
kwebapp-javascript - implement web application JavaScript and TypeScript classes

SYNOPSIS
kwebapp-javascript [-t] [config...]

DESCRIPTION
The kwebapp-javascript utility accepts a kwebapp(5) config (defaulting to standard input) and creates JavaScript or TypeScript classes formatting the JSON produced by kwebapp-c-header(1) and kwebapp-c-source(1). The configuration may be broken apart into several files. Its arguments are as follows:

-t  Emits Typescript instead of JavaScript.

config
    Configuration file in kwebapp(5) syntax.

Both output formats consist of a set of classes within the "kwebapp" namespace describing structures, enumerations, and bitfields. The method for acquiring the JSON is not managed by kwebapp-javascript, but is usually provided by a CGI interfacing with kwebapp-c-header(1) and kwebapp-c-source(1).

To use the interface, simply include the generated file as a script, create objects from the JSON exported by kwebapp-c-source(1), and invoke the applicable object's fill(), fillByClass(), fillInner(), fillInnerByClass(), fillArray(), fillArrayOrHide(), and fillArrayOrShow(), methods with a DOM tree node.

These methods operate on elements with certain classes beneath a given element root as follows:

foo-xxxx-bits-checked
    Sets or unsets the checked attribute depending upon whether the input's value attribute is covered by the object's bitmask. Only applicable to bit types.

foo-xxxx-date-text
    Replaces the contents of the element with the ISO 8601 date of the object's value. Only applicable to date and epoch types.

foo-xxxx-date-value
    Sets the value attribute to the ISO 8601 date of the object's value. Only applicable to date and epoch types.

foo-xxxx-enum-select
    All <option> descendents of the element are marked as "selected" or not depending upon whether their value matches the field value.

foo-xxxx-obj
    For structures, creates and invokes the fillInner() method on the nested structure at the given element and its descendents. This is only applicable for structure types.

foo-xxxx-text
    Replaces the contents of the element with the field value. This is not applicable to blob native types.

foo-xxxx-value
    Sets the value attribute (as in a form submission) with the field value. This is not applicable to blob native types.

foo-xxxx-value-checked
    Sets or unsets the checked attribute depending upon whether the input's value attribute matches the objects. This is not applicable to blob or structure types.

foo-has-xxxx
    Remove the “hide” class if the object is null, otherwise add the “hide” class.

foo-no-xxxx
    Add the “hide” class if the object is null, otherwise remove the “hide” class.

The fillInner() and fillInnerByClass() methods may be used to exclude the passed-in root element, while fill() and fillByClass() include this element.

The fillArray(), fillArrayOrHide(), and fillArrayOrShow() methods invoke fill() repeatedly over an array of objects by removing, then subsequently cloning and appending, the first element of the give DOM root. The show and hide variants perform additional labour, usually to show a message that elements have not or (more rarely) have been found.

Enumeration and bitfield classes are also generated from the input file. These are appended to the namespace as a series of classes consisting of static variables assigned the enumeration value.

All output objects are fully documented in the jsdoc(1) format.

  Customisation
All functions accept an optional argument for providing custom per-field or per-structure callbacks. Keys in the object must consist of the structure name, followed by a dash, followed by the field name. For example, assuming a structure “client” with a field “dob” consisting of a UNIX epoch:

    var custom = { 'client-dob': formatDate };
    new kwebapp.client(obj).fillInner(document.body, custom);

And letting a formatting function be:

    function formatDate(e, name, value) {
      var list, i;
      list = e.getElementsByClassName('client-dob-date-moment');
      for (i = 0; i < list.length; i++)
        list[i].innerHTML =
          moment.unix(value).format('DD-MM-YYYY'));
    }

This invokes the “moment.js” formatter to create dates.

The same can be applied to structures instead of to fields within structures. The keys for these are simply the structure name.

    var custom = { 'client': formatClient };
    new kwebapp.client(obj).fillInner(document.body, custom);

The callback will then be provided the full client object.

In either case, the value for the custom key may also be an array of functions just as above. Each will be invoked in the order given, in the same way.

    var custom = { 'client': [ format1, format2 ] };

The callback function (or functions) will be invoked regardless of whether the value has been set. In the event of an unset field value, the function is passed null.

When using TypeScript, the values of the format function are typed according to the structure or field passed. For example, if the “dob” field of structure “client” is a UNIX epoch, the format function accepts a number or null.

    function formatDate(e: HTMLElement,
      name: string, v: number|null): void {
    	/* Do something... */
    }

The dictionary object is defined as follows:

    let custom: DataCallbacks = { 'client-dob': formatDate };
    new kwebapp.client(obj).fillInner(document.body, custom);

  Enumeration and Bitfield Labels
Enumerations and bitfields in kwebapp(5) are translated into classes with a static format() function that may be passed as a custom handler for corresponding fields. These fill in the kwebapp(5) jslabel of the corresponding values. If a language is specified in the root of the HTML or XML document, it is first matched to the language of the label. If there is no language, or none for that label, the default label is used. If there is no default label, an empty string is used instead.

In the event of unset bitfields, the corresponding kwebapp(5) isunset value is used, and the kwbp-unset class set on the element. For null values, isnull is used and kwbp-null set on the element.

For example, to fill in the label of an enumeration enum someenum on a field named val, provide a custom callback.

    var obj = JSON.parse(response);
    var e = document.getElementById('foo');
    var custom = {
      'foo-val': kwebapp.someenum.format
    };
    new kwebapp.foo(obj).fill(e, custom);

EXIT STATUS

EXAMPLES
Given a kwebapp(5) structure “foo” with a single field “bar” and an AJAX response “response”, an example invocation may be as follows:

    var obj = JSON.parse(response);
    new kwebapp.foo(obj).fill
      (document.getElementById('foo'));

This will fill in all classes under e (if found) named foo-bar-value, foo-bar-text, foo-has-bar, foo-no-bar, and foo-enum-select.

The TypeScript interface would instead look as follows, assuming that the JSON parse returns the “foo” JSON object.

    let obj: kwebapp.fooData =
      <kwebapp.fooData>JSON.parse(response);
    new kwebapp.foo(obj).fill
      (document.getElementById('foo'));

SEE ALSO
jsdoc(1), kwebapp-c-header(1), kwebapp-c-source(1), tsc(1), kwebapp(5)