|This page documents the implementation of the OOINet UI Release 2 (ion-ux source code repository)|
- jQuery 1.9.1
- jQuery DataTables 1.9.3
- Underscore 1.4.4
- Backbone.js 1.0
- backbone-forms 0.10.1
- Bootstrap 2.2.2
- Flask 0.10.1
- Jinja2 2.7.1 (Flask dependency)
- Requests 1.2.3
The UI is represented in a Filemaker database built by UX architects. This database maps OOI resources (Instrument, InstrumentModel, etc.) to screen elements and components: views, groups, blocks, attributes. The orange elements below illustrate the areas of the UI described by the Filemaker database.
In addition to mapping data, it also describes UI blocks (widgets) like tables, attribute groups (name, value), etc. These records contain a data-path that get injected into HTML tags so that the UI can map and bind data. An example:
This tells the UI to look for resource.name in JSON data returned from the backend from a separate ajax call.
Filemaker was designed and maintained by UX architects. It is exported as CSV files to http://userexperience.oceanobservatories.org/database-exports/
See OOINet UX Release Process for details
CSV files are imported as UI Resources into OOIN during the UI preload phase:
All the UI objects are delivered to ion-ux as a JSON object. This object is traversed to build HTML templates for each view. Many of the group, block and attribute widgets are reused across many OOIN resource types, so CSS class masking is applied. For instance, if you have a table widget that is used on Instrument, InstrumentModel and Platform pages, the template markup for this would look like:
The table above would only be implemented and used on the pages associated with the OOIN resource types listed in the class attribute. The code for traversing the JSON UI database representation and making templates is here:
The end result of this code is that all the database “views/groups/blocks/attributes” are inserted in ion_ux.html as script tags for later use by Backbone/Underscore (_.template).
NOTE: LayoutApi is the result of a rapid prototype effort and needs optimization.
The following Backbone.js components are used extensively:
- Router (with HTML5 pushState enabled)
Some things to note about IONUX.init():
- An AJAX call to /ui/navigation bootstraps the Dashboard with Observatories and Orgs for navigation and Google map rendering.
- IONUX.SESSION_MODEL tracks important user information.** It is a standard Backbone Model.** It is also responsible for polling for new user roles and privileges.
- setup_ajax_error is the global error handler for the entire application. It is overridden in other places by setting jQuery.ajax “global” to false.
IONUX.init() is called when ion_ux.html is downloaded to the client.
Client-side application routing is done in ux-router:
In many ways, the router is being used more like an application controller especially as requirements grew and more application state was introduced. The route mapped to page() is where most of the dynamic UI rendering occurs.
A resource_extension model is instantiated and fetch() is called to load the page data.
After the fetch returns successfully, a template is loaded into #dynamic-container. It can be one of any of the types defined in AVAILABLE_LAYOUTS.
page_render() is called. This iterates through the template that inserted and does three things:
- renders the appropriate widget (i.e. table, attribute group, etc.);
- reads the element’s data-path attribute and grabs the data for the widget.
This function checks for the following widget types (defined in Filemaker):
Each of these widget types have a Backbone.View that handles rendering a template and it's data. These views typically live in static/js/ux-views.js if they are small or in their own file (i.e. static/js/ux-views-datatable.js) if they are more complex.
The ion-ux dashboard consists of several Backbone views, models and collections -- all of which reside in static/js/ux-views-dashboard.js.
This toggles the dashboard between Map/Org and Resource/List views.
The primary navigation element in the Map/Org view.
The primary navigation element in the Resource/List view.
A Backbone view that instantiates and maps OOIN resources with Google Maps.
All the dashboard table views extend IONUX.Views.DataTable. There are three dashboard tables:
This view triggers filters on the IONUX.Dashboard.MapDataResources collection. It applies changes to IONUX.DataProductWhitelist, which is an array of DataProducts to be displayed. When any change is applied to the whitelist, IONUX.Dashboard.MapDataResources collection is filtered and rendered.
This view extends static/js/ux-views-actionmenu.js and gives the user a menu to select/de-select all DataProduct filter options (IONUX.Views.DataProductFilter)
This view triggers filters on IONUX.Dashboard.MapResources using IONUX.MapWhitelist.
This view triggers filters on IONUX.ListWhitelist in the Resource/List view.
There are two themes: light (static/css/salt.css) and dark (static/css/pepper.css). Each of these use the following sprite images: /static/img/salt_sprite.png and /static/img/pepper_sprite.png
Two Backbone views use metadata to build the appropriate template: IONUX.Views.DataTable and IONUX.Views.AttributeGroup. Here is an example of the metadata used by IONUX.Views.DataTable so that it knows what columns to display:
Each array contains the following information (in order): view type, screen label, data path, positioning, visibility and view level. For a better idea of how this metadata is used, take a look at the _get_table_metadata() function in ux-views-database.js: