Property widgets

Property widgets enable enterprise installations to modify the way instance properties (return values) are presented to end users. A custom widget is a piece of JavaScript and a CSS file that is responsible for producing HTML code that will replace a property’s basic string representation.

For example, you can write your own widget to represent a numeric field “progress” as a graphical progress bar, create some links, or show additional information.


Widgets are javascript functions assigned to a specific property with the help of a “widget router” function. The router makes decisions to apply a widget based on the property name, its value and nesting depth (if it’s a JSON object).

You can define several routers, but only one widget can be applied to a property If several routers apply different widgets to the same property, the last router to be defined takes precedence.

The router function is applied hierarchically. Assume you have a property called databases with the following value ['', '']. At the first step, the router will attempt to apply its function to the entire property value, then, if it is deemed unapplicable, it will attempt to apply it to individual array elements. In the similar manner, the function would be applied top-to-bottom in an hierarchical JSON object. Whenever the value tests positively, the router function returns the widget function itself.

The router function and the widget function accept three parameters.

The property object has the following members:

model - backbone-data model, referring to the intance or environment the property belongs to. Contains the name and id attributes.

The widget function will be attached to its containing DOM element. You can use this pointer to interact with its DOM subelements. Use method to persist state. Please, note that a widget is recreated (and the data is lost) when the underlying property changes its value. $(this).data('myVar', value)


The example below turns IP addresses into links, renders progress bars, and adds a stateful password widget, all pictured above.

// Simple RegExp for IP's
var ipRegExp = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;

// Widgets will applied by this function
app.widgets.registerWidgetRouter(function(property, location, model) {
  if (property.path[0] == 'password') {
    return PasswordWidget;
  else if (property.path[0] == 'progress') {
    return ProgressWidget;
  else if (ipRegExp.test(property.runtimeValue)) {
    return IPWidget;

// Draw simple progress bar
function ProgressWidget(property) {
  var $progress = $('<progress max="100"></progress>').prop('value', property.runtimeValue);

// Display IP as link with an icon
function IPWidget(property) {
  var ip   = property.runtimeValue;
  var link = $('<a/>').attr('href', 'http://' + ip).text(ip);

  $(this).append('<i class="fa fa-cloud"></i>&nbsp;').append(link);

// Hide the password by default with the checkbox to show it
function PasswordWidget(property) {
  var pass     = property.runtimeValue;
  var propName = property.path[0];
  var dotsNode = $('<span/>').text('•••••••••••••••••'.substr(0, pass.length));
  var passNode = $('<span/>').text(pass);
  var checkbox = $('<label class="inline"><input type="checkbox"> show password</label>');

  checkbox.on('click', 'input', function(e) {
    $(this).data('currentState', this.checked);

  // Restore last state
  var state = $(this).data('currentState');
  if (state) {
    checkbox.find('input').prop('checked', state);
  } else {



Create my-extensions.js and my-extensions.css files and host them on a publicly available web server. Then, you can add links to these files in menu “Edit organization”.

Note: backbone.js, underscore.js and jQuery are used by the web site so you don’t need to download and attach them in the widget code.