Introduction

One great feature of the jsPlumb Toolkit is the way client side templating is baked right in - your Node, Group and
Port definitions in the View declare the id of some template to use and the Toolkit takes care of the rest.

Rotors is the default template adapter in the jsPlumb Toolkit. You can use
any templating mechanism you want to - you just need to write an appropriate adapter, and provide this function
as the value of the templateRenderer parameter - but it is recommended that you use Rotors, because Rotors'
ability to update previously rendered content means that you can update your UI "automatically" from a change to
the data.

Here's what the table template looks like in the Database Visualizer application:

<scripttype="jtk"id="tmplTable"><divclass="table"><divclass="table-name">
${name}
<divclass="new-column"title="Click to add a new column">+</div></div><ulclass="table-columns"><r-eachin="columns"><r-tmplid="tmplColumn"></r-tmpl></r-each></ul></div></script>

Limitations

When using the default template engine, your templates must return a single root node. If you return multiple
nodes, the Toolkit will use the first node only.

Inferring Template IDs

As shown above, the Node and Port definitions passed as part of the view parameter on a render call allow you to
specify a template to be used to render an instance of the given type. Sometimes you will find that you have nothing
other than a template directive in a Node or Port definition. So to cut down on boilerplate, the Toolkit will make
a guess at a suitable template id if you do not provide.

The inferred template id consists of "jtk-template-" as a prefix, followed by the type of the object. So in the
previous example, a Node of type table would have an inferred template id of jtk-template-table.

Custom Template Resolver

The default template resolution mechanism is to look for a <script> element in the DOM with an ID matching the ID of
the template to retrieve. You can supply your own template resolver like this:

toolkit.render({container:...,view:{...},templateResolver:function(templateId){// find the matching template and return it - as a String.}});

For some use cases, where the templates are not overly complex, this can be handy.

Configuring Connectivity

Note from version 1.2.6 onwards this information applies to Groups as well as Nodes/Ports. Prior to version 1.2.6 this applies
only to Nodes and Ports.

jtk- Elements

To configure your UI to allow for the user to establish connections using the mouse, you use one or more custom tags in
your HTML templates. In the previous section, we saw a template that had a jtk-source and a jtk-target element;
these were used to declare that the given element should act as both a connection source and connection target.

A third custom element available in the jsPlumb Toolkit is jtk-port - used to declare an Endpoint on some element.

A full discussion of each element follows.

jtk-source

This element is used when you want to configure some element as a connection source. It is analogous (and maps directly to)
the makeSource method in jsPlumb. The element that is configured as the connection source is that element which is the
parent of the jtk-source element - here, it's the .table-column li.

Six attributes are supported on the jtk-source element:

port-id

This defines the id of the port on the node. It is not mandatory: if you use the jtk-source element to turn some Node
into a connection source, then you don't need to set this attribute - you are configuring the Node's default Port. If
you wish to assign this connection source to a Port, though, then you must set this attribute. This attribute's value
must be unique on its Node, but may be the same as the id of some Port on another Node. Here we are using the id
member of the data backing the column.

port-type

Maps to a Port type in the view, as discussed above. Note that you can set this even if you don't set port-id, as you
will want to associate a Node's default Port with some type.

scope

The jsPlumb Toolkit can make use of jsPlumb's scope concept to control, in a relatively crude way, what can be
connected to what. In this template you see that both the jtk-source and jtk-target elements use the same value for
scope, and in the Database Visualizer this is mapped to the column's underlying datatype. There is a more sophisticated
mechanism available to control connections should you need it: see Interceptors.

endpoint

Setting this to true causes jsPlumb to create an Endpoint for the given Node, and not to configure the element itself
as a drag source. The created Endpoint is used for any Edges whose source is the given Node. New Edges may be dragged
from the Endpoint.

filter

Oftentimes you will want to configure an element as a connection source but not actually have the entire element respond
to a connection drag start. This is quite common in the sorts of UIs for which the jsPlumb Toolkit is used: you need to
be able to drag your nodes around the screen, but you'd also like to be able to drag connections from the nodes too.
Using filter you provide a CSS selector that identifies elements from which connection drag should be supported.

filter-exclude

If you run into a problem specifying a suitable selector for the filter (:not selectors, in particular, are a little
restricting), you can set filter-exclude:true, which will mean that the elements identified by the filter selector
will be excluded from starting a drag.

jtk-target

This element is the opposite of the jtk-source element: it allows you to identify its parent as an element that you
wish to configure as a connection target. It also has an analogue in jsPlumb to which it is directly mapped: makeTarget.

This element supports four of the six attributes supported by jtk-source. Their meaning and usage is the same:

port-id

port-type

scope

endpoint

The fifth and six parameters - filter and filter-negate - are not supported, which means that it is always the
entire element that is configured as a connection target. It is possible that, in the future, jsPlumb will support the
filter and filter-negate attributes on the makeTarget method. If/when that happens, the Toolkit's jtk-target
element will be updated to also support them.

jtk-port

Use this element when you want to have an Endpoint added to your UI and map it to a Port. Its analogue in jsPlumb is the addEndpoint method.
This element supports the same attributes as makeTarget (with the exception of endpoint), plus some extras:

port-id

port-type

scope

anchor-x This attribute can be used to specify the location, in the x axis, of the Anchor used by the
Endpoint associated with this Port. This is a proportional value, as discussed in the
anchor documentation.

anchor-y This attribute can be used to specify the location, in the y axis, of the Anchor.

orientation-x Used to associate an orientation, in the x axis, with the Anchor associated with the Port. Orientation is discussed
in the anchor documentation linked above. This is optional, but if omitted, the default of 0 will be used.

orientation-y Used to associate an orientation, in the y axis, with the Anchor associated with the Port.

Note using this declarative means of configuring ports does not mean that the UI artefacts associated with the
Endpoints exist in the DOM as children of the port's parent element. Remember that the Toolkit always makes use of
jsPlumb's Container concept, to ensure that all of the Endpoints and Connections contained inside a given Surface
have the same parent.

Note also that any jsPlumb Toolkit elements that are found during rendering are removed from the DOM after processing.

External Templates

To help you organize your templates better, you can store them in external files and reference them via a script import in your HTML:

The key here is that the type is text/x-jtk-templates. There may be one or more templates declared in the specified file.
This example is one from one of the Toolkit's unit tests; the file contains several templates. Here's the first two:

You can have multiple x-jtk-templates scripts declared in your html. Note, though, that the loading of these scripts postpones the firing of the ready event in the Toolkit,
so you should ensure you're not getting any 404s and what you are loading is loading quickly.

Rotors

Rotors is the default templating mechanism used by the jsPlumb Toolkit. It uses a strict XHTML syntax and can run both
in the browser and headless on the server.

With an Object

The key here is that each entry is presented to the template as an object with $key and $value members.

If

There are two if statements in Rotors: one that is an element, which you use in the body of your templates, and one that is
inline, which you use inside tags to selectively include/exclude attributes:

Existence

<r-if test="someObjectRef">
<div>hola</div>
</r-if>

Expressions

<r-iftest="foo == 5"><div>hola</div></r-if>

Inline

<inputtype="radio"class="foo"selected></input>

Notes

you can not use the IF statement inside an attribute expression.

an IF statement is executed once and once only. If your dataset changes in such a way that the IF statement would have
resolved differently, this will not be detected by Rotors. If you have some content you wish to selectively show/hide, a
better approach is to render everything and use CSS along with data- attributes to hide the things you do not wish to
see under certain conditions.

Else

The element version of the IF statement has an optional ELSE statement:

<r-iftest="something"><divclass="success">ok</div><r-else><divclass="fail">things are not ok.</div></r-if>

For

The r-for tag takes a loop attribute that specifies how many iterations you want. It can be a static value:

<r-forloop="5"><div>${$index}</div></r-for>

..or it can be a computed value (from the data that is in scope at the time the for loop executes):

<r-forloop="somelist.length"><div>${$index}</div></r-for>

You might, for instance, have called the template that renders the for loop above with this data:

{somelist:[0,1,2,3,4]}

The current loop index is available as the $index parameter inside the template.

Comments

Comments follow the standard XHTML syntax:

<div><!-- a comment <span>Maybe some code was commented</span>--></div>

Comments are stored in the parse tree for a template. This may or may not prove useful.

Embedding HTML

By default Rotors treats text as plain text. For example with this template:

Nested Templates

With specific context

<div><r-tmplid="nested"context="someItem"></r-tmpl></div>

Inheriting parent context

<div><r-tmplid="nested"></r-tmpl></div>

The difference between these two examples is that in the first, an item called someItem is extracted from the current
dataset, and passed in to the nested template, whereas in the second, the nested template is passed the exact same
data that the parent is currently using to render itself.

With complex context

You are not limited to extracting single variables from the current context to pass in to a nested template. You can
specify a complex object too:

<div><r-tmplid="nested"context="{id:foo, label:'Hello'}"/></div>

In this example, foo will be extracted from the context in which the current template is executing, and Hello is
a hardcoded string.

# Accessing nested properties

You can also specify properties that are nested inside the current context, either with dotted notation:

will result in a node element with a span that says FOO-NEW, and a list of three items: un, deux and trois.

Updating the class attribute

Rotors won't update the class attribute once a template has been written. Since the update method can only write values
for classes that were in the template, there's a risk that any classes added by other parts of your app would be removed.
For example say you have this template:

<divclass="${nodeType}">
FOO
</div>

If you render this with {nodeType:"start-node"} then you'd end up with a div with class start-node. Then say some
code comes along and does this:

$(myDiv).addClass("selected");

Now you've got a div with class start-node selected. If you then called update, Rotors would re-write the class
attribute to have only the nodeType class; probably not at all what you want. In this scenario you are better off
using attribute selectors.

Alternative Template Renderers

You can provide your own template renderer to replace Rotors, should you wish to, by supplying it as the templateRenderer argument
to a render call on an instance of the Toolkit.

Note as mentioned above, it is recommended that you use Rotors, because Rotors' ability to update previously rendered
content means that you can update your UI "automatically" from a change to the data. Using some other template renderer will
mean that the updateNode, updatePort and updateGroup methods cannot automatically update your UI.