Leveraging Bootstrap and Angular

Saturday, April 13, 2013

The driving force behind my current Javascript experiment was a need to modernize the UI for the Pivot Table. Clearly the old good JPivot-like UI doesn't match modern users expectations: context menus, drag & drop items, etc. So, once my Javascript cellset fulfilled basic functionality (drill up/down and add/remove hierarchies) I've started my work to rejuvenate the UI into a more stylish one.

Bootstrap looked like the obvious choice for styling, and the AngularJS team has a project providing Angular directives for Bootstrap components. So, I made no further research (as I've said in a previous post, I'm pretty new to this Javascript thing, and have no strong opinions on it).

include expand/collapse icons (courtesy of Glyphicons through
Bootstrap)

and voilá, a modern looking CellSet with row hover highlight for free.

Context Menu

Wouldn't be nice if you could just right-click on a hierarchy element to remove it from the hierachy, remove the whole hierarchy, or add a new one to that axis? That's the first step to get rid of the hierarchy panel in the old JSF version, and there are a couple of things to do to make that happen.

Styling

Bootstrap's toolbox saves our day again: just use its dropdowns to get something like this:

Dynamic Behaviour

I'll start with the context for the menu. I modified the CellSet jQuery component to add a function olapGetMetadataAt(element) to the DOM element it's binded. This function provides, for each DOM element within the table, metadata information for the represented olap
object. The returned object will have the following properties:

axisOrdinal {number}

for hierarchies and hierarchy members, the ordinal for the axis containing it (0 for columns, 1 for rows)

hierarchy {Object}

hierarchy metadata for hierarchies and hierarchy members

member {Object}

member metadata for hierarchy members

isLeaf {Boolean}

indicates if that member is a leaf in its hierarchy

With this function in place, we can add a ng-click directive to the HTML element containing the cell set, and use the event information to get the metadata for the clicked element. So we modify the div containing the cellset like this:

<div ng-click="showContextMenu($event)" olap-cellset="query"/>

And then the implementation for the click handler in the Angular controller sets a scope property (currentMember) with the clicked on metadata: