Font Awesome, jsplumbtoolkit-demo.css, and app.css are used for this demo and are not jsPlumb Toolkit requirements. jsplumbtoolkit-defaults.css is recommended for
all apps using the Toolkit, at least when you first start to build your app. This stylesheet contains sane defaults for the various widgets in the Toolkit.

The Start node consists of an ellipse with a text label centered inside of it. Note here - and in all the other
templates in this demo - there are a few main differences between the format of this template and that of a template using
the Toolkit's default templating mechanism:

You do not need to prefix SVG elements with an svg namespace in Angular.

You must prefix SVG attributes if they contain an expression. There are numerous examples of this above: ng-attr-cx,
ng-attr-cy etc. This is how Angular handles the fact that SVG elements are unforgiving when an attribute does not have
a value that is in the correct format (due to the digest loop in Angular, values are not written when the template is
first rendered).

You must also prefix a style attribute, eg ng-attr-style instead of just style. This is just for IE compatibility;
other browsers allow you to specify style.

All references to the node data that is being rendered are prefixed with node.. For instance, the first line in the
template here is:

<divng-attr-stylestyle="width:{{node.w}} px;height:{{node.h}} px;">

but in the version of this demo using the default templating mechanism it looks like this:

<divstyle="width:${w}px;height:${h}px;">

Any jtk-source, jtk-target or jtk-port elements that are intended to configure the node's main container have to
be placed in the root of the template. This is in contrast to the default templating mechanism, which expects one
root element per template. It is due to the fact that the template is rendered by Angular inside of its directive element,
and the directive element is not discarded. There is a mechanism in Angular to instruct it to remove the original
directive element (replace:true in a directive), but this is deprecated and not recommended by Angular, and will not
work with the Toolkit integration.

The jtk-source element declares that this node is an edge source, of type start (the port-type attribute
specifies this). The filter attribute instructs the Toolkit to enable drag only from some element that is not a
child of an svg element, but then filter-negate is true: the result is that dragging will begin only from a
descendant of the svg element. What this means visually is that the user will not be able to start a drag from the
whitespace surrounding the ellipse.

The main things to note here are that the scope passed in to this method contains toolkit and surface members. This
demo assigns the toolkit member to a variable in the Controller's scope, so it is subsequently available
everywhere.

Data Loading

Dragging New Nodes

As discussed above, a jsplumb-palette is declared, which configures all of its child li elements to be droppable onto
the Surface canvas. When a drop occurs, the type of the newly dragged node is calculated by the typeExtractor
function declared on DemoController:

Edit Node Text

$scope.editNode=function(node){varinfo=this.surface.getObjectInfo(node);jsPlumbToolkit.Dialogs.show({id:"dlgText",data:info.obj,title:"Edit "+info.obj.type+" name",onOK:function(data){if(data.text&&data.text.length>2){// if name is at least 2 chars long, update the underlying data and// update the UI.toolkit.updateNode(info.obj,data);}}});};

The meat of this method is the same as that which the original FlowchartBuilder demo has; it's just the trigger to
launch the method that is different.

Note here the getObjectInfo method: this is method with which you will want to acquaint yourself. It is defined on a
Surface, not on a Toolkit instance, and takes a DOM element as argument and places it within the context of some object
managed by the Toolkit instance that the Surface is associated with. In this case, the click event occurs on an
icon. getObjectInfo traverses up the icon's ancestors until it finds an element that is associated with a Toolkit
object - in our app, either a Table or View. When a Toolkit object is found, getObjectInfo returns an object with these
values:

id ID of the Toolkit object

obj The associated Toolkit object. May be a Node or a Port.

el The DOM element for the Toolkit object

type The type of the Toolkit object. This will be "Node" or "Port".

In this event handler, we show the user a dialog that will allow them to edit the Node's text. If the edited text is
at least two character long we update the model.

This application uses the Toolkit's dialogs import to manage simple interactions with data members such as
this. Your application may choose to use a different mechanism.

Resizing/Dragging Nodes

To resize or drag a node first you must either click on it, or use the lasso (described below) to select
it. A selected node looks like this:

The dotted line and drag handles that are added to a selected Node are put there by the Tookit's drawing tools. It
listens to the Toolkit's select/deselect events and decorates UI elements accordingly. These tools are discussed in detail on this page.

The drawing tools are initialized with this line of code (inside DemoController.init):

Selecting Nodes

Left Click

Nodes can be selected with a left-click (or tap on a touch device; tap is a better event to choose in general because the
Toolkit abstracts out the difference between mouse devices and touch devices and presents click events as tap events
on non touch devices). This is configured in the view parameter to the render call. In this application,
Nodes of type selectable have the capability enabled with this code:

The tap event (discussed here) is preferable to click, as it ensures the application responds only to true clicks on devices with a mouse, and also avoids the delay that some vendors introduce to a click event on touch devices.

Here we've registered an event listener to be informed when the Surface's mode has changed; it is responsible for setting the appropriate classes on the toolbar items. The click listener extracts the desired mode from the button that was clicked and sets it on the renderer.

Lasso Operation

The lasso works in two ways: when you drag from left to right, any node that intersects your lasso will be selected. When you drag from right to left, only nodes that are enclosed by your lasso will be selected.

Exiting Select Mode

The Surface widget automatically exits select mode once the user has selected something. In this application we also listen to clicks on the whitespace in the widget and switch back to pan mode when we detect one. This is the events argument to the render call:

events:{canvasClick:function(e){toolkit.clearSelection();}}

clearSelection clears the current selection and switches back to Pan mode.

Dialogs

The dialogs used in this app are part of the jsPlumb Toolkit core. They provide a simple abstraction around the business of getting input from the user and dealing with it; they're not necessarily fully-featured enough for all applications.

Initialization

To initialize the dialogs, first call jsPlumbToolkit.Dialogs.initialize, with an appropriate selector for the templates for your dialogs (see below for an explanation of this):

Binding Parameters

These templates use the same template engine as the Surface renderer, so in this example you can see we've extracted query from the View node's data, and injected it into the textarea. But what might not be immediately obvious is the purpose of the jtk-att attribute: it tells the dialog handler that the value of this textarea should be passed to the OK handler, using the key query.

Note also in the above example, the jtk-focus attribute: this tells the dialog handler that the textarea should be given the focus when the dialog first opens.

Showing a dialog

This example is the dialog that is shown when you edit a View query. We provide the id of the template to use for the dialog, and we provide the View node's data as the backing data for the dialog. Then we provide an onOK callback:

The data argument to the onOK callback consists of an object whose key value pairs are determined by the jtk-att attributes found in the template. Recall that above we had a textarea with jtk-att:"query". This means that the data argument to onOK looks like this:

{query:"the contents of the text area"}

Supported Input Types

The list of supported input types is:

text

radio button(s)

checkbox

select

textarea

Dialog Titles

If you set a title attribute on a dialog's template, that value will be used for the title of the dialog.
Alternatively, you can provide a title parameter to the show call.

Lifecycle Callbacks

There are three lifecycle callbacks supported:

onOpen Called when the dialog has been opened. The related DOM element for the dialog is passed to this method.

onOK Called when the user presses OK. The callback is provided a data object as discussed above.

onCancel Called when the user presses cancel. No arguments are provided to the callback.