Angular Integration

The jsPlumb Toolkit offers several components to assist you in integrating with Angular (1.x). The Toolkit uses "strict" format in all of its Angular components.


The Toolkit's Angular components are stored in a separate file - jsPlumbToolkit-angular-x.x.x.js. You need to import this file, after you import the Toolkit.

The Angular components are stored inside a module called $jsPlumb:

var app = angular.module('app', ['$jsPlumb']);



This directive creates a Toolkit instance and renders it to the given element.

<jsplumb-toolkit surface-id="mySurface" jtk-id="myToolkit" params="ToolkitParams" renderParams="RenderParams">

    You can put content in here.

  • jtk-id Identifier for the Toolkit. Strictly speaking this is not required, but if you need to access the Toolkit via the jsPlumbService you will need to have set this.

  • [surface-id] Provides the identifier to associate with the created Surface widget. This is optional, but you will need to provide this if you wish to attach a jsplumb-miniview or jsplumb-palette.

  • [params] Optional reference to parameters for the Toolkit constructor. By "reference" we mean the name of some variable that is in the scope in which the directive is executing.

  • [renderParams] Optional reference to parameters for the render call. By "reference" we mean the name of some variable that is in the scope in which the directive is executing.

  • [init] Optional reference to a function that will be called once the Toolkit and Surface have both been instantiated. The function's method signature is:

init(scope, element, attrs, controller);
  • [data] Optional reference to some Object in scope that contains the data for the Toolkit to load.


Creates a Miniview:

<jsplumb-miniview surface-id="mySurface"></jsplumb-miniview>
  • surface-id The ID of the Surface widget to which this Miniview should attach itself. Required.

Note When using the jsplumb-toolkit Angular directive you must use the jsplumb-miniview directive to configure a Miniview. Any miniview declared in the renderParams will be ignored.


This directive is declared as both an Attribute and Element directive. Here it is used as an Attribute directive:

<div class="someClass" jsplumb-palette selector="li" type-extractor="typeExtractor">
        <li data-type="foo">FOO</li>
        <li data-type="bar">BAR</li>
  • jsplumb-palette This is what turns the directive on for the element.
  • selector A CSS3 selector identifying which child elements should be configured as draggable/droppable.
  • [type-extractor] The name of an optional function that is in scope that can be used to extract the type of a dropped node.

The type-extractor is used to determine what is the type of a dropped node. In the example markup above, a suitable type-extractor function would be:

$scope.typeExtractor = function(element) {
    return element.getAttribute("data-type");    
  • [generator] The name of an optional function that is in scope that can be used to prepare some initial data for a dropped node.
  • [location-setter] The name of an optional function that is in scope that can be used to set the location of a dropped node.

For a more detailed explanation of the last three parameters, see here.

Rendering Nodes

When using the Angular integration you do not need to use Angular to render your nodes if you do not want to - you can use the standard Toolkit templating mechanism. If you wish to use Angular, though, you will need to create a directive for each Node type, and you'll need to use the jsPlumbFactory to do this. Here's an example from the angular integration demo (which is the Flowchart Builder application converted to use Angular):

 var app = angular.module('app', ['$jsPlumb']);
 app.directive('question', function (jsPlumbFactory) {
     return jsPlumbFactory.node({
         inherit:["removeNode", "editNode"],
         templateUrl: "question_template.tpl",
         link:function(scope, element) {
             element.addClass("flowchart-object flowchart-question");

The key here is the call to jsPlumbFactory.node. This method takes care of setting everything you need; you provide the URL of the template to use and optionally a link function. You'll also notice a parameter called inherit in this example - this is discussed below.


You cannot provide an inline template; your templates must be declared somewhere in your HTML.


A link function is not required, but can be provided if you wish. In the Toolkit's Angular demo, the link function is used to get around the fact that when the Toolkit renders Nodes via Angular, there is no declarative way of setting attributes (such as the class name) on that directive's root element. So in this link function you can see we retroactively set a couple of classes on the Node's root element.


This concept is not a core Angular concept. It is a helper that enables you to declare items from your Controller's scope that you wish to have in your Node's scope. The mechanism used by the Toolkit, out of necessity, creates an isolated scope for each Node. The inherit mechanism will pull named items out of the isolated scope's ancestors and copy them in to the isolate scope itself. In the Toolkit's Angular example, removeNode and editNode are functions declared in the controller's scope that all Nodes need to have access to.

jsPlumb Service

Accessing Toolkit/Surface instances

To access instances of the Toolkit or of the Surface widget, you can use the jsPlumbService:

app.controller("FooController", [ "jsPlumbService", function(jsPlumbService) {
    var toolkit = jsPlumbService.getToolkit("myToolkit");
    var surface = jsPlumbService.getSurface("mySurface");

Resetting a Toolkit instance

Should you wish to clear a Toolkit instance (this is not the same as the Toolkit's own clear method: this is for clearing a Toolkit reference out from the service, so that subsequent requests for the Toolkit with the given ID will cause a new Toolkit to be created), you can make this call:


Binding Events

To bind to an event on a Toolkit, which may or may not yet exist, you can use the service's bind method:

app.controller("FooController", [ "jsPlumbService", function(jsPlumbService) {
    jsPlumbService.bind("ready", "myToolkit", function() {
        alert("The toolkit is ready");

In most cases when you try to bind to a Toolkit it will have been created. In the above example it may well not have been; in general you can use this method for safety if you haven't yet got a concrete handle on the Toolkit instance you want.

jsPlumb Factory

We saw above that you need to use the jsPlumbFactory when declaring directives for Nodes.