Editing widgets

After you have created a widget, select it from the “Your Widgets” section of the Apps area in the Admin Interface.

../_images/widget-edit1.png

The first thing you see is this App Definition. It looks a little scary, but you can ignore this section entirely. It was automatically generated by DeskPRO and you will probably never need to edit it.

Note

The fact is that Widgets are actually fully-feautred Apps under-the-covers, and the App Definition is how an app configures itself. It tells DeskPRO which templates you have defined and where to put them.

Ignore the first App Definition tab and switch to any of the other tabs which contain the HTML and Javascript templates you can edit to actually add content to your widget.

../_images/widget-edit2.png

For every location you checked during the widget creation step, you will have two files: A Javascript controller and an HTML template.

Javascript controller

The Javascript file is what we call a controller. Here is where you can add custom Javascript code like AJAX calls or event handlers. All of your JS code should live within that one function controller.

You’ll notice that the default JS controller accepts a number of paramaters. The next section goes into more detail about how JS controllers work, but briefly:

  • $scope is a special object that lets you connect your JS controller to your HTML template. Any value you assign to $scope will be available from your template. We’ll go over a few examples in a moment.
  • $ticket is an object containing all of the current ticket information including things like the ticket ID, the subject, the user, the user email etc. There is a lot of information here. To view the available values, the easiest thing to do is use console.log($ticket) and then view your browser console (e.g., Chrome Developer Console).
    • If you specified a different tab type, such as a user or organization profile, you won’t see $ticket. Instead you’ll have $person or $org which are user info and org info, respectively.
  • $person is also available on tickets, it’s an alias for $ticket.person.
  • $http is a service for performing AJAX requests. We’ll go over a few examples below.
  • $el contains a jQuery-wrapped element that is the outer container for your HTML template. You can use this to fine specific elements in your HTML template. For example, $el.find('input') to find an input box.
    • Note that there are much better ways than using jQuery for connecting your JS controller to your template. The next section goes into more detail.
  • $app is a reference to the Javascript object that represents your widget app. It includes things like your app ID. You probably will never need to use this.

HTML template

Below the JS file is the HTML template file. This HTML template has special features attached to it that makes it easy to interact with the JS controller. We go into more detail in the next section, but here are a few examples.

Binding variables

Perhaps the most common thing you will want to do is to render values from your JS controller in your HTML template. For example, perhaps you have done an AJAX lookup and want to render the results.

To do this, just assign values to the $scope variable in your controller:

$scope.name = 'Christopher'

Then within your HTML template, use the variable syntax:

Hello, {{name}}

You can even use variables to generate things like links:

<a href="http://example.com/script?name={{name}}">Hello, {{name}}</a>

Attaching click events

You could use jQuery and the $el variable to manually attach events. But there is a much cleaner way to do it.

First, define a function callback on your $scope:

$scope.submitForm = function() {
    alert("Hello!");
}

Then in your HTML template, use the special ng-click attribute on an element:

<button ng-click="submitForm()">Submit</button>

Conditionally showing an element

Use the special ng-if attribute on an element to conditionally show an element based on a Javascript expression:

<div ng-if="name">Hello, {{name}}</div>
<div ng-if="!name">You have no name</div>

Binding form controls

Binding form values can be done with the special ng-model attribute. When the form input changes, the target variable will be set on your Javascript $scope variable.

Enter your name: <input type="text" ng-model="name" />
<button ng-click="submitForm()">Submit</button>

// Javascript
$scope.submitForm = function() {
    alert("Hello, " + $scope.name + "!");
}

Iterating over a collection

If you have an array of data in your Javascript controller:

$scope.family = [
    { name: "John", age: 38 },
    { name: "Jane", age: 36 },
    { name: "Jesse", age: 12 }
];

... then you can iterate over those values in your template with ng-repeat:

<ul>
    <li ng-repeat="p in family">
        {{p.name}} is {{p.age}}
    </li>
</ul>

Using data from the ticket

Use the $ticket object. Here are some commonly used values:

  • $ticket.id - The ticket ID
  • $ticket.subject - The ticket subject
  • $ticket.agent - Is an object containing information for the currently assigned agent:
    • $ticket.agent.id - The agent ID
    • $ticket.agent.display_name - The agent name
    • $ticket.agent.primary_email.email - The agent’s primary email address
    • $ticket.agent.picture_url_80 - The agent’s profile picture scaled to 80x80. Replace ‘80’ with any of these standard sizes: 80, 64, 50, 45, 32, 22, 16
  • $ticket.agent_team.name - The name of the currently assigned team
  • $ticket.department.name - The name of the assigned department
  • $ticket.status - The current status
  • $ticket.urgency - The current urgency
  • $ticket.person - An object containing information about the user who opened the ticket:
    • $ticket.person.id - The user ID
    • $ticket.person.display_name - The user’s name
    • $ticket.person.primary_email.email - The user’s primary email address
    • $ticket.person.picture_url_80 - The user’s profile picture scaled to 80x80. Replace ‘80’ with any of these standard sizes: 80, 64, 50, 45, 32, 22, 16

To use these values in your HTML template, you need to assign them to the $scope:

// Javascript
$scope.user_name = $ticket.person.display_name;

// HTML
Hello, {{user_name}}

Or you could assign the entire ticket object to the scope:

// Javascript
$scope.ticket = $ticket;

// HTML
Subject: {{ticket.subject}}<br/>
User Name: {{ticket.person.display_name}}<br/>
User Email: <a href="mailto:{{ticket.person.primary_email.email}}">{{ticket.person.primary_email.email}}</a>

Performing AJAX requests

Use the $http service to perform AJAX requests.

Note

The Apps system is powered by a framework called AngularJS, and $http is a built-in service. You can refer to the official documentation for detailed API information: https://docs.angularjs.org/api/ng/service/$http

Here’s an example of using $http to perform an AJAX call to a web-service. After the result comes back, see how we assign the value to $scope which we use in the template:

// Javascript
$scope.is_loading = true;

$http.get('/web-service').success(function(data) {
    $scope.is_loading = false;
    $scope.customer = data.customer;
});
// HTML
<div ng-if="is_loading">Loading results, please wait...</div>
<div ng-if="!is_loading">
    Customer ID: {{customer.id}}
</div>

Note that due to a browser security feature called same-origin policy, you cannot use AJAX to load web services from external domains. For example, if your helpdesk is on support.example.com you cannot use $http to perform AJAX requests against other-domain.com because the domain is different and the browser will reject the request.

If your API supports JSONP, you can use that method instead via $http.jsonp. Otherwise, you can use the DeskPRO proxy service which allows you to proxy a AJAX requests through DeskPRO to make remote API calls:

var params = {
    url:           'http://other-domain.com/api/some-service',
    email_address: $ticket.person.primary_email.email,
    other_params:  'example',
    something:     'these other params will be passed as-is to your remote service'
};
$http.get('DP_URL/agent/misc/proxy', {params: params}).siccess(function(data) {
    // ...
});

Note that the special DP_URL prefix in the URL will be automatically replaced to the URL of your helpdesk.

Much more...

There is much much more you can do with your Javascript and HTML templates that we will go over in the next section.