In this section you will enable context integration with a clinical application (typically an image viewer). This integration is provided by the JavaScript library HarbingerJS (included in harbinger-rails-extensions, further documentation).

Prerequisites

Familiarity with jQuery features for selecting elements of a page and for attaching to event callbacks is required.

Setup

To use the HarbingerJS libraries, they need to be included in app/assets/javascripts/application.js:

//= require jquery
//= require jquery_ujs
//= require bootstrap-sprockets
//= require harbinger-js/core.js
//= require harbinger-js/integration.js

Edit app/stylesheets/application.scss to add a line of CSS:

.data { display: none; }

The data class will be used in markup to store information invisible to the user.

Page-specific JavaScript (like will be needed to handle the context integration button) should exist in a separate file. Make a directory to store page-specific JavaScript: app/assets/javascripts/pages. Create an empty JavaScript file by running touch app/assets/javascripts/pages/worklist.js.

Add that file to the view using the javascript_include_tag helper. Script tags scattered inside a view can be difficult to work with when using a browser debugging tool, so another rails helper, content_for should be used to put the javascript_include_tag in the head of the page. Edit app/views/worklist/index.html and add this line at the top:

<% content_for(:javascript_includes, javascript_include_tag("pages/worklist.js")) %>

The content will appear in app/views/layout/application.html.erb from the line:

<%= yield(:javascript_includes) %>

Finally, the Rails asset pipeline needs to be configured with the new JavaScript files. Edit config/initializers/assets.rb:

# Be sure to restart your server when you modify this file.

# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '1.0'

# Add additional assets to the asset load path
# Rails.application.config.assets.paths << Emoji.images_path

# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
Rails.application.config.assets.precompile += ["pages/*.js"]

This adds any files with the .js extension inside the pages directory to the asset pipeline. Rails now knows that they are valid assets and when an application is compiled for production, Rails will precompile these assets separately from those referenced in application.js.

Restart the rails server for this to take effect.

Usage

Update app/views/worklist/index.html to include the information needed for the button to work (add the data to the markup, then use it in a JavaScript click handler):

<td class="launch-group">
  <div class="data">
    <div class="integration-definition"><%= exam.imageViewer %></div>
    <div class="exam-object"><%= exam.integrationJson %></div>
  </div>
  <button class="btn btn-xs btn-primary <%= 'disabled' if exam.imageViewer.blank? %>">View Images</button>
</td>

Next, build the click handler. Edit app/assets/javascripts/pages/worklist.js to add:

$(document).ready(function() {
    $(".launch-group button").bind("click", function(e) {
    var data = $(this).siblings(".data");
    var integration = $.parseJSON(data.find(".integration-definition").html());
    var exam = $.parseJSON(data.find(".exam-object").html());
    $.harbingerjs.integration.view(integration,exam);
    });
});

How it works

This adds the two pieces needed to drive an integration to the markup. The first is the integration definition for the viewer (exam.imageViewer). The integration definition is configured when Bridge is deployed to a customer. Integrations are defined for each external_system in the data model. Depending on the exam being launched, different integrations can execute (based on the configuration). It is also possible that an exam won't have an integration associated with it, which is why 'disabled' if exam.imageViewer.blank? was implemented in the view. The disabled class is used by bootstrap to disable the button. The second piece is the parameters that need to be passed to the integration definition. These are accessed using exam.integrationJson.

Best Practice - The $.harbingerjs.integration.view function takes an optional third argument. It enables a prenamed function by which the integration will be launched or a function that will do the launching. This is helpful for debugging, but should not be used to launch an image viewer in a production application. The integration definition itself defines how to launch the integration for a given external system.