DHTMLX Kanban. Grouping two or more statuses into a single column example
When your workflow has more statuses than you want visible columns, you can group multiple statuses into a single column. This keeps the board compact while preserving fine-grained status tracking. Cards show their specific status, but live in a broader column.
Live example
const updateColumn = card => {
for (let col in groupingRules) {
if (groupingRules[col].includes(card.status)) {
card.column = col;
break;
}
}
};
const groupingRules = {
open: ["todo", "unassigned"],
inprogress: ["dev", "testing"],
done: ["merged", "released"],
};
cards = cards.map(card => {
updateColumn(card);
return card;
});
const board = new kanban.Kanban("#root", {
columns,
cards,
cardShape: {
label: true,
headerFields: [
{
key: "status",
label: "Status",
},
],
},
editorShape: [
{
key: "label",
type: "text",
label: "Title",
},
{
key: "status",
type: "select",
label: "Status",
values: [
{ id: "todo", label: "To do" },
{ id: "unassigned", label: "Unassigned" },
{ id: "dev", label: "In development" },
{ id: "testing", label: "Testing" },
{ id: "merged", label: "Merged" },
{ id: "released", label: "Released" },
],
},
],
});
board.api.intercept("move-card", ev => {
board.api.exec("update-card", {
id: ev.id,
card: { status: groupingRules[ev.columnId][0] },
});
});
board.api.intercept("update-card", ev => {
updateColumn(ev.card);
});<div class="g-wrap" style="height: 100%;">
<!-- Kanban container -->
<div id="root" style="height: 100%;"></div>
</div>
<!-- dataset -->
<script>
const columns = [
{
label: "Open",
id: "open",
},
{
label: "In progress",
id: "inprogress",
},
{
label: "Done",
id: "done",
},
];
let cards = [
{
label: "Integration with Angular/React",
status: "todo",
},
{
label: "Archive the cards/boards ",
status: "unassigned",
},
{
label: "Searching and filtering",
status: "dev",
},
{
label: "Set the tasks priorities",
status: "testing",
},
{
label: "Custom icons",
status: "merged",
},
{
label: "Integration with Gantt",
status: "released",
},
{
label: "Drag and drop",
status: "todo",
},
{
label: "Adding images",
status: "unassigned",
},
{
label: "Create cards and lists from the UI and from code",
status: "dev",
},
{
label: "Draw swimlanes",
status: "testing",
},
{
label: "Progress bar",
status: "released",
},
];
</script>The code defines a groupingRules map that assigns statuses to columns (e.g., "todo" and "unassigned" both map to the "Open" column). Before initialization, cards are preprocessed to set their column based on their status. Two interceptors keep things in sync: intercept("move-card") assigns the first status of the target column when a card is dragged, and intercept("update-card") recalculates the column when a status changes in the editor. The headerFields card shape option displays the status badge directly on each card.
Solution overview
- Define a
groupingRulesobject mapping column IDs to arrays of status values - Pre-process cards to assign
columnbased on theirstatusfield - Use
headerFieldsincardShapeto display the status on each card - Add
editorShapewith aselectfield for the status, listing all possible values - Intercept
move-cardto assign the first status of the target column - Intercept
update-cardto recalculate the column when status changes
Key points
intercept, notonfor pre-commit changes:api.interceptruns before the action is committed and can modify event data;api.onruns after. Useinterceptwhen you need to transform data as part of the action, not react to it- First status is the default: When dragging a card to a new column, it gets
groupingRules[columnId][0], the first status in that column's group headerFieldsfor visual feedback: the default card shape does not have the status of a card, because by default it is 1 status per column and the name of the status is on the column header- Custom
editorShaperequired: The default editor doesn't have a status fields. You need to define it explicitly
API reference
- cardShape: Configures card appearance including
headerFields - editorShape: Defines custom editor fields
- api.intercept: Intercepts and modifies events before they are applied