Pro version only
This functionality requires PRO version of the DHTMLX Grid (or DHTMLX Suite) package.
You can manage block selection within a grid via the API of the BlockSelection
module. It allows selecting ranges of cells using the mouse pointer, touch input, or keyboard navigation, visualizing the selection, and controlling behavior through various modes and handlers. It also supports an event system to track user actions, including keyboard and mouse combinations.
To initialize the BlockSelection
module, use the blockSelection
property in the configuration of the dhx.Grid component. Once the Grid is created, the module is accessible through the grid.block
property.
const grid = new dhx.Grid("grid_container", {
columns: [
{ id: "a", header: [{ text: "A" }] },
{ id: "b", header: [{ text: "B" }] },
],
data: [
{ id: "1", a: "A1", b: "B1" },
{ id: "2", a: "A2", b: "B2" },
],
blockSelection: true
});
The blockSelection
property can also be set as an object to enable the module and provide additional configuration options. Learn about configuration possibilities of the BlockSelection
module in the Configuration guide.
Related sample: Grid. BlockSelection in the "range" mode. Selection with restricted columns
Enabling/disabling BlockSelection moduleâYou can activate the block selection module via the enable()
method of the block
object. The following example shows how the module is enabled after deactivation on initialization:
const grid = new dhx.Grid("grid_container", {
columns: [
{ id: "a", header: [{ text: "A" }] },
{ id: "b", header: [{ text: "B" }] },
],
data: [
{ id: "1", a: "A1", b: "B1" },
{ id: "2", a: "A2", b: "B2" },
],
blockSelection: { disabled: true }
});
grid.block.enable();
console.log(grid.block.isDisabled());
To disable the block selection in Grid, use the disable()
method of the block
object. The example below shows disabling of the BlockSelection
module:
const grid = new dhx.Grid("grid_container", {
columns: [
{ id: "a", header: [{ text: "A" }] },
{ id: "b", header: [{ text: "B" }] },
],
data: [
{ id: "1", a: "A1", b: "B1" },
{ id: "2", a: "A2", b: "B2" },
],
blockSelection: true
});
grid.block.disable();
console.log(grid.block.isDisabled());
Checking BlockSelection module stateâ
You can check whether the BlockSelection
module is disabled, using the isDisabled()
method of the block
object. It returns true
, if the module is disabled and false
, if it is enabled. The following example shows checking of the module's activity status:
const grid = new dhx.Grid("grid_container", {
columns: [
{ id: "a", header: [{ text: "A" }] },
{ id: "b", header: [{ text: "B" }] },
],
data: [
{ id: "1", a: "A1", b: "B1" },
{ id: "2", a: "A2", b: "B2" },
],
blockSelection: true
});
console.log(grid.block.isDisabled());
grid.block.disable();
console.log(grid.block.isDisabled());
Using events of the BlockSelection objectâ
To make the process of working with block selection more flexible, you can apply the related events of the block
object.
This section describes the main UI features of the BlockSelection
module: the way of selecting a range of cells, the available keyboard navigation combinations, as well as the appearance and behavior of the selection handle.
The main points of cell selection while using the BlockSelection
module are given below:
Shift + click
combination allows extending the range from the current initial cell to the clicked cell."range"
mode uses the RangeSelection API"manual"
mode requires specifying a custom logic via the eventsThe module supports keyboard navigation for selecting and managing ranges, similar to keyboard navigation used in Google Spreadsheets. The following shortcut keys and their combinations are available:
ArrowUp resets the selected range and moves the focus to the previous vertical cell, setting the initially selected cell if no selection is active ArrowDown resets the selected range and moves the focus to the next vertical cell, setting the initially selected cell if no selection is active ArrowLeft resets the selected range and moves the focus to the previous horizontal cell, setting the initially selected cell if no selection is active ArrowRight resets the selected range and moves the focus to the next horizontal cell, setting the initially selected cell if no selection is active Shift+ArrowUp extends the selected range from the current initial cell to the previous vertical cell Shift+ArrowDown extends the selected range from the current initial cell to the next vertical cell Shift+ArrowLeft extends the selected range from the current initial cell to the previous horizontal cell Shift+ArrowRight extends the selected range from the current initial cell to the next horizontal cell Ctrl+ArrowUp resets the selected range and moves the focus to the first vertical cell Ctrl+ArrowDown resets the selected range and moves the focus to the last vertical cell Ctrl+ArrowLeft resets the selected range and moves the focus to the first horizontal cell Ctrl+ArrowRight resets the selected range and moves the focus to the last horizontal cell Ctrl+Shift+ArrowUp extends the selected range to the first vertical cell Ctrl+Shift+ArrowDown extends the selected range to the last vertical cell Ctrl+Shift+ArrowLeft extends the selected range to the first horizontal cell Ctrl+Shift+ArrowRight extends the selected range to the last horizontal cellThe following shortcut key and mouse combination is available:
Shift + click sets the end cell of the range, extending the selection from the current initial cellThe following shortcut key is available when the editable
mode is set for the Grid component and the BlockSelection
module is used in the "range"
mode:
It is possible to cancel the cells clearing by using the beforeKeyDown
event:
const grid = new dhx.Grid("grid_container", {
columns: [
{ id: "country", header: [{ text: "Country" }] },
{ id: "population", header: [{ text: "Population" }], editable: false },
{ id: "yearlyChange", header: [{ text: "Yearly Change" }] },
],
blockSelection: {
mode: "range"
},
editable: true,
});
grid.events.on("beforeKeyDown", (event) => {
if (event.key === "Delete") {
return false;
}
});
Selection handleâ
The peculiarities of the selection handle functionality are the following:
blockSelection.handle
, it appears in the bottom-right corner of the range.handler
property isn't specified in the handle
object) and the BlockSelection
module is used in the "range"
mode, the behavior of the handle is the following:
"manual"
mode, the handle and handler
are ignored, and the built-in filling does not work.The way of BlockSelection
API interacting with other grid modules depends on which mode the module is used in: the "range"
or the "manual"
mode.
BlockSelection
module uses the RangeSelection
API to manage continuous rectangular ranges.BlockSelection
module does not use the RangeSelection
API. The developer implements logic via the events such as blockSelectionValidate
, afterBlockSelectionApply
.This example shows how to control the start of a block selection and programmatically set a range using the RangeSelection
API.
const grid = new dhx.Grid("grid_container", {
columns: [
{ id: "a", header: [{ text: "A" }], minWidth: 150 },
{ id: "b", header: [{ text: "B" }], minWidth: 150 },
{ id: "c", header: [{ text: "C" }], minWidth: 150 },
{ id: "d", header: [{ text: "D" }], minWidth: 150 },
{ id: "e", header: [{ text: "E" }], minWidth: 150 },
{ id: "f", header: [{ text: "F" }], minWidth: 150 },
],
data,
autoWidth: true,
blockSelection: {
mode: "range",
handle: { allowAxis: "xy" }
}
});
grid.block.events.on("blockSelectionValidate", (cell, handle, event) => {
if (cell.column.id === "a") {
console.log("Selection cannot start from column A");
return false;
}
});
grid.range.setRange({ xStart: "b", xEnd: "d", yStart: "4", yEnd: "8" });
Related sample: Grid. BlockSelection in the "range" mode. Selection with restricted columns
Setting custom logic in the manual modeâThis example demonstrates the "manual"
mode, providing full control and allowing the use of events for custom logic, such as styling.
const grid = new dhx.Grid("grid_container", {
columns: [
{ id: "a", header: [{ text: "A" }], minWidth: 150 },
{ id: "b", header: [{ text: "B" }], minWidth: 150 },
{ id: "c", header: [{ text: "C" }], minWidth: 150 },
{ id: "d", header: [{ text: "D" }], minWidth: 150 },
{ id: "e", header: [{ text: "E" }], minWidth: 150 },
{ id: "f", header: [{ text: "F" }], minWidth: 150 },
],
data,
autoWidth: true,
blockSelection: {
mode: "manual",
handle: false
},
rangeSelection: true,
});
grid.block.events.on("afterBlockSelectionApply", (startCell, endCell) => {
if (
startCell.column.id === endCell.column.id &&
startCell.row.id === endCell.row.id
) {
return;
}
if (grid.range.getRange) {
grid.range.getRangedCells().forEach(cell => {
grid.removeCellCss(cell.row.id, cell.column.id, "custom-selected-cell");
});
}
grid.range.setRange({
xStart: startCell.column.id,
xEnd: endCell.column.id,
yStart: startCell.row.id,
yEnd: endCell.row.id,
});
grid.range.getRangedCells().forEach(cell => {
grid.addCellCss(cell.row.id, cell.column.id, "custom-selected-cell");
});
});
Setting a custom handler for the handleâ
This example shows how to override the handle behavior by adding a custom logic, such as modifying values based on the drag direction.
const columns = [
{ id: "productId", header: [{ text: "Product ID" }] },
{ id: "productName", header: [{ text: "Product Name" }] },
{ id: "category", header: [{ text: "Category" }] },
{ id: "receivedDate", header: [{ text: "Received Date" }], type: "date", dateFormat: "%d.%m.%Y" },
{ id: "stock", header: [{ text: "Stock" }], type: "number" },
{ id: "price", header: [{ text: "Price" }], type: "number", numberMask: { prefix: "$" } }
];
const grid = new dhx.Grid("grid_container", {
columns,
data,
autoWidth: true,
history: true,
blockSelection: {
handle: {
allowAxis: "y",
handler: blockSelectionHandler,
},
},
});
grid.range.setRange({
xStart: "productId",
yEnd: grid.data.getId(0),
});
let initValues = {};
let columnIndex = {};
function blockSelectionHandler({ cell, array, index, grid }) {
if (!index) {
initValues = {};
columnIndex = {};
}
const columnId = cell.column.id;
if (!initValues[columnId]) {
initValues[columnId] = cell.row[columnId];
columnIndex[columnId] = 0;
return { prev: initValues[columnId], current: initValues[columnId] };
}
const colIndex = columnIndex[columnId] += 1;
const initValue = initValues[columnId];
let prev = current = cell.row[columnId];
switch (cell.column.type) {
case "number":
current = initValue + colIndex * 10;
break;
case "date":
const [year, month, day] = initValue.split("-");
current = new Date(Number(year), Number(month) - 1, Number(day) + colIndex).toISOString();
break;
default:
current = initValue;
break;
}
if (columnId === "productId") {
current = `P00${parseInt(initValue.replace(/\D/g, "")) + colIndex}`;
}
if (columnId === "category") {
current = `${current} (${colIndex})`;
}
const history = { prev, current };
grid.data.update(cell.row.id, { [columnId]: current },
index < array.length - 1
);
return history;
}
Related sample: Grid. BlockSelection. Work with the handle configuration
Selection stylingâThis example demonstrates how to customize the appearance of the selected range and of the handle.
<script>
const grid = new dhx.Grid("grid_container", {
columns: [
{ id: "a", header: [{ text: "A" }], minWidth: 150 },
{ id: "b", header: [{ text: "B" }], minWidth: 150 },
{ id: "c", header: [{ text: "C" }], minWidth: 150 },
{ id: "d", header: [{ text: "D" }], minWidth: 150 },
{ id: "e", header: [{ text: "E" }], minWidth: 150 },
{ id: "f", header: [{ text: "F" }], minWidth: 150 },
],
data,
autoWidth: true,
blockSelection: { mode: "range" }
});
</script>
<style>
.dhx_grid_block-selection-area,
.dhx_grid_block-selection-start-cell{
border: var(--dhx-border-width) solid var(--dhx-color-secondary);
background-color: var(--dhx-color-secondary-light-hover);
}
.dhx_grid_block-selection-handle {
border: 2px solid var(--dhx-color-secondary);
background-color: var(--dhx-color-secondary);
}
.dhx_grid_block-selection-handle-area {
border-color: var(--dhx-color-danger);
}
</style>
Related sample: Grid. BlockSelection. Styling (custom CSS)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4