Skip to main content

Range Selection

BBjGridExWidget - Enhanced Version BBjGridExWidget - SAM Required

Range selection allows Excel-like range selection of cells. Range selections are useful for visually highlighting data, copying data to the Clipboard, or for doing aggregations using the Status Bar.

Selecting Ranges

Range Selection is enabled using the following grid option EnableRangeSelection=true. When enabled, ranges can be selected in the following ways:

  • Mouse Drag: Click the mouse down on a cell and drag and release the mouse over another cell. A range will be created between the two cells and clear any existing ranges.
  • Ctrl & Mouse Drag: Holding Ctrl key while creating a range using mouse drag outside an existing range will create a new range selection and keep any existing ranges.
  • Shift & Click: Clicking on one cell to focus that cell, then holding down Shift while clicking another cell, will create a range between both cells.
  • Shift & Arrow Keys: Focusing a cell and then holding down Shift and using the arrow keys will create a range starting from the focused cell.
  • Ctrl & Shift & Arrow Keys: Focusing a cell and then holding down Ctrl + Shift and using the arrow keys will create a range starting from the focused cell to the last cell in the direction of the Arrow pressed.

Range Deselection

It is possible to deselect part of existing ranges in the following ways:

  • Ctrl & Mouse Drag: Holding Ctrl and dragging a range starting within an existing range will cause any cells covered by the new range to be deselected.
  • Ctrl & Click: Holding Ctrl and clicking a cell will deselect just that cell.

Note that deselecting part of a range can split the range into multiple ranges, since individual ranges have the limitation of being rectangular.

The example below demonstrates simple range selection. Ranges can be selected in all the ways described above.

use ::BBjGridExWidget/BBjGridExWidget.bbj::BBjGridExWidgetuse ::BBjGridExWidget/GxClientModels.bbj::GxClientRowModeluse com.basiscomponents.db.ResultSetuse com.basiscomponents.bc.SqlQueryBCdeclare auto BBjTopLevelWindow wnd!wnd! = BBjAPI().openSysGui("X0").addWindow(10,10,800,600,"Checkbox Selection")wnd!.setCallback(BBjAPI.ON_CLOSE,"byebye")gosub mainprocess_eventsmain:  declare SqlQueryBC sbc!  declare ResultSet rs!  declare BBjGridExWidget grid!  sbc! = new SqlQueryBC(BBjAPI().getJDBCConnection("CDStore"))  rs! = sbc!.retrieve("SELECT * FROM CDINVENTORY")  grid! = new BBjGridExWidget(wnd!,100,0,0,800,600)  grid!.getOptions().setEnableRangeSelection(1)  grid!.getOptions().setSuppressRowClickSelection(1)  grid!.setData(rs!)returnbyebye:bye

BBjGridExWidget - Range Selection Basic

Suppress Multi Range Selection

By default multiple ranges can be selected. To restrict range selection to a single range, even if the Ctrl key is held down, enable the following grid options: SuppressMultiRangeSelection=true.

grid!.getOptions().setSuppressMultiRangeSelection(1)

Range Selection Changed Event

The BBjGridExWidget::ON_GRID_RANGE_SELECTION_CHANGED is fired when a the grid's range selection is changed.

grid!.setCallback(grid!.ON_GRID_RANGE_SELECTION_CHANGED(), "handleChanged")

Range Selection API

The following methods are available on the BBjGridExWidget class for managing range selection.

MethodDescription
getRangeSelections()This will return back a BBjVector of GxClientRangeSelectionModel objects
addRangeSelection(GxClientAddRangeSelectionModel model!)Add new range selection
addRangeSelection(BBjString columns! , BBjNumber start! , BBjNumber end!)Add new range selection
clearRangeSelection()Clears the selected range.

Example: Advanced Range Selection

The example below demonstrates a more complex range selection scenario. The example listens for the ON_GRID_RANGE_SELECTION_CHANGED and re-create the BBjGridExWidget statusbar in BBj.

use ::BBjGridExWidget/BBjGridExWidget.bbj::BBjGridExWidgetuse ::BBjGridExWidget/GxStatusBar.bbj::GxStatusBarAggregationComponentuse ::BBjGridExWidget/GxClientModels.bbj::GxClientRangeSelectionModeluse ::BBjGridExWidget/GxClientModels.bbj::GxClientColumnModeluse ::BBjGridExWidget/GxClientModels.bbj::GxClientAddRangeSelectionModeluse com.basiscomponents.db.ResultSetuse com.basiscomponents.bc.SqlQueryBCuse java.sql.Typesuse java.util.ArrayListuse java.util.Collectionsuse java.util.Randomdeclare auto BBjTopLevelWindow wnd!wnd! = BBjAPI().openSysGui("X0").addWindow(10,10,800,600,"Range Selection Demo")wnd!.setCallback(BBjAPI.ON_CLOSE,"byebye")wnd!.setCallback(BBjAPI.ON_RESIZE,"resize")aggTemplate! = "Average : %s - Count : %s - Min : %s - Max : %s - Sum : %s"statusbar! = wnd!.addStatusBar(98,$8000$)vector! = bbjapi().makeVector()vector!.add(150)vector!.add(65535)statusbar!.setSegments(vector!)statusbar!.setTextAt(0, "Aggregation done with BBj")statusbar!.setAlignmentAt(0,statusbar!.LEFT)statusbar!.setTextAt(1, String.format(aggTemplate!,0,0,0,0,0))statusbar!.setAlignmentAt(1,statusbar!.LEFT)onRandomRange! = wnd!.addButton(99,10,10,150,25,"Add Random Range")onRandomRange!.setCallback(BBjAPI.ON_BUTTON_PUSH,"onRandomRange")clearRange! = wnd!.addButton(100,180,10,150,25,"Clear Ranges")clearRange!.setCallback(BBjAPI.ON_BUTTON_PUSH,"onClearRange")gosub mainprocess_eventsrem /**rem  * Retrieve the data from the database and configure the gridrem  */main:  declare BBjGridExWidget grid!  declare SqlQueryBC sbc!  declare ResultSet rs!  sbc! = new SqlQueryBC(BBjAPI().getJDBCConnection("CDStore"))  rs! = sbc!.retrieve("SELECT TITLE , COST , RETAIL , ONHAND FROM CDINVENTORY")  grid! = new BBjGridExWidget(wnd!,101, 0 , 50 , 800 , 530)  REM   Set to true to enable Range Selection  grid!.getOptions().setEnableRangeSelection(1)  REM   Allow users to move between cells using arrow keys instead of rows  grid!.getOptions().setNavigationBehavior(grid!.GRID_NAVIGATION_BEHAVIOUR_NEXT_CELL())  REM   Disable row selection on row click  grid!.getOptions().setSuppressRowClickSelection(1)  REM  Attach the aggregation component to the grid's built-in statusbar.  REM  The component provides aggregations on the selected range.  grid!.getStatusbar().addComponent(new GxStatusBarAggregationComponent("right"))  REM  Here we add a range selection to the grid by defining the columns which are included  REM  in the range and the start and end row's index/id  grid!.addRangeSelection("COST,RETAIL" , 2, 6)  REM listen to the grid range selection event so we can build our own statusbar in BBj  grid!.setCallback(grid!.ON_GRID_RANGE_SELECTION_CHANGED(),"onRangeSelectionChange")  grid!.setFitToGrid()  grid!.getSidebar().setHiddenByDefault(1)  grid!.setData(rs!)  REM  align columns of type number to the right to get better presentation  grid!.getColumn("COST").setAlignment(BBjGridExWidget.GRID_ALIGN_RIGHT() , 1)  grid!.getColumn("RETAIL").setAlignment(BBjGridExWidget.GRID_ALIGN_RIGHT() , 1)  grid!.getColumn("ONHAND").setAlignment(BBjGridExWidget.GRID_ALIGN_RIGHT() , 1)returnonRangeSelectionChange:  declare auto GxClientRangeSelectionModel currentRange!  declare auto GxClientColumnModel column!  REM vector of ranges  ranges! = grid!.getRangeSelections()  IF (ranges!.size() = 0) THEN      statusbar!.setTextAt(1, String.format(aggTemplate!,0,0,0,0,0))      return  FI  rangesLength! = ranges!.size() - 1  sum!          = 0  count!        = 0  min!          = 0  max!          = 0  average!      = 0  values!       = new ArrayList()  rem we start by looping over all ranges  FOR rangeIndex! = 0 TO rangesLength!      currentRange!   = ranges!.get(rangeIndex!)      rows!           = currentRange!.getRows()      rowsLength!     = rows!.size() - 1      columns!        = currentRange!.getColumns()      columnsLength!  = columns!.size() - 1      count!          = count! + (columns!.size() * rows!.size())      FOR rowIndex! = 0 TO rowsLength!          FOR columnsIndex! = 0 TO columnsLength!              column! = columns!.get(columnsIndex!)              type!   = column!.getType()              SWITCH (type!)                  CASE Types.BIGINT                  CASE Types.BIT                  CASE Types.DECIMAL                  CASE Types.DOUBLE                  CASE Types.FLOAT                  CASE Types.INTEGER                  CASE Types.NUMERIC                  CASE Types.NUMERIC                  CASE Types.TINYINT                      row!   = rows!.get(rowIndex!).asDataRow()                      value! = num(row!.getField(column!.getName()).getValue())                      sum!   = sum! + value!                      values!.add(value!)                      BREAK                  CASE DEFAULT                      BREAK              SWEND          NEXT columnsIndex!      NEXT rowIndex!  NEXT rangeIndex!  IF (values!.size() > 0) THEN      min!      = Collections.min(values!)      max!      = Collections.max(values!)      average!  = sum! / values!.size()  FI  statusbar!.setTextAt(1, String.format(aggTemplate!, round(average!), count!, round(min!), round(max!), round(sum!)))returnrem /**rem  * Add a random add range modelrem  */onRandomRange:    declare GxClientAddRangeSelectionModel addModel!    REM  list of columns which can be included in the range    columns! = new ArrayList()    columns!.add("COST")    columns!.add("RETAIL")    columns!.add("ONHAND")    REM number of columns include with the random generated range    numberOfColumns! = rnd(3)    rand! = new Random()    rangeColumns! = new ArrayList()    FOR index = 0 TO numberOfColumns!     randomIndex! = rand!.nextInt(columns!.size())     rangeColumns!.add(columns!.get(randomIndex!))     columns!.remove(randomIndex!)    NEXT index    addModel! =  new GxClientAddRangeSelectionModel()    addModel!.setColumns(rangeColumns!)    addModel!.setStart(str(rnd(10)))    addModel!.setEnd(str(rnd(10)))    grid!.clearRangeSelection()    grid!.addRangeSelection(addModel!)returnrem /**rem  * We clear all range selectionsrem  */onClearRange:    grid!.clearRangeSelection()returnresize:  ev! = BBjAPI().getLastEvent()  w=ev!.getWidth()  h=ev!.getHeight()  grid!.setSize(w,h - 50)returnbyebye:bye

BBjGridExWidget - Range Selection API