This article refers to dap version 0.1.6

Dap 0.1.6 Starter Kit

The dap Starter Kit is a set of simple dap libraries providing some handy dap-style functionality, not included into dap core. These libraries do not pretend to be exhaustively sufficient in their purpose. They are rather a sort of starting point for developers, to help them in development of their own libraries.

Dap Starter Kit is distributed under LGPL. You are welcome to study, modify and redistribute your copies of Starter Kit libraries. Unlike DAPMX core script, dap libraries (including Starter Kit ones) cannot be served directly from They must be deployed on your website (be served from the same origin) to be available to XMLHttpRequest from your page.


This library facilitates some HTML-specific aspects of document handling.


  • htm.js

    Evaluates input value as javascript, returns the resulting value

  • htm.h, htm.p, htm.b, htm.i

    wraps input value with corresponding HTML tag, returns the resulting HTML node

  • htm.cssurl

    wraps input into url(' ... '). Handy for specifying urls in a node's CSS style

  • htm.ask

    Prompts user for a value, using token value as prompt message (escaped). Returns user input.


  • htm.option

    builds an option element from the token list. Anonymous tokens are added to the option's text, named tokens are mapped onto the option's attributes. After all tokens are mapped, the option's value attribute is compared against its selected attribute; if they match, selected attribute is set to "selected", otherwise removed.

  • htm.inputs

    flattens the token list into an array of html form inputs. Anonymous tokens specify the type of inputs generated from consequent tokens. Named tokens produce html inputs having name attribute set to the token's alias, and initial value equal to the token's value.


  • htm.? @alias=value

    If value is true, assigns the CSS class specified by alias to the node. Multiple classes may be specified comma separated.

  • @alias=value

    Sets the node's style aspect specified by alias

  • htm.! @alias=value

    Sets the node's property specified by alias

  • htm.%$target @alias=value

    Maps the node's property specified by value onto target field specified by alias. If value not specified, it is assumed "value". This mapper is handy for extracting HTML form inputs' value property.


d="htm.?@grow=asc yesterday today; htm.? today@positive:+? today@negative:-?"
Add CSS class 'grow' to the node if today's value is greater than yesterday's; and assign 'positive' or 'negative', depending on the today's value sign.

d=" @backgroundImage:cssurl=myBG.jpg"
Set node's style.backgroundImage property to url('myBG.jpg')"

d="htm.! @id=myFavoriteNode @style.borderColor=red"

u="htm.% @selectedNodeId=id @selectedNodeName=nodeName; htm%$result"
Copies the node's id property to selectedNodeId datafield, node's nodeName property — to selectedNodeName datafield, and node's value property to $result status variable.


Currently, grid.xml only contains a grid. flattener wich allows client-side rowset sorting, and a few markup templates facilitating creation of sortable html tables.

The grid. flattener allows to dynamically change order-key field and order direction. To get an ordered rowset from unordered, three tokens should be fed to the grid. flattener in this very order:

  • The source rowset — fed anonymous (like, $rowset@)
  • The sort key field — fed with alias "sort" (like, $sort or $column@sort). Value specifies the field by wich the dataset is sorted.
  • Reverse flag — fed with alias "reverse" (like, $reverse or $dsc@reverse). When value is present, the rowset is reversed, otherwise it is not.


<table d="$rowset:#dat =/samples/pricelist.xml;  $sort= $reverse=" class="grid">
  <tr u="-$reverse">
   <td d="ui" u=" $sort=product">product</td>
   <td d="ui" u=" $sort=name">name</td>
   <td d="ui" u=" $sort=price">price</td>
 <tbody d="*=grid. $rowset@ $sort $reverse">
  <tr d="attr description@title; ui">
   <td d="! product"></td>
   <td d="! name"></td>
   <td><i d="! price:fo.num"></i> USD</td>

In this example, the table is sortable by any column. Click a column head to sort. Click again to reverse order.

product name price

Client-side sorting can be handy in many cases. However, it is not a replacement for server-side ORDER BY's. Client-side sorting should only be used for rowsets, wich are guaranteed to be complete fetches (not imposed to rows count limit, say by TOP clause in SQL). Otherwise (if the fetch is clipped), the sort result will be incorrect.


This library implements a dap-style "events" model, wich is mostly aimed for non-destructive visual masking (such as fades, slides etc.) of dap-nodes. Non-destructive visual masking of a node means that only the node's appearance-related properties are affected (such as opacity, clipping etc.), while the page's DOM is not changed. Such a way is somewhat similar to what they call "javascript menus" or "javascript effects" or the like. The difference is that you don't need to keep track of all elements on page (providing them all with unique names, binding mouse event handlers etc.) that might be fairly tricky for dynamically transformable dap documents.

Syntactically, dap-style events are ordinary datapieces. As any data piece in dap, any dap "event" is bound to the scope it was defined in. Any observer of that scope may fire the event and signup to recieve kicks from it. Effectively, a dap "event" is just a "hub", wich broadcasts kicks over its scope.

The primary purpose of this "event model" is support for animated fades and slides. A node may have a number of event → goal bindings, each of them stating that on the specified event the node shall start moving toward the specified goal.

A goal describes the visual state of the node. It may specify such aspects of visual appearance as node's opacity and margins. It may also specify the tween timing aspects, such as duration and damping. Support for more aspects can be implemented easily and added to the library.

A special very simple mini-language is used to describe goals. All aspects are represented by aspect:percentage pairs (very similar to CSS syntax). All aspects are measured in percents, where 0 corresponds to the node's "default", visible state; and 100 — to "completely hidden" state. For example, aplpha:50;bottom:90 goal signature describes a target state, where the node is semi-transparent and 90 percent cut from the bottom. The percentage may be omitted, in wich case its value will be recalculated every next time as a complement to current at the moment — in other words, it toggles each time event fires.

Goals are grouped into behaviors. A behavior may contain any number of arbitrary named goals.


On the top of each square you can see the goal bound to the square beneath it. Click the goal to see its action.

The former three goals in this example are one-way: the aspects are provided with values; you'll have to hit reset to get the square back. The latter three are two-way goals — aspects are toggled each time the goal line is clicked.



The trivial routine to add fx functionality to a node, is:

  1. Specify a behavior with a set of goals

    d=":fx.behavior@fooBehavior= @show=alpha:0 @hide=alpha:100 @toggle=alpha"
  2. Define the events in the scope of a common ancestor of all involved nodes

    d=":fx.event @fooToggle @fooShow @fooHide"
  3. Involve the listeners using fx.? mapper:

    d="fx.? fooBehavior@show fooToggle@toggle fooShow@show fooHide@hide"
  4. Add event launcher to the triggering node's u-rule

    d="ui@mouseover" u="fx.! fooToggle"


  • fx.behavior

    Converts a datarow object into behavior object. The input datarow's fields must correspond to the output goals and contain the goal style (a string).

  • fx.event

    Returns an event object.


  • fx.?

    If a token specifies a behavior, the node adopts that behavior. The token's alias specifies initial goal for the node.

    If a token specifies an event hub, signup for that event. The token's aliases specify the target goals for event over this node.

  • fx.!

    Fire the event. All event signees are kicked by the hub and start their way towards the goals, specified for that event.