Auto-width Bootstrap Column XPages Controls

I’ve been stuck working with OneUI Version 3 for the past couple of years, due to a regretful decision made at the beginning of my major project. OneUI was better than nothing but very frustrating at times.
Finally, I have moved on to my next project and I am now using bootstrap (version 3)

A common task when laying out a page using bootstrap is to divide sections up into rows and columns, and use the appropriate css styles to do so. I’m going to assume you are familiar with bootstrap’s grid system, and if not I recommend you hearing it from the horse’s mouth instead of me trying to explain it again.

I like creating XspLibrary controls, so I decided I would go ahead and create row and column controls. It could be seen as a little overkill and you can easily live without it, but I see the Bootfaces project did it, so I took inspiration from their container, row and column controls.

I then also added the ability for the columns to have their widths automatically distributed. Auto-widths is a feature that is coming with bootstrap 4,  but for now we need to do it ourselves!

Example XPages Markup

The following examples end up looking like this: (Note: the blue border is just added for demo purposes to show the outline of the columns)

Here is a simple example of 2-column layout with equal width columns

Notice above how I haven’t specified any column widths? The columns will all become equal width, so in the example above, they will both be 6 columns wide (12 divided by 2 columns).

If there have 3 columns, then they would each automatically be 4 columns wide (12 divided by 3 columns).

Specifying a column width

If you want a column to be a specifc width, you use the span property to specify the width for that column, the remaining columns will receive their fair share of whatever is left over.

Specifying alignment

I’ve also added an align property so I can quickly align the contents.

Full Row column

If you want to use the entire row, then you can just leave the column definition out entirely and the contents will automatically be wrapped in a col-md-12 column

Using style and styleClass

You can still use style and styleClass properties as you normally would.

Container Control

If you are using one of the extension library bootstrap applicationLayouts, then you won’t need to use the container control because it is already covered by that. But, If you are rolling your own you can use the container layout which has a fluid property to control whether is is a bootstrap fluid layout or not.

Overview of creating the controls

Here is what we are going to do:

  1. Create the Container UIComponent
  2. Create the Column UIComponent
  3. Create the Row UIComponent
  4. Provide Control Definitions via an xsp-config file so that designer knows how to use them
  5. Program in the auto-width algorithm

Notice we are not going to create a renderer. We will be extending the panel control, and the existing panel renderer will be used automatically.

For each component we are just going to extend the existing <xp:panel> control to re-use all the existing functionality, and just add a few extra properties.

Creating the Container Component

The container component is simply an extension of the panel control (UIPanelEx) with an additional property ‘fluid’. We add the getters and setters for the fluid property, and make sure it is included in the restore and save state operations.

We also override the getStyleClass method so that it will always concatenate ‘container’ or ‘container-fluid’ depending on the fluid property.

Creating the Column Component

The column component is a little more complex. We are also going to extend the UIPanelEx control but we will also add some control properties

  • span – This will be an integer that can be set to specify the column span of the bootstrap grid
  • align – This will be a String which can be ‘left’ (Default), ‘center’ or ‘right’. This will then add the necessary bootstrap css class to perform aligning of the contents

I am also going to add a property guessSpan which is not exposed to domino designer and will only be used to store our ‘guesstimate’ column span when calculating the auto widths.

Then, I create a private method ‘getEffectiveSpan’ which will check if a column span has been explicitly set with the span property and if so it will use that. If a span was not set, it will use the ‘guessSpan’ that was guessed via the algorithm

Then we override the ‘getStyleClass’ method, so that when the renderer comes along and asks for the styleClasses, we can inject some styleClasses of our own.

We are using the very handy method from Extension Library’s ExtLibUtil, which allows us to easily concatenate styles. I have copied the method into my own Util class so that there will be no dependency on the Extension Library.

First we ask for any styles that have been explicitly set. Then we concatenate our column style from the bootstrap grid system e.g. “col-md-8”, and then we concatenate an alignment style if one was set on the column.

Creating the Row Component

The row component is also an extension of the panel control. But we are going to add some extra behaviour to it. Just before the Row’s children (the columns) are Rendered we are going to calculate the necessary spans for any columns that did not have a span. If we can’t find any columns as children, then we will assume that we are supposed to wrap all the contents into a single column and therefore we will render a start and end tag for a <div class=”col-md-12″>

Programming the auto-width algorithm

The auto-width algorithm does the following

  1. Finds the total span of columns that have been explicitly allocated using the span property
  2. Figures out the remaining span available (e.g. 12 – allocated)
  3. Figures out the average span to allocate to remaining columns without a span
  4. Allocates the ‘guessed’ span to the remaining columns

Provide Component Definition via xsp-config file

The xsp-config file tells Domino Designer everything it needs to know to include it on an XPage so we need to specify the properties that can be set.

The file starts with namespace definition to say ‘all component definitions in this file are under this namespace’ and then it specifies the 2 components.

We provide the description, tagname, display name, corresponding java class (so it knows how to instantiate it) a component type (usually just the same as the class).

Then we specify the properties that can be set. You can see for the row there is no extra properties, but for the column we have added the span and align properties and have provided combo options Left, Center and Right for the align property. For the container component, we have specified the fluid property.

Installing

If you would like to use these controls, you have 2 choices!

  1. Install the latest version of my GregorbyteXspLibrary to your Designer Client and Domino Server using the same method as Extension Library Installation
  2. Scavenge the necessary files from my Github repository and include it your own NSF

To Scavenge the necessary files from my Github Repo:

  • You will need to place these java files in your java design elements:
    • /com.gregorbyte.xsp.controls/src/com/gregorbyte/xsp/component/bootstrap/UIColumn.java
    • /com.gregorbyte.xsp.controls/src/com/gregorbyte/xsp/component/bootstrap/UIRow.java
    • /com.gregorbyte.xsp.controls/src/com/gregorbyte/xsp/component/bootstrap/UIContainer.java
    • /com.gregorbyte.xsp.core/src/com/gregorbyte/xsp/util/GregorbyteUtil.java
  • You will need to place this xsp-config file in the WEB-INF directory
    • /com.gregorbyte.xsp.controls/src/com/gregorbyte/xsp/config/gregorbyte-bootstrap.xsp-config

Conclusion

You can easily get the job done without these controls, but so far I have really enjoyed having them in my palette.

I’ve only just started using these controls, so I expect to improve on them. Maybe by adding the ‘small’, ‘medium’, ‘large’, ‘extraLarge’ properties to the columns (but for now I can use styleClass=”col-sm-4″ etc.)

I’m also keen to take a look at other parts of the bootfaces project and see if any of the ideas might be effective in Xpages.

If you end up using these please let me know! I’d love to hear any suggestions and as always if any problems then please leave a comment or post an issue on my GregorbyteXspLibrary project.

 

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *