Flexible View Control for XPages – Categorized Views

HCL Digital Week made very clear the emphasis in the application development space is on “low-code”. That got me thinking about the Flexible View Control and how, at the end of the day, it really is a low-code tool to add View data to XPage applications. Just like with Domino Volt, many aspects of configuring a View with the Flexible View Control are as simple as drag, drop, and configure.

Creating a categorized View is no different. Let’s take a look at just how easy it is by creating a View of all the Ferraris listed in the used car database. Naturally, we start by creating the View Definition:

The View Definition

The View Definition being used for the demos shown in this post can be found here.

I want to categorize this View by the MODEL column. Just like we do for a Notes View, I make that the first column. Next, check off the “category” checkbox in the last column of the MODEL column row.

A couple of important notes in the above sceenshot:

  1. The column to be categorized MUST be sorted.
  2. In the image above the MODEL column is being hidden. That might seem counter-intuitive since this is the column we are categorizing, but it will make sense in a moment.

The View XPage

Link to the demo used in this post.

BEFORE adding categorization

The image above shows what the Ferraris View looks like before adding the categorization.

The image below shows what the View looks like after adding the categorization and hiding the MODEL column.

AFTER adding categorization and hiding the MODEL column

How does it work?

To create the categorization the Flexible View Control traverses the DataTable during the drawCallback phase and when a row contains a different MODEL value, a new tr node is inserted before that row to represent the category. The reason why we can hide the MODEL column is the traversal is done on the DataTable dataset, not the actual HTML of the table. After inserting the tr node a click event is applied to provide expand/collapse functionality for the category.

Let’s break down the tr node that gets added for each category:

category tr element insert for each category
  • The data-category attribute is the unique identifier for this category. This value also gets applied to all of the child rows for this category.
  • “group” classes are added to aid in referencing the category rows.
  • The data-hide attribute is used to handle expansion/collapse of the category.
  • The table cell created inside the tr node is automatically given a colspan equal to the number of cells in a non-category row.

Doing the Twist(ie)

You probably noticed in the image above that there is a “twistie” node in the tr HTML. By default this is simply a “-” to denote expansion and a “+” to denote a collapsed category. This is handled with some simple CSS:

.twistie {margin-right:5px}
.twistie-expand::before{
	content:'-';
	font-size:1.25em;
}
.twistie-collapse::before {
	content:'+';
	font-size:1.25em;
}

Adding a little more “flair” to the twistie is easy by simply overriding the CSS. For example, I’m a big fan of Font Awesome and use that for my twistie icons:

Using Font Awesome icons for twisities
.twistie-expand::before{
	font-family: FontAwesome;
	content: "\f056";
	font-size: inherit;
}
.twistie-collapse::before {
	font-family: FontAwesome;
	content: "\f055";
	font-size: inherit;
}

Expand/Collapse All

Just as in a Notes View that contains categorization, the Flexible View Control provides the ability to expand or collapse the entire View. In our demo there are two buttons at the top that are wired with this functionality:

When the control is rendered functions are created dynamically that call functions contained in the csjsCCRestView.js script library:

collapseAll : function() {
	ccRestView.groups.collapseAll(this.thisView);
},
expandAll : function() {
	ccRestView.groups.expandAll(this.thisView);
}

The code behind the buttons can then refer directly to a specific View, which we’ve named ViewBasic in the thisView property of the control for this demo:

ViewBasic.collapseAll();
ViewBasic.expandAll();

Filtering

One of the great features of DataTables is being able to enter a query in the search box and having the contents of the DataTable reduce to the records that match that query. This functionality still works when the View is categorized!

The next post will expand on the categorization functionality by introducing subcategories and a feature called “category renderers”.


Flexible View Control for XPages Updates

On the heels of the OpenNTF Webinar where I presented the Flexible View Control for XPages, I was able to make some long-overdue updates that improve the functionality and performance of the control.

Get the code from GitHub:

Release v2020-11-17

Updates in this release:

  • Improved the setup and configuration process to make it more intuitive, including adding an option to create the default (view-definitions) View Definition automatically.
  • Fixed and improved category/sub-category creation and expansion/collapse.
  • Cleaned up the View Definition UI.
  • Added additional client sorting fields in the View Definition. There is now a total of 4 levels of client-side sorting available.
  • Fixed totals options including totaling up for each category/subcategory and showing totals in the footer.
  • Added ability to total # of rows or total the values for a column in each row.
  • Added a category renderer option to the View Definition.
  • Added a footer callback option.
  • Reduced expression language evaluations on the ccRestView custom control.
  • Added a stats component to the View object to track the performance of different aspects of the control.

The demo site has been updated with the most recent version of the control. Blog posts expanding on/demonstrating the items listed above to follow soon!