TaskBoard
A kanban board widget that allows you to visualize and mange tasks.
//<code-header>
fiddle.title = 'Task board basic';
//</code-header>
const taskBoard = new TaskBoard({
appendTo : targetElement,
height : 400,
// Url for resource avatar images
resourceImagePath : 'data/Grid/images/transparent-users/',
// Columns to display
columns : [
'todo',
'doing',
'done'
],
// Field used to pair a task to a column
columnField : 'status',
// Project using inline data
project : {
tasks : [
{ id : 1, name : 'Try TaskBoard', status : 'doing' },
{ id : 2, name : 'Test Scheduler', status : 'done' },
{ id : 3, name : 'Evaluate Gantt', status : 'doing' },
{ id : 4, name : 'Download Grid', status : 'todo' },
{ id : 5, name : 'Install Scheduler Pro', status : 'todo' }
],
resources : [
{ id : 1, name : 'Angelo', image : 'angelo.png' },
{ id : 2, name : 'Celia', image : 'celia.png' },
{ id : 3, name : 'Dave', image : 'dave.png' },
{ id : 4, name : 'Emilia', image : 'emilia.png' }
],
assignments : [
{ id : 1, event : 1, resource : 1 },
{ id : 2, event : 2, resource : 2 },
{ id : 3, event : 3, resource : 3 },
{ id : 4, event : 4, resource : 4 },
{ id : 5, event : 5, resource : 1 },
{ id : 6, event : 1, resource : 2 },
{ id : 7, event : 2, resource : 3 },
{ id : 29, event : 3, resource : 1 }
]
}
});Datalayer
TaskBoards datalayer is based on Schedulers. It consumes a project that holds stores that in turn holds records. The stores used by default are:
- TaskStore - Store holding tasks, which are instances of TaskModel
- ResourceStore - Holds resources, see ResourceModel
- AssignmentStore - Holds assignments, links between resources and tasks, see AssignmentModel
Data can be supplied inline or loaded using the projects CrudManager capabilities. Example using inline data:
new TaskBoard({
project : {
tasks : [
{ id : 1, name : 'Try TaskBoard' }
]
}
});And using CrudManager to load remote data:
new TaskBoard({
project : {
loadUrl : 'data/load.php',
autoLoad : true
}
});Columns
The tasks are displayed in columns. Which column a task belongs to is determined by the tasks value for the configured columnField. Columns can be defined as strings or as ColumnModel data objects, supplied to the config. This snippet illustrates it:
new TaskBoard({
// The status field of tasks will be used to link a task to a column
columnField : 'status',
// Columns as strings or objects
columns : [
'todo', // Will be displayed as Todo
{ id : 'done', text : 'Done!' }
],
// TaskBoard data
project : {
tasks : [
// Since we use the "status" field to determine column,
// this task will belong to the "done" column
{ id : 1, name : 'Create mockup', status : 'done' },
// And this one to "todo"
{ id : 2, name : 'Write docs', status : 'todo' }
]
}
});The supplied columns are loaded into an internal store, named columns. You can use it at runtime to access, add, remove and filter columns.
Adding a catch-all column
If you want to add a catch-all column that will contain all tasks that do not match any of the configured columns,
you can do so by adding a column with id * (asterisk) to the columns config:
new TaskBoard({
columns : [
'todo',
'doing',
// Add a catch-all column
{ id : '*', text : 'All others' }
]
});
By default, the catch-all column is not shown in the task editors columns combo. Instead it will be populated with the defined columns + all distinct column values found in the tasks.
Swimlanes
The TaskBoard can optionally be divided into horizontal swimlanes.
//<code-header>
fiddle.title = 'Task board swimlanes';
//</code-header>
const taskBoard = new TaskBoard({
appendTo : targetElement,
height : 500,
width : '100%',
features : {
columnToolbars : false
},
// Swimlanes to display
swimlanes : [
'high',
'low'
],
swimlaneField : 'prio',
columns : [
'todo',
'doing',
'done'
],
columnField : 'status',
project : {
tasks : [
{ id : 1, name : 'Easter campaign', status : 'doing', prio : 'high' },
{ id : 2, name : 'Follow up', status : 'done', prio : 'low' },
{ id : 3, name : 'Adjust ads', status : 'doing', prio : 'low' },
{ id : 4, name : 'Spring campaign', status : 'todo', prio : 'low' },
{ id : 5, name : 'Survey', status : 'todo', prio : 'low' }
]
}
});They are defined and populated in a very similar manner to columns:
new TaskBoard({
// The prio field of tasks will be used to link a task to a swimlane
swimlaneField : 'prio',
// Swimlanes as strings or objects
swimlanes : [
'low', // Will be displayed as Low
{ id : 'high', text : 'High!' }
],
// TaskBoard data
project : {
tasks : [
// Since we use the "prio" field to determine swimlane,
// this task will belong to the "high" lane
{ id : 1, name : 'Create mockup', status : 'done', prio : 'high' },
// And this one to "low"
{ id : 2, name : 'Write docs', status : 'todo', prio : 'low' }
]
}
});Task order
The order of tasks in a column is determined by their order in the task store. By default the store is sorted by weight. Changing store sorting will rearrange the tasks:
// Rearrange tasks by name
taskBoard.project.taskStore.sort('name');
When loading tasks that has no weights specified a generated weight (index * 100) will be silently assigned.
Dragging and dropping tasks changes their weight and resorts the store. Note that if you want to sort by something
other than weight and still want a task to stay where it is dropped you will have to opt out of the default
behaviour by configuring reorderTaskRecords as true.
If you programmatically change a weight you have to manually sort the store for the task to move:
// Programmatic change of weight requires resorting manually
taskBoard.project.taskStore.first.weight = 1000;
taskBoard.project.taskStore.sort();
Sharing a project
When consuming a project from a different product (for example Gantt), you will likely want the cards on the board to have a stable order no matter how data is sorted in the other product. This can be achieved by configuring a taskSorterFn, which is then applied on the UI layer to resort tasks before rendering their cards. You can use it to enforce sorting by weight:
// Shortcut to always enforce sorting by weight
const taskBoard = new TaskBoard({
taskSorterFn : true
});
Or supply a custom Array sort function:
// Custom sorting fn
const taskBoard = new TaskBoard({
taskSorterFn(a, b) {
return a.name.localeCompare(b.name);
}
});
Customizing task content
Task contents can be easily customized using task items, lightweight "widgets" that can be added to a tasks header, body and footer.
For more control over what gets rendered into a task, you can supply a taskRenderer function. It is called prior to updating the DOM for each task, allowing you to directly manipulate what ends up there.
For more information see:
Large data sets
Having a large number of cards rendered to DOM simultaneously can lead to poor performance. To address this issue, TaskBoard supports partial virtualized rendering. This means that only the cards that are visible in the viewport are fully rendered, cards outside the viewport are only outlined.
When enabled, the board displays faster and is more responsive with big data sets, but it also means that scrolling is more costly since cards coming into view has to be rendered. And since it is not fully virtualized, the board will still be slow with very large data sets.
To enable partial virtualized rendering, the height of all tasks must be known. To communicate this to the TaskBoard, implement a getTaskHeight() function. See its documentation for more information and snippets.
Keyboard shortcuts
| Keys | Action | Action description |
|---|---|---|
ArrowDown |
navigateDown | Moves focus to task below currently focused element |
ArrowLeft |
navigateLeft | Moves focus to task to the left of currently focused element |
ArrowUp |
navigateUp | Moves focus to task above currently focused element |
ArrowRight |
navigateRight | Moves focus to task to the right of currently focused element |
Enter |
activate | Show the Task Editor for currently focused task |
Space |
keyboardSelect | This selects or deselects the focused card (deselecting all others) |
Ctrl+Space |
keyboardToggleSelect | This selects or deselects the focused card, preserving any other selection |
Shift+ArrowDown |
selectDown | Hold Shift when keyboard navigating to extend selection |
Shift+ArrowLeft |
selectLeft | Hold Shift when keyboard navigating to extend selection |
Shift+ArrowUp |
selectUp | Hold Shift when keyboard navigating to extend selection |
Shift+ArrowRight |
selectRight | Hold Shift when keyboard navigating to extend selection |
Ctrl is the equivalent to Command and Alt
is the equivalent to Option for Mac usersIf you prefer for selection to always move with the arrow keys, see selectOnNavigation.
The following TaskBoard features has their own keyboard shortcuts. Follow the links for details.
For more information on how to customize keyboard shortcuts, please see our guide.
Configs
157
Configs
157Common
Columns hold their tasks in stores chained off the project's task store. Filters applied to the project store
are by default not applied to the column stores; they are only affected by their own filters. By configuring
chainFilters : true, the filters from the project store will also be taken into account when filtering the
columns.
Filters on the columns' stores are applied separately, and clearing the filters on them by using clearFilters will not clear the filter(s) on the project's store.
See also chainFilters.
Field on a task record used to determine which column the task belongs to.
const taskBoard = new TaskBoard({
columnField : 'status',
columns : [
'todo',
'done'
],
project : {
tasks : [
// Linked using the status field, to the done column
{ id : 1, name : 'Fun task', status : 'done' }
]
}
});
Store containing the TaskBoard columns. A tasks columnField is matched against the id of a
column to determine in which column it is displayed.
Accepts an array of column records/objects/strings, a store instance, a store id or a store config object used to create a new store.
When supplying an array, a store configured with {Core.data.mixin.StoreProxy#config-objectify} is automatically created. Using that config allows for a nicer interaction syntax with the columns:
// Without objectify:
taskBoard.columns.getById('done').text = 'Finished';
// With objectify:
taskBoard.columns.done.text = 'Finished';
When supplying strings, the raw string will be used as the columns id and a capitalized version of it is
used as the columns text:
taskBoard = new TaskBoard({
columns : [
'doing',
'done'
]
});
Is equivalent to:
taskBoard = new TaskBoard({
columns : [
{ id : 'doing', text : 'Doing' },
{ id : 'done', text : 'Done' }
]
});
Columns data can be also be loaded remotely as part of the Project dataset.
*, a catch-all column is created that will hold all tasks that do not
match any of the other columns, including tasks where the column id is not set.An object containing Feature configuration objects (or true if no configuration is required)
keyed by the Feature class name in all lowercase.
When using framework wrappers, features must be configured via featureNameFeature properties.
See Framework Integration Guide for details.
See Keyboard shortcuts for details
Path to load resource images from. Used by the for example the resource picker in the task editor and by the
ResourceAvatars task item. Set this to display miniature images for each resource using their image field.
NOTE: The path should end with a /:
new TaskBoard({
resourceImagePath : 'images/resources/'
});
Show task count for a column in its header, appended after the title
new TaskBoard({
showCountInHeader : false
});
Makes column and swimlane headers sticky
new TaskBoard({
stickyHeaders : true
});
Setting this will cause cards to expand to share the available width if there are fewer than tasksPerRow.
By default, the tasksPerRow always applies, and if it is 3, then a single card in a column will be 33% of the available width.
To have fewer cards than the tasksPerRow evenly share available column width,
configure this as true;
Field on a task record used to determine which swimlane the task belongs to.
const taskBoard = new TaskBoard({
// Use the "prio" field of tasks to determie which swimlane a task belongs to
swimlaneField : 'prio',
swimlanes : [
'high',
'low'
],
project : {
tasks : [
// Linked using the prio field, to the high swimlane
{ id : 1, name : 'Fun task', prio : 'high' }
]
}
});
Store containing the TaskBoard swimlanes. A tasks swimlaneField is matched against the id
of a swimlane to determine in which swimlane it is displayed.
Accepts an array of swimlane records/objects, a store instance, a store id or a store config object used to create a new store.
When supplying an array, a store configured with objectify is automatically created. Using that config allows for a nicer interaction syntax with the swimlanes:
// Without objectify:
taskBoard.swimlanes.getById('highprio').text = 'Important!';
// With objectify:
taskBoard.swimlanes.done.text = 'Finished';
When supplying strings, the raw string will be used as the swimlanes id and a capitalized version of it is
used as the swimlanes text:
taskBoard = new TaskBoard({
swimlanes : [
'high',
'low'
]
});
Is equivalent to:
taskBoard = new TaskBoard({
swimlanes : [
{ id : 'high', text : 'High' },
{ id : 'low', text : 'Low' }
]
});
Controls how many cards are rendered to a row in each column. Can be controlled on a per column basis by setting tasksPerRow
new TaskBoard({
tasksPerRow : 3
});
Advanced
The name of the event that should activate a task and trigger editing (if an editing feature is active). Available options are: 'taskClick', 'taskDblClick' or null (disable)
Set to true to auto generate columns when columns is undefined.
A column will be created for each distinct value of columnField on the tasks. The columns will be sorted in alphabetical order. The following snippet will yield two columns, Q1 and Q2:
const taskBoard = new TaskBoard({
columnField : 'quarter',
autoGenerateColumns : true,
project : {
tasks : [
{ id : 1, name : 'Inform tenants', quarter : 'Q1' },
{ id : 2, name : 'Renovate roofs', quarter : 'Q2' }
]
}
});
Set to true to auto generate swimlanes when swimlanes is undefined.
A swimlane will be created for each distinct value of swimlaneField on the tasks. The swimlanes will be sorted in alphabetical order. The following snippet will yield two swimlanes, Q1 and Q2:
const taskBoard = new TaskBoard({
swimlaneField : 'quarter',
autoGenerateSwimlanes : true,
project : {
tasks : [
{ id : 1, name : 'Inform tenants', quarter : 'Q1' },
{ id : 2, name : 'Renovate roofs', quarter : 'Q2' }
]
}
});
The function is called for each task as part of the render loop, and is expected to return the height in pixels for the task. Using this function is only recommended when using partial virtualized rendering, see the virtualize setting.
How the height is determined is up to the application, it could for example return a fixed value:
taskBoard = new TaskBoard({
getTaskHeight() {
return 150;
}
}
Or get the height from data:
taskBoard = new TaskBoard({
getTaskHeight(taskRecord) {
return taskRecord.myTaskHeight;
}
}
Or use some custom application logic:
taskBoard = new TaskBoard({
getTaskHeight(taskRecord) {
if (taskRecord.isCollapsed) {
return 20;
}
return taskRecord.myTaskHeight;
}
}
| Parameter | Type | Description |
|---|---|---|
taskRecord | TaskModel | The task record |
The height of the task in pixels
Default scroll options, see the options for scrollIntoView
Defaults to:
scrollOptions : {
animate : true,
block : 'nearest',
highlight : true
}
Can be overridden per call for all scroll functions.
An empty function by default, but provided so that you can override it. This function is called each time a swimlane is rendered into the task board. It allows you to manipulate the DOM config object used for the swimlane before it is synced to DOM, thus giving you control over styling and contents.
const taskBoard = new TaskBoard({
swimlaneRenderer({ swimlaneRecord, swimlaneConfig }) {
// Add an icon to all swimlane headers
swimlaneConfig.children.header.children.icon = {
tag : 'i',
class : 'fa fa-dog'
}
}
});
| Parameter | Type | Description |
|---|---|---|
detail | Object | An object containing the information needed to render a swimlane. |
detail.swimlaneRecord | SwimlaneModel | The swimlane. |
detail.swimlaneConfig | DomConfig | DOM config object for the swimlane |
Allows sorting tasks in the UI independent of how they are sorted in the task store.
Specify true to force sorting tasks by weight.
Supply a sort function to force a custom sort order.
This is likely something you will want to use if combining TaskBoard with other products, sharing the project. Without this, sorting tasks in for example Gantt will also rearrange the cards on the board.
As described above it accepts either a boolean or a Function, but it always returns a sorter function.
| Parameter | Type | Description |
|---|---|---|
first | TaskModel | The first task to compare |
second | TaskModel | The second task to compare |
Return 1 if first task is greater than second task, -1 if the opposite is true or 0
if they are equal
CSS
CSS variable prefix, appended to the keys used in css.
Normally you do not need to change this value.
Data
Inline assignments, will be loaded into an internally created AssignmentStore as a part of a project.
Default values to apply to task records created by task boards features (such as the column header menu and the column toolbar)
A project config object or an instance that holds all stores and data used by the TaskBoard.
const taskBoard = new TaskBoard({
project : {
// Use a custom task model
taskModelClass : MyTaskModel,
// Supply inline data
tasks : [
{ id : 1, name: 'Task 1', ... },
...
]
});
Project has built-in crud manager functionality to handle syncing with a backend:
const taskBoard = new TaskBoard({
project : {
loadUrl : 'data/data.json'
},
autoLoad : true
});
Also has built-in state tracking manager functionality to handle undo/redo:
```javascript
const taskBoard = new TaskBoard({
stm : {
autoRecord : true,
disabled : false
}
});Inline resources, will be loaded into an internally created ResourceStore as a part of a project.
Experimental
Experimental, animate actions that cannot be animated using CSS transitions. Currently includes:
- Programmatically moving tasks
- Moving tasks using the task editor
- Adding tasks
- Removing tasks
- Sorting tasks
- Hiding/showing/filtering columns
- Hiding/showing/filtering swimlanes
new TaskBoard({
useDomTransition : true
});
NOTE: This flag is not supported for Lightning Web Components
Masking
TaskBoard does not use a sync mask by default. If you want one, see syncMask for configuration options.
Misc
By default, the header text is HTML-encoded. Set this flag to false disable this and allow html
elements in the column headers. Can also be specified on a single
column.
Other
A function which renders the text, HTML, or DomConfig object to show as the column title. If you provide a
DomConfig object, it will replace the title element and you are responsible for styling it + laying it out.
new TaskBoard({
columnTitleRenderer({ columnRecord }) {
const highPrioCount = columnRecord.taskStore.query(task => task.status === columnRecord.id && task.prio === 'high').length;
return `${columnRecord.text} <span class="highprio-count">(${highPrioCount} high prio)</span>`;
}
})
| Parameter | Type | Description |
|---|---|---|
renderData | Object | |
columnRecord | ColumnModel | The column instance |
Whether to draw cards on scroll, or only when scrolling ends.
Only applies when using partial virtualized rendering (see getTaskHeight).
Setting this to false will boost scroll performance, but cards scrolled into view will be empty outlines
until scrolling ends.
By turning on this setting you enable partial virtualized rendering for the board, which reduces initial rendering time and makes interaction less sluggish when using thousands of tasks. The tradeoff is that scrolling in most cases will be slower.
For a nice UX, it is strongly recommended to also implement a getTaskHeight function. Without it, the height of tasks out of view will be unknown and the behaviour when scrolling will be less than ideal.
Scrolling
Configuration values for the ScrollManager class. It is used to manage column/body scrolling during task, column or swimlane drag.
new TaskBoard({
scrollManager : {
zoneWidth : 100, // increase zone size
scrollSpeed : 3 // and scroll speed
}
})
Task content
An empty function by default, but provided so that you can override it. This function is called each time a task is rendered into the task board. It allows you to manipulate the DOM config object used for the card before it is synced to DOM, thus giving you control over styling and contents.
const taskBoard = new TaskBoard({
taskRenderer({ taskRecord, cardConfig }) {
// Add an icon to all tasks header
cardConfig.children.header.children.icon = {
tag : 'i',
class : 'fa fa-beer'
}
}
});
For more information, see the Customize task contents guide.
| Parameter | Type | Description |
|---|---|---|
detail | Object | An object containing the information needed to render a task. |
detail.taskRecord | TaskModel | The task record. |
detail.columnRecord | ColumnModel | The column the task will be displayed in. |
detail.swimlaneRecord | SwimlaneModel | The swimlane the task will be displayed in. |
detail.cardConfig | DomConfig | DOM config object for the cards element |
Content
DOM
Float & align
Layout
misc
Properties
139
Properties
139Common
Field on a task record used to determine which column the task belongs to.
taskBoard.columnField = 'category';
Store containing the TaskBoard columns.
The ProjectModel instance, containing the data visualized by the TaskBoard.
Setting this will cause cards to expand to share the available width if there are fewer than tasksPerRow.
By default, the tasksPerRow always applies, and if it is 3, then a single card in a column will be 33% of the available width.
To have fewer cards than the tasksPerRow evenly share available column width,
configure this as true;
Field on a task record used to determine which swimlane the task belongs to.
taskBoard.swimlaneField = 'category';
Store containing the TaskBoard swimlanes.
Advanced
The function is called for each task as part of the render loop, and is expected to return the height in pixels for the task. Using this function is only recommended when using partial virtualized rendering, see the virtualize setting.
How the height is determined is up to the application, it could for example return a fixed value:
taskBoard = new TaskBoard({
getTaskHeight() {
return 150;
}
}
Or get the height from data:
taskBoard = new TaskBoard({
getTaskHeight(taskRecord) {
return taskRecord.myTaskHeight;
}
}
Or use some custom application logic:
taskBoard = new TaskBoard({
getTaskHeight(taskRecord) {
if (taskRecord.isCollapsed) {
return 20;
}
return taskRecord.myTaskHeight;
}
}
| Parameter | Type | Description |
|---|---|---|
taskRecord | TaskModel | The task record |
The height of the task in pixels
Class hierarchy
Data
Inline assignments, will be loaded into an internally created AssignmentStore as a part of a project.
Inline resources, will be loaded into an internally created ResourceStore as a part of a project.
Other
Whether to draw cards on scroll, or only when scrolling ends.
Only applies when using partial virtualized rendering (see getTaskHeight).
Setting this to false will boost scroll performance, but cards scrolled into view will be empty outlines
until scrolling ends.
By turning on this setting you enable partial virtualized rendering for the board, which reduces initial rendering time and makes interaction less sluggish when using thousands of tasks. The tradeoff is that scrolling in most cases will be slower.
For a nice UX, it is strongly recommended to also implement a getTaskHeight function. Without it, the height of tasks out of view will be unknown and the behaviour when scrolling will be less than ideal.
CSS
DOM
Layout
Misc
Selection
State
Widget hierarchy
Functions
101
Functions
101Common
Add a new task to the specified column / swimlane intersection (swimlane is optional), scroll it into view and start editing it (if an editing feature is enabled).
By default the task is created using the data defined in the newTaskDefaults combined with values
for the columnField, the swimlaneField and a generated weight to place it last. To override these or to
supply your own values for any field, pass the taskData argument.
If project is configured to auto sync changes to backend, the sync request will be awaited before editing starts.
| Parameter | Type | Description |
|---|---|---|
columnRecord | ColumnModel | Column to add the task to |
swimlaneRecord | ColumnModel | Swimlane to add the task to |
taskData | Object | Data for the new task |
Removes one or more tasks from the linked task store (and thus the TaskBoard).
First fires a 'beforeTaskRemove' event, which is preventable and async. Return false or a promise that
resolves to false from a listener to prevent the operation.
taskBoard.on({
async beforeRemoveTask() {
const result = await askForConfirmation();
return result;
}
});
taskBoard.remove(myTask);
| Parameter | Type | Description |
|---|---|---|
taskRecord | TaskModel | TaskModel[] | A single task or an array thereof to remove from the task store. |
Returns true if the tasks were removed, false if the operation was prevented.
DOM
Retrieves the element for the supplied column.
Only applicable when not using swimlanes. If you are using swimlanes, see getColumnElements.
| Parameter | Type | Description |
|---|---|---|
columnRecord | ColumnModel |
Retrieves the elements for the supplied column. When using swimlanes, a column has one element per swimlane.
| Parameter | Type | Description |
|---|---|---|
columnRecord | ColumnModel |
Retrieves the header element for the supplied column.
| Parameter | Type | Description |
|---|---|---|
columnRecord | ColumnModel |
Retrieves the element for the supplied swimlane / column intersection.
const element = taskBoard.getSwimlaneColumnElement(taskBoard.swimlanes.first, taskBoard.columns.last);
| Parameter | Type | Description |
|---|---|---|
swimlaneRecord | SwimlaneModel | |
columnRecord | ColumnModel |
Retrieves the element for the supplied swimlane.
const swimlaneElement = taskBoard.getSwimlaneElement(taskBoard.swimlanes.first);
| Parameter | Type | Description |
|---|---|---|
swimlaneRecord | SwimlaneModel |
Retrieves the element for the column that holds the supplied task record.
const columnElement = taskBoard.getColumnElement(taskRecord);
| Parameter | Type | Description |
|---|---|---|
taskRecord | TaskModel |
Retrieves the task element (card) corresponding to the supplied task record.
const cardElement = taskBoard.getTaskElement(taskRecord);
| Parameter | Type | Description |
|---|---|---|
taskRecord | TaskModel |
Retrieves the element for the swimlane that holds the supplied task record.
const swimlaneElement = taskBoard.getTaskSwimlaneElement(taskRecord);
| Parameter | Type | Description |
|---|---|---|
taskRecord | TaskModel |
Retrieves a column record resolved from the supplied element. Has to be a .b-task-board-column element or
descendant thereof (such as a card).
const columnRecord = taskBoard.resolveColumnRecord(taskElement);
| Parameter | Type | Description |
|---|---|---|
element | HTMLElement |
Retrieves a swimlane record resolved from the supplied element. Has to be a .b-task-board-swimlane element or
descendant thereof.
const swimlaneRecord = taskBoard.resolveSwimlaneRecord(taskElement);
| Parameter | Type | Description |
|---|---|---|
element | HTMLElement |
Retrieves a task record corresponding to the supplied element. Has to be a .b-task-board-card element or
descendant thereof.
const taskRecord = taskBoard.resolveTaskRecord(taskElement);
| Parameter | Type | Description |
|---|---|---|
element | HTMLElement |
Scrolling
Scroll specified column into view.
taskBoard.scrollToColumn('backlog');
taskBoard.scrollToColumn(taskBoard.columns.first);
| Parameter | Type | Description |
|---|---|---|
columnOrId | ColumnModel | Number | String | Column or its id |
options | BryntumScrollOptions | Scroll options, see scrollOptions |
Scroll to the intersection between specified swimlane and column.
taskBoard.scrollToIntersection('high', 'done');
taskBoard.scrollToIntersection(taskBoard.swimlanes.low, taskBoard.columns.todo);
| Parameter | Type | Description |
|---|---|---|
swimlaneOrId | SwimlaneModel | Number | String | Swimlane or its id |
columnOrId | ColumnModel | Number | String | Column or its id |
options | BryntumScrollOptions | Scroll options, see scrollOptions |
Scroll specified swimlane into view.
taskBoard.scrollToSwimlane('high');
taskBoard.scrollToSwimlane(taskBoard.swimlanes.last);
| Parameter | Type | Description |
|---|---|---|
swimlaneOrId | SwimlaneModel | Number | String | Swimlane or its id |
options | BryntumScrollOptions | Scroll options, see scrollOptions |
Scroll the specified task into view.
taskBoard.scrollToTask(10);
taskBoard.scrollToTask(taskStore.first);
| Parameter | Type | Description |
|---|---|---|
taskOrId | TaskModel | Number | String | |
options | BryntumScrollOptions | Scroll options, see scrollOptions |
Configuration
Events
Misc
Other
Selection
Widget hierarchy
Events
48
Events
48Triggered when a task is "activated" by pressing Enter or double clicking it.
By default this leads to the task editor being shown.
taskBoard.on('activateTask', ({ taskRecord }) => {
Toast.show(`Activated ${taskRecord.name}`);
});
// Adding a listener using the "on" method
taskBoard.on('activateTask', ({ source, taskRecord, event }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
taskRecord | TaskModel | Task record |
event | MouseEvent | Browser event |
Triggered when one or more tasks are to be removed by a call to removeTask().
The UI routes through removeTask() (currently only the task menu offers task removal), this event can be
used to add a confirmation flow or similar to those actions.
Return false or a promise that resolves to false in a listener to prevent removal.
taskBoard.on({
async beforeRemoveTask() {
const result = await askForConfirmation();
return result;
}
});
// Adding a listener using the "on" method
taskBoard.on('beforeTaskRemove', ({ source, taskRecords }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
taskRecords | TaskModel[] | Task records to be removed |
Triggered when a column header is clicked.
taskBoard.on('columnHeaderClick', ({ columnRecord }) => {
Toast.show(`Clicked on ${columnRecord.text}`);
});
// Adding a listener using the "on" method
taskBoard.on('columnHeaderClick', ({ source, columnRecord, event }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
columnRecord | ColumnModel | Column record |
event | MouseEvent | Browser event |
Triggered when a column header is right-clicked.
taskBoard.on('columnHeaderContextMenu', ({ columnRecord }) => {
Toast.show(`Right-clicked on ${columnRecord.text}`);
});
// Adding a listener using the "on" method
taskBoard.on('columnHeaderContextMenu', ({ source, columnRecord, event }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
columnRecord | ColumnModel | Column record |
event | MouseEvent | Browser event |
Triggered when a column header is double-clicked.
taskBoard.on('columnHeaderDblClick', ({ columnRecord }) => {
Toast.show(`Double-clicked on ${columnRecord.text}`);
});
// Adding a listener using the "on" method
taskBoard.on('columnHeaderDblClick', ({ source, columnRecord, event }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
columnRecord | ColumnModel | Column record |
event | MouseEvent | Browser event |
Triggered when a column title element is clicked.
taskBoard.on('columnTitleClick', ({ columnRecord, event }) => {
Toast.show(`Clicked on ${columnRecord.text}`);
});
// Adding a listener using the "on" method
taskBoard.on('columnTitleClick', ({ source, columnRecord, event }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
columnRecord | ColumnModel | Column record |
event | MouseEvent | Browser event |
Triggered when a column title element is right-clicked.
taskBoard.on('columnTitleContextMenu', ({ columnRecord }) => {
Toast.show(`Right-clicked on ${columnRecord.text}`);
});
// Adding a listener using the "on" method
taskBoard.on('columnTitleContextMenu', ({ source, columnRecord, event }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
columnRecord | ColumnModel | Column record |
event | MouseEvent | Browser event |
Triggered when a column title element is double-clicked.
taskBoard.on('columnTitleDblClick', ({ columnRecord }) => {
Toast.show(`Double-clicked on ${columnRecord.text}`);
});
// Adding a listener using the "on" method
taskBoard.on('columnTitleDblClick', ({ source, columnRecord, event }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
columnRecord | ColumnModel | Column record |
event | MouseEvent | Browser event |
Triggered when a tasks element is removed.
This happens when a task is removed or when it is move to another swimlane / column (in which case a renderTask
event is triggered for the new element).
If you used listener for renderTask to alter the element of tasks, you should also listen for this event to
clean that modification up.
// Adding a listener using the "on" method
taskBoard.on('removeTaskElement', ({ source, taskId, element }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | TaskBoard instance |
taskId | String | Number | Id of the task (not the record itself since it might be removed) |
element | HTMLElement | Tasks element |
Triggered when a task is rendered.
This happens on initial render, when a task is added or when the task element is updated.
Listening to this event allows you to manipulate the tasks element directly after it has been updated. Please
note that we strongly recommend using a taskRenderer to manipulate the DomConfig used to update the task for
most scenarios.
If you listen for this event and manipulate the element in some way, you should also listen for
removeTaskElement and revert/clean up the changes there.
// Adding a listener using the "on" method
taskBoard.on('renderTask', ({ source, taskRecord, isRefresh, element }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | TaskBoard instance |
taskRecord | TaskModel | Task being rendered |
isRefresh | Boolean |
|
element | HTMLElement | Tasks element |
Triggered when all tasks in the task board are rendered
// Adding a listener using the "on" method
taskBoard.on('renderTasks', ({ source, taskRecords }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | TaskBoard instance |
taskRecords | TaskModel[] | Tasks being rendered |
Triggered when a swimlane header is clicked.
taskBoard.on('swimlaneHeaderClick', ({ swimlaneRecord }) => {
Toast.show(`Clicked on ${swimlaneRecord.text}`);
});
// Adding a listener using the "on" method
taskBoard.on('swimlaneHeaderClick', ({ source, swimlaneRecord, event }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
swimlaneRecord | SwimlaneModel | Swimlane record |
event | MouseEvent | Browser event |
Triggered when a swimlane header is right-clicked.
taskBoard.on('swimlaneHeaderContextMenu', ({ swimlaneRecord }) => {
Toast.show(`Right-clicked on ${swimlaneRecord.text}`);
});
// Adding a listener using the "on" method
taskBoard.on('swimlaneHeaderContextMenu', ({ source, swimlaneRecord, event }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
swimlaneRecord | SwimlaneModel | Swimlane record |
event | MouseEvent | Browser event |
Triggered when a swimlane header is double-clicked.
taskBoard.on('swimlaneHeaderDblClick', ({ swimlaneRecord }) => {
Toast.show(`Double-clicked on ${swimlaneRecord.text}`);
});
// Adding a listener using the "on" method
taskBoard.on('swimlaneHeaderDblClick', ({ source, swimlaneRecord, event }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
swimlaneRecord | SwimlaneModel | Swimlane record |
event | MouseEvent | Browser event |
Triggered when a card is clicked.
taskBoard.on('taskClick', ({ taskRecord }) => {
Toast.show(`Clicked on ${taskRecord.name}`);
});
// Adding a listener using the "on" method
taskBoard.on('taskClick', ({ source, taskRecord, columnRecord, swimlaneRecord, event }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
taskRecord | TaskModel | Task record |
columnRecord | ColumnModel | Column record for the tasks column |
swimlaneRecord | SwimlaneModel | Swimlane record for the tasks swimlane (if used) |
event | MouseEvent | Browser event |
Triggered when a card is double-clicked
taskBoard.on('taskDblClick', ({ taskRecord }) => {
Toast.show(`Double clicked on ${taskRecord.name}`);
});
// Adding a listener using the "on" method
taskBoard.on('taskDblClick', ({ source, taskRecord, columnRecord, swimlaneRecord, event }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
taskRecord | TaskModel | Task record |
columnRecord | ColumnModel | Column record for the tasks column |
swimlaneRecord | SwimlaneModel | Swimlane record for the tasks swimlane (if used) |
event | MouseEvent | Browser event |
Triggered when the mouse enters a card
taskBoard.on('taskMouseEnter', ({ taskRecord }) => {
Toast.show(`Mouse entered ${taskRecord.name}`);
});
// Adding a listener using the "on" method
taskBoard.on('taskMouseEnter', ({ source, taskRecord, columnRecord, swimlaneRecord, event }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
taskRecord | TaskModel | Task record |
columnRecord | ColumnModel | Column record for the tasks column |
swimlaneRecord | SwimlaneModel | Swimlane record for the tasks swimlane (if used) |
event | MouseEvent | Browser event |
Triggered when the mouse leaves a card
taskBoard.on('taskMouseLeave', ({ taskRecord }) => {
Toast.show(`Mouse left ${taskRecord.name}`);
});
// Adding a listener using the "on" method
taskBoard.on('taskMouseLeave', ({ source, taskRecord, columnRecord, swimlaneRecord, event }) => {
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
taskRecord | TaskModel | Task record |
columnRecord | ColumnModel | Column record for the tasks column |
swimlaneRecord | SwimlaneModel | Swimlane record for the tasks swimlane (if used) |
event | MouseEvent | Browser event |
Event handlers
48
Event handlers
48Called when a task is "activated" by pressing Enter or double clicking it.
By default this leads to the task editor being shown.
taskBoard.on('activateTask', ({ taskRecord }) => {
Toast.show(`Activated ${taskRecord.name}`);
});
new TaskBoard({
onActivateTask({ source, taskRecord, event }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
taskRecord | TaskModel | Task record |
event | MouseEvent | Browser event |
Called when one or more tasks are to be removed by a call to removeTask().
The UI routes through removeTask() (currently only the task menu offers task removal), this event can be
used to add a confirmation flow or similar to those actions.
Return false or a promise that resolves to false in a listener to prevent removal.
taskBoard.on({
async beforeRemoveTask() {
const result = await askForConfirmation();
return result;
}
});
new TaskBoard({
onBeforeTaskRemove({ source, taskRecords }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
taskRecords | TaskModel[] | Task records to be removed |
Called when a column header is clicked.
taskBoard.on('columnHeaderClick', ({ columnRecord }) => {
Toast.show(`Clicked on ${columnRecord.text}`);
});
new TaskBoard({
onColumnHeaderClick({ source, columnRecord, event }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
columnRecord | ColumnModel | Column record |
event | MouseEvent | Browser event |
Called when a column header is right-clicked.
taskBoard.on('columnHeaderContextMenu', ({ columnRecord }) => {
Toast.show(`Right-clicked on ${columnRecord.text}`);
});
new TaskBoard({
onColumnHeaderContextMenu({ source, columnRecord, event }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
columnRecord | ColumnModel | Column record |
event | MouseEvent | Browser event |
Called when a column header is double-clicked.
taskBoard.on('columnHeaderDblClick', ({ columnRecord }) => {
Toast.show(`Double-clicked on ${columnRecord.text}`);
});
new TaskBoard({
onColumnHeaderDblClick({ source, columnRecord, event }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
columnRecord | ColumnModel | Column record |
event | MouseEvent | Browser event |
Called when a column title element is clicked.
taskBoard.on('columnTitleClick', ({ columnRecord, event }) => {
Toast.show(`Clicked on ${columnRecord.text}`);
});
new TaskBoard({
onColumnTitleClick({ source, columnRecord, event }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
columnRecord | ColumnModel | Column record |
event | MouseEvent | Browser event |
Called when a column title element is right-clicked.
taskBoard.on('columnTitleContextMenu', ({ columnRecord }) => {
Toast.show(`Right-clicked on ${columnRecord.text}`);
});
new TaskBoard({
onColumnTitleContextMenu({ source, columnRecord, event }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
columnRecord | ColumnModel | Column record |
event | MouseEvent | Browser event |
Called when a column title element is double-clicked.
taskBoard.on('columnTitleDblClick', ({ columnRecord }) => {
Toast.show(`Double-clicked on ${columnRecord.text}`);
});
new TaskBoard({
onColumnTitleDblClick({ source, columnRecord, event }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
columnRecord | ColumnModel | Column record |
event | MouseEvent | Browser event |
Called when a tasks element is removed.
This happens when a task is removed or when it is move to another swimlane / column (in which case a renderTask
event is called for the new element).
If you used listener for renderTask to alter the element of tasks, you should also listen for this event to
clean that modification up.
new TaskBoard({
onRemoveTaskElement({ source, taskId, element }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | TaskBoard instance |
taskId | String | Number | Id of the task (not the record itself since it might be removed) |
element | HTMLElement | Tasks element |
Called when a task is rendered.
This happens on initial render, when a task is added or when the task element is updated.
Listening to this event allows you to manipulate the tasks element directly after it has been updated. Please
note that we strongly recommend using a taskRenderer to manipulate the DomConfig used to update the task for
most scenarios.
If you listen for this event and manipulate the element in some way, you should also listen for
removeTaskElement and revert/clean up the changes there.
new TaskBoard({
onRenderTask({ source, taskRecord, isRefresh, element }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | TaskBoard instance |
taskRecord | TaskModel | Task being rendered |
isRefresh | Boolean |
|
element | HTMLElement | Tasks element |
Called when all tasks in the task board are rendered
new TaskBoard({
onRenderTasks({ source, taskRecords }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | TaskBoard instance |
taskRecords | TaskModel[] | Tasks being rendered |
Called when a swimlane header is clicked.
taskBoard.on('swimlaneHeaderClick', ({ swimlaneRecord }) => {
Toast.show(`Clicked on ${swimlaneRecord.text}`);
});
new TaskBoard({
onSwimlaneHeaderClick({ source, swimlaneRecord, event }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
swimlaneRecord | SwimlaneModel | Swimlane record |
event | MouseEvent | Browser event |
Called when a swimlane header is right-clicked.
taskBoard.on('swimlaneHeaderContextMenu', ({ swimlaneRecord }) => {
Toast.show(`Right-clicked on ${swimlaneRecord.text}`);
});
new TaskBoard({
onSwimlaneHeaderContextMenu({ source, swimlaneRecord, event }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
swimlaneRecord | SwimlaneModel | Swimlane record |
event | MouseEvent | Browser event |
Called when a swimlane header is double-clicked.
taskBoard.on('swimlaneHeaderDblClick', ({ swimlaneRecord }) => {
Toast.show(`Double-clicked on ${swimlaneRecord.text}`);
});
new TaskBoard({
onSwimlaneHeaderDblClick({ source, swimlaneRecord, event }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
swimlaneRecord | SwimlaneModel | Swimlane record |
event | MouseEvent | Browser event |
Called when a card is clicked.
taskBoard.on('taskClick', ({ taskRecord }) => {
Toast.show(`Clicked on ${taskRecord.name}`);
});
new TaskBoard({
onTaskClick({ source, taskRecord, columnRecord, swimlaneRecord, event }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
taskRecord | TaskModel | Task record |
columnRecord | ColumnModel | Column record for the tasks column |
swimlaneRecord | SwimlaneModel | Swimlane record for the tasks swimlane (if used) |
event | MouseEvent | Browser event |
Called when a card is double-clicked
taskBoard.on('taskDblClick', ({ taskRecord }) => {
Toast.show(`Double clicked on ${taskRecord.name}`);
});
new TaskBoard({
onTaskDblClick({ source, taskRecord, columnRecord, swimlaneRecord, event }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
taskRecord | TaskModel | Task record |
columnRecord | ColumnModel | Column record for the tasks column |
swimlaneRecord | SwimlaneModel | Swimlane record for the tasks swimlane (if used) |
event | MouseEvent | Browser event |
Called when the mouse enters a card
taskBoard.on('taskMouseEnter', ({ taskRecord }) => {
Toast.show(`Mouse entered ${taskRecord.name}`);
});
new TaskBoard({
onTaskMouseEnter({ source, taskRecord, columnRecord, swimlaneRecord, event }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
taskRecord | TaskModel | Task record |
columnRecord | ColumnModel | Column record for the tasks column |
swimlaneRecord | SwimlaneModel | Swimlane record for the tasks swimlane (if used) |
event | MouseEvent | Browser event |
Called when the mouse leaves a card
taskBoard.on('taskMouseLeave', ({ taskRecord }) => {
Toast.show(`Mouse left ${taskRecord.name}`);
});
new TaskBoard({
onTaskMouseLeave({ source, taskRecord, columnRecord, swimlaneRecord, event }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | TaskBoard | This TaskBoard |
taskRecord | TaskModel | Task record |
columnRecord | ColumnModel | Column record for the tasks column |
swimlaneRecord | SwimlaneModel | Swimlane record for the tasks swimlane (if used) |
event | MouseEvent | Browser event |