Visokio website     Downloads     Video tutorials     KnowledgeBase  
Content View: Native Browser JavaScript API (2.8+) - Visokio Forums
Content View: Native Browser JavaScript API (2.8+)
  •     steve August 24, 2012 1:04PM
    We've been busy working on building a Native Browser API for the Content View in 2.8.

    This allows advanced users with JavaScript development skills to effectively build a custom view in Javascript which runs in your system browser, embedded inside the Omniscope Content View, with the page source editable in the Content View as usual.

    This is very much work in progress, and subject to change following feedback before we release 2.8 in public beta. Please experiment and post below, but don't build any live reports that depend upon the new behaviour.

    But can't I already use Javascript in the Content View?


    The Content View already supports Javascript pre-processing. In your page source, you have special <# #> tags indicating the start and end of script fragments. Omniscope then, behind the scenes, executes the Javascript in a browser-less environment to produce the final page text.

    This is directly equivalent to the way a PHP/JSP/ASP/etc. web server might "execute" a server-side page to produce the HTML document that is sent to the client. We chose to use Javascript on the "server" side, but note that there is no HTML DOM or browser Window object, for example; this is pure "headless" Javascript.

    In this case, the "server" is the Omniscope Content View back-end, in-memory on your desktop, and the "client" is the page renderer, either Java within Omniscope, or a separate native browser process embedded in the Omniscope window.

    New source editing enhancements


    When editing in "source mode" in the Content View, we now have full syntax highlighting of your page source. This makes scripting and HTML coding much, much easier.

    Note that if you're using script pre-processing, advanced formulae, or the native browser, you will only be allowed to use source mode, rather than "design mode" for editing your page.

    New menu items in the view's Tools menu:


    • "Use native browser"

      This affects how the HTML page content is rendered, after it has been evaluated (e.g. applying any formula insertion or script pre-processing).

      This is deselected by default, matching 2.7 behaviour, meaning the page is displayed using Omniscope's built-in rich text display (via Java, based on HTML 3.2, without any support for in-page Javascript).

      When selected, the page is displayed by embedding the system web browser (typically IE on Windows), allowing "client-side" scripts to be executed in the browser's Javascript engine, with full access to the HTML DOM, etc. This allows you to build Javascript interactivity and do other native browser behaviours such as embed media.

    • "View in external browser"

      Click this to open the same page in an external browser. This allows you to debug your page in a full separate browser; we recommend Google Chrome for its developer tools out-of-the-box. The embedded browser, if IE, has very limited support for debugging.

      Note that Javascript native dialogs (alert/confirm/prompt) are disabled in the embedded browser, because it can often lead to a complete freeze of the application. You should use alternative Javascript frameworks instead.

    • "Refresh on change"

      By default, the page content is rebuild and the browser refreshed when cell edits or filtering occur. Untick this option to disable. You will need to code in a different means of triggering updates to any data you may have loaded via API / AJAX calls.

      Even if ticked, viewing in an external browser will never refresh automatically on change; you will need to manually reload the external browser.



    AJAX requests


    You can choose to use this native browser option to add some animations or general pizzazz to your Content Views, or more extensively by using the API to request and process data.

    We currently provide two APIs. At a low level, an HTTP service is provided should you wish to roll your own AJAX calls and perhaps use different or incompatible JS libraries to those used by the high-level API.

    The high-level API is enabled by inserting a pre-processing snippet into your page source in the HTML HEAD tag, and provides Javascript objects and methods to 'call' the enclosing Omniscope Content View.

    Low-level API

    The page itself is served up by "page.html" within an auto-generated unique URL, which changes each time the view is opened. Use "View in external browser" to see the URL. But you should not need to know this, since the other HTTP services are available in a relative URL to this page. For example, from within "page.html", you can use AJAX and hit the "meta.json" URL (without any further URL qualifiers).

    All requests return HTTP status code 200 if successful.

    • page.html

      Returns the page content as text/html after applying pre-processing and evaluating formulas.

      No request parameters.

    • eval.json

      Evaluates a JS expression on the back-end, with access to formula functions.

      Accepts a POST request with text/plain upload body (NOT regular key/value form data), containing a Javascript expression to evaluate against the Content View's dataset as per "script pre-processing". This can be used to query arbitrary formula functions such as subset_max("fieldname"), for example.

      Returns JSON { "result": value } where value is the result of the expression; can be a complex object or array.

    • meta.json

      Retrieves metadata about the view's data.

      No request parameters.

      Returns JSON { "fieldCount" : 13, "recordCount": 1052, "fieldNames": ["field1","field2",...], "fieldTypes": ["text","text","date","integer","decimal",...] }

    • cells.json

      Retrieves one or more cell values.

      Accepts a POST request with the following form key/value pairs:
      "fields": a JSON array of field names; if omitted, all fields are retrieved
      "firstRow": The first row to retrieve, 0-indexed, must be in-bounds; if omitted, zero is used
      "numberOfRows": The number of rows to retrieve; if omitted, all remaining rows are retrieved; automatically capped by the last row in the dataset

      Returns JSON { "result": [ [cell00, cell10, cell20], [cell01, cell11, cell21], [cell20, cell21, cell22] ] }
      (where the 2-dimensional array's dimensions reflect the filtered data results, doesn't contain a row for field names, and is indexed [column][row]).

    • edit.json

      Writes back one or more cell edits to the data table.

      Accepts a POST request with the same key-value pairs as "cells.json", plus:
      "data": a JSON two-dimensional array, in the same format as returned by "cells.json" under the "result" property.

      Returns the empty JSON {} to indicate success.

      This will only work in licensed editions where editing cell data is permissioned - i.e. not in the free Viewer. It will propagate a change to all views, and you will immediately see the result. You will need to untick "Refresh on change" if you want to avoid the same Content View (which originated the call) from reloading your page.


  • 5 Comments
  •     steve August 24, 2012 1:11PM
    High-level API

    To use the high-level API, you must include a special directive in your page's HTML HEAD tag, as follows:

    <html>
    <head>
    <# insertNativeBrowserApiScriptTag() #>
    ...
    </head>
    ...
    </html>

    This inserts several SCRIPT tags which import various Javascript files, bundled with Omniscope, which are required by the high-level API. These are subject to change, so don't link them directly, and instead use this directive.

    For information, these are currently:
    • jquery-1.8.0.min.js (required for api.js)
    • json2.min.js (required for api.js)
    • api.js (the high-level API itself)


    Methods available:

    • vo.eval(javascriptExpression, function(result))

      Evaluates a JS expression on the back-end, with access to formula functions.

      Accepts an arbitrary Javascript expression as a quoted String. Uses AJAX, and on success calls the function, passing the expression result. Automatically handles conversion to/from JSON.

      Example: vo.eval("1+2", function(result) {...}) will shortly call back the function with result 3.

      Example: vo.eval("subset_min('Price')", function(result) {...}) yields the minimum value in the Price field.

    • vo.call(methodName, args, function(result))

      Calls a JS method on the back-end, with access to formula functions. Uses AJAX, and on success calls the function, passing the expression result.

      Internally, uses the same low-level API call as eval().

      methodName: the String name of the method

      args: an array of JS arguments, which will be transferred to the server as JSON arguments in an apply() call.

      Example: vo.call("subset_min", ["Price"], function(result) {...}) yields the minimum value in the Price field.

    • vo.meta(function(result))

      Retrieves metadata about the view's data.

      Returns, via callback, an object with properties:
      fieldCount: number
      recordCount: number
      fieldNames: array of Strings
      fieldTypes: array of Strings, values text/date/integer/decimal.

      Example: vo.meta(function(result) {...}) yields { fieldCount: 3, recordCount: 73, fieldNames: ["Price",...], fieldTypes: ["decimal", ...] }

    • vo.cells(fields, firstRow, numberOfRows, function(data))

      Retrieves one or more cell values.

      fields: an array of field names, null/omitted for all
      firstRow: the first row number to retrieve, 0-indexed, must be in-bounds; if omitted/null, zero is used
      numberOfRows: the number of rows to retrieve; if omitted, all remaining rows are retrieved; automatically capped by the last row in the dataset

      Returns, via callback, a two-dimensional array. The dimensions reflect the filtered data results, it doesn't contain a row for field names, and is indexed [column][row].

      Example: vo.cells(["Price", "Sales"], 0, 2, function(result) {...}) yields a 2x2 array of price and sales data for the first two records.

    • vo.edit(fields, firstRow, numberOfRows, data, function())

      Writes back one or more cell edits to the data table.

      Accepts the same arguments as cells(), plus:
      data: a two-dimensional array, in the same format as returned by cells().

      The callback is made on success (no data is returned).

      This will only work in licensed editions where editing cell data is permissioned - i.e. not in the free Viewer. It will propagate a change to all views, and you will immediately see the result. You will need to untick "Refresh on change" if you want to avoid the same Content View (which originated the call) from reloading your page.

      Example: vo.edit(["Price", "Sales"], 1, 1, [ [1.23], [4.56] ], function() {...}) sends edits in the second row back to the server.


    As well as defining a global "vo" object (actually "window.vo") containing various methods, the high-level API also attempts to redefine the window.alert/prompt/confirm functions so they throw an exception, rather than silently do nothing, since they are disabled in the embedded Content View browser by Omniscope. You will see these in the Chrome JS console if viewed externally.

    Data is exchanged with the high-level API as JavaScript String, Number or Date. Some back-end formula results cannot be exchanged with either API such as the result of a SUBSET() function, a server-side-only reference to a subset of data.
  •     steve August 24, 2012 1:32PM

    Demo file


    See the attached file, which demonstrates a very primitive use of the Native Browser high-level API.

    On clicking the button, it loads a table of text fields containing data retrieved from Omniscope. Edit the text in one of the fields and press Enter to submit the cell edit back to Omniscope. You should see the data in Omniscope update immediately.

    Requires Omniscope 2.8 b273 or later.
  •     steve September 5, 2012 1:29PM

    Browser version


    Warning: Omniscope's web browser uses IE (whatever version is installed) on Windows, and Safari on Mac. If you're developing your own scripts, you are recommended to develop in Chrome for its development tools, but test compatibility in IE.

    We may consider supporting the use of a predefined version of Mozilla (Firefox) instead, but this would either require an optional additional download per client or would significantly install the Omniscope installer size.
  • admin May 10, 2013 11:55AM
    This feature is now publicly available in 2.8 beta:
    http://forums.visokio.com/discussion/2130/omniscope-2.8-beta
  •     steve June 10, 2014 12:15PM
    Updated attachment for "Demo file" comment above; this fixes outdated reference to a JS library from the custom JS in the Content view.

Welcome!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In Apply for Membership