Components

Apps are made up of:

  • An app.js file
  • Widgets
  • And widgets have HTML templates and Javascript controllers

We’ll go over each of these briefly, and later sections will go in to more detail.

app.js

Your app.js file is how DeskPRO “bootstraps” your app. This is how you define which templates you want to render where and load controllers and do anything else your app might need.

Here is an empty app.js file:

define(function() {
    return {
        init: function() {
            console.log("Hello, world");
        }
    }
});

The init method is called once the DeskPRO app platform is ready. This is where you will register your widgets.

Note

The object you define and return in app.js is “mixed in” to a system class called AppContext which defines a number of useful methods that we’ll go over later. We mention this now because you may be wondering how calls to this.someMethod work below if you don’t define them. It’s because these are defined in the system AppContext.

Widgets

Widgets are Javascript controllers that you register for certain types of tabs in DeskPRO. For example, the tab type ticket will run on all tickets. The type org runs on Organization profiles.

Most widgets also define a template that is rendered to a specific location within the tab. For example, tickets have a pre-defined location called header.bottom that renders your template near the top of the ticket tab.

Note

Refer to the glossary for a list of types and pre-defined locations.

Most of your app will be defined as “widgets” because this is how you will tie functionality to a specific place in DeskPRO. For example, by creating a ticket widget, you are able to easily work with data on the ticket, render templates to the ticket view, etc.

Registering widgets

There are three ways to register widgets:

  • this.registerAppWidget(type, templateName, controller):
  • this.registerWidget(type, location, templateName, controller)
  • this.registerWidgetTab(type, location, tabTitle, templateName, controller)
Param Description
type This is the tab type you want to register on. For example, if you want the widget to show on tickets, the tab type would be ticket. Refer to the glossary for a full list of tab types.
templateName This is the name of your template file in the html/ directory. For example, if you had an HTML file called html/Foo/bar.html, then templateName would be Foo/bar.html (so you drop the ‘html/’ prefix).
controller This is a Javascript controller. A new instance of this controller will be created every time your widget is rendered. We’ll have examples of controllers later.
location This is where in the tab to render your widget. There are many pre-defined locations. Refer to the glossary for a list.
tabTitle If you are registering a widget that adds a tab to a tabbed box, this is the title of the tab.

Here’s an app.js that registers a template that renders a template in a ticket header:

define(function() {
    return {
        init: function() {
            this.registerWidget('ticket', '@header.bottom', 'Foo/bar.html');
        }
    }
});
  • ticket is the tab type
  • @header.bottom is a pre-defined location in tickets
  • Foo/bar.html is the name of the template to render (this would need to exist on the filesystem at html/Foo/bar.html).
  • There was no controller specified in this example.

Templates

Templates are just HTML files you save to the html/ directory. Templates are loaded by passing the filename as the templateName paramter when registering a widget.

Templates and controllers work hand-in-hand. Refer to the Templates section for details.

Controllers

Controllers are how you interact with your templates: for example, rendering variables, reading form input, etc.

Here is the source for an example controller:

define(function() {
    return function($scope, $ticket, $el, $app) {
        console.log("Hello, world");
    }
});

Your controller source must return a function as shown above. The paramaters your function receives are important. The names must match values that DeskPRO “knows” about. For example, $ticket is an object representing the current ticket. You could NOT rename this to something else because DeskPRO would not know what it is.

Note

Refer to the glossary for a list of available parameters for each tab type.

Loading Javascript source files

DeskPRO uses RequireJS to define and load script files. This is why all the Javascript you’ve seen so far is written as define() functions that return some kind of value.

You can define your Javascript controllers in separate files and then use RequireJS to load them. For example, here is an app.js file that defines two controllers and itself all in one file:

define(function() {
    var ControllerA = function($scope) {
        $scope.hello = 'world';
    };
    var ControllerB = function($scope, $ticket) {
        $scope.foo = 'bar';
    };

    return {
        init: function() {
            this.registerWidget('ticket', '@header.bottom', 'hello.html', ControllerA);
            this.registerWidget('ticket', '@header.bottom', 'Foo/bar.html', ControllerB);
        }
    }
});

As you can imagine, if those controllers were very long, your app.js file would become very big and overly complicated. So it’s good practice to separate the source files:

 // This would be saved at js/Controllers/ControllerA.js
 define(function() {
    return function($scope) {
        $scope.hello = 'world';
    };
);

// This would be saved at js/Controllers/ControllerB.js
define(function() {
    function($scope, $ticket) {
        $scope.foo = 'bar';
    };
);

// This is app.js, but notice how we are adding dependencies
// to the define() call to load the other source files.
define(['Controllers/ControllerA', 'Controllers/ControllerB'], function(ControllerA, ControllerB) {
    return {
        init: function() {
            this.registerWidget('ticket', '@header.bottom', 'hello.html', ControllerA);
            this.registerWidget('ticket', '@header.bottom', 'Foo/bar.html', ControllerB);
        }
    }
});