Row Spanning
By default, each cell will take up the height of one row. You can change this behaviour to allow cells to span multiple rows. This feature is similar to cell merging in Excel or row spanning in HTML tables.
Configuring Row Spanning
To allow row spanning, the grid must have grid option SuppressRowTransform=1. Row spanning is then configured at the
column level. To have a cell span more than one row, you need to set the RowSpanExpression , the expression must return how many rows to span.
The option SuppressRowTransform=1 is used to stop the grid positioning rows using CSS transform and instead the grid will
use CSS top. The reason row span will not work with CSS transform is that CSS transform creates a stacking context which
constrains CSS z-index from placing cells on top of other cells in another row.
Having cells extend into other rows is necessary for row span which means it will not work when using CSS transform. The downside to not using transform is performance; row animation (after sort or filter) will be slower.
RowSpanExpression
An RowSpanExpression is arbitrary JavaScript code/expression that applies application-defined rules to check how many rows to span. The expression must return a number value to indicate the number of rows to span.
When working with expressions keep the following points in mind:
- If the expression has the word
returnin it, then we will assume it is a multi-line expression and will not wrap it. - If the expression does not have the word
returnin it, then we will insert thereturnstatement and the;for you. - If the expression has many lines, then you will need to provide the
;at the end of each line and also provide thereturnstatement.
Expressions have access to several predefined variables:
| Variable | Description |
|---|---|
| x | Mapped from cell value |
| value | Same as x |
| data | Mapped from the DataRow |
| column | Current column |
| columnGroup | Current column group |
| getValue | The value after it is processed by the ValueGetterExpression |
| ctx | The grid client context |
For instance
column!.setRowSpanExpression("data.SHOW ? 4 : 1")
Row Spanning Example
Row spanning will typically be used for creating reports with BBjGridExWidet. Below is something that would be more typical of the row spanning feature.
The following can be noted from the example:
- We disable soring , sidebar and menus to prevent the user from ruining the spanning.
- Column
Showrow spans by 4 rows when it has content. - Column
Showuses CSS class rules to specify background and border. - Column
Showhas a custom cell renderer(GxRendererCustomHTML)to make use of the extra space.
GxRendererCustomHTML accepts a template.
This is a lodash template. It starts with <% and ends with %>.
To force the template to execute and print directly what is inside it, we add the = sign
to the start tag <%=. Inside the template you can use only Javascript and embedded HTML and CSS.
DO NOT confuse lodash templates syntax with JSP. They are different things.
- row-span.bbj
- data/row-span.json
use ::BBjGridExWidget/BBjGridExWidget.bbj::BBjGridExWidgetuse ::BBjGridExWidget/Demo/assets/Utilities.bbj::GxDemoUtilitiesuse ::BBjGridExWidget/GxRenderers.bbj::GxRendererCustomHTMLuse com.basiscomponents.db.ResultSetuse com.basiscomponents.bc.SqlQueryBCuse com.google.gson.JsonObjectdeclare auto BBjTopLevelWindow wnd!wnd! = BBjAPI().openSysGui("X0").addWindow(10,10,800,600,"Row Spanning Demo")wnd!.setCallback(BBjAPI.ON_CLOSE,"byebye")wnd!.setCallback(BBjAPI.ON_RESIZE,"resize")gosub mainprocess_eventsmain: declare ResultSet rs! declare BBjGridExWidget grid! rs! = ResultSet.fromJson(GxDemoUtilities.readAssetsAsString("data/row-span.json")) grid! = new BBjGridExWidget(wnd!,100,0,0,800,600) grid!.getOptions().setSuppressRowTransform(1) grid!.getSidebar().setHiddenByDefault(1) defaultColDef! = grid!.getOptions().getDefaultColumnDefinition() defaultColDef!.setSortable(0) defaultColDef!.setSuppressMenu(1) grid!.setData(rs!) grid!.setFitToGrid() showColumn! = grid!.getColumn("SHOW") showColumn!.setRowSpanExpression("data.SHOW ? 4 : 1") renderingTemplate! = ""+: "<% if(params.value) { %>"+ : "<div style='display: flex; flex-direction: column;align-items: baseline;'>" +: "<div class='show-name' style='font-weight: bold'>" +: "<%= params.value.NAME %>"+: "</div>" +: "<div class='show-presenter' style='font-weight: italic'>" +: "<%= params.value.PRESENTER %>"+: "</div>" +: "</div>"+: "<% } %>" showColumn!.setCellRenderer(new GxRendererCustomHTML(renderingTemplate!)) cellStyleRules! = showColumn!.getCellClassRules() cellStyleRules!.addProperty("show-cell","value !== undefined") showCellStyle! = new JsonObject() showCellStyle!.addProperty("background","white") showCellStyle!.addProperty("border","1px solid lightgrey !important") showCellStyle!.addProperty("border-top","none !important") grid!.addStyle(".show-cell", showCellStyle!)returnresize: ev! = BBjAPI().getLastEvent() w=ev!.getWidth() h=ev!.getHeight() grid!.setSize(w,h) grid!.setFitToGrid()returnbyebye:bye[
{
"LOCALTIME": "5:00AM",
"SHOW": {
"NAME": "WAKE UP DUBLIN",
"PRESENTER": "ANDREW CONNELL"
},
"A": 0.231,
"B": 0.523
},
{
"LOCALTIME": "5:15AM",
"A": 0.423,
"B": 0.452
},
{
"LOCALTIME": "5:30AM",
"A": 0.537,
"B": 0.246
},
{
"LOCALTIME": "5:45AM",
"A": 0.893,
"B": 0.083
},
{
"LOCALTIME": "6:00AM",
"SHOW": {
"NAME": "PURE BACK IN THE DAY",
"PRESENTER": "KEVIN FLANAGAN"
},
"A": 0.231,
"B": 0.523
},
{
"LOCALTIME": "6:15AM",
"A": 0.423,
"B": 0.452
},
{
"LOCALTIME": "6:30AM",
"A": 0.537,
"B": 0.246
},
{
"LOCALTIME": "6:45AM",
"A": 0.893,
"B": 0.083
},
{
"LOCALTIME": "7:00AM",
"SHOW": {
"NAME": "THE QUEENS BREAKFAST",
"PRESENTER": "TONY SMITH"
},
"A": 0.231,
"B": 0.523
},
{
"LOCALTIME": "7:15AM",
"A": 0.423,
"B": 0.452
},
{
"LOCALTIME": "7:30AM",
"A": 0.537,
"B": 0.246
},
{
"LOCALTIME": "7:45AM",
"A": 0.893,
"B": 0.083
},
{
"LOCALTIME": "8:00AM",
"SHOW": {
"NAME": "COSMETIC SURGERY",
"PRESENTER": "NIALL CROSBY"
},
"A": 0.231,
"B": 0.523
},
{
"LOCALTIME": "8:15AM",
"A": 0.423,
"B": 0.452
},
{
"LOCALTIME": "8:30AM",
"A": 0.537,
"B": 0.246
},
{
"LOCALTIME": "8:45AM",
"A": 0.893,
"B": 0.083
},
{
"LOCALTIME": "8:00AM",
"SHOW": {
"NAME": "BRICKFIELD PARK SESSIONS",
"PRESENTER": "BRICKER MCGEE"
},
"A": 0.231,
"B": 0.523
},
{
"LOCALTIME": "8:15AM",
"A": 0.423,
"B": 0.452
},
{
"LOCALTIME": "8:30AM",
"A": 0.537,
"B": 0.246
},
{
"LOCALTIME": "8:45AM",
"A": 0.893,
"B": 0.083
}
]
