Skip to main content

DHTMLX Kanban. Custom toolbar with custom searching and sorting logic example

The default toolbar provides basic actions, but real applications often need branding, custom search logic, sort options, and additional buttons. The toolbar items array accepts a mix of built-in controls, custom HTML strings, and functions for full flexibility.

Live example

const board = new kanban.Kanban("#root", {
    columns,
    cards,
    cardShape
});

new kanban.Toolbar("#toolbar", {
    api: board.api,
    items: [
        () => `<div style="font-weight:500;font-size:18px;padding:0 10px;">Logo<div/>`,
        {
            type: "search",
            options: [
                {
                    id: "label",
                    label: "By label",
                },
                {
                    id: "start_date",
                    label: "By date",
                    searchRule: (card, value, by) => {
                        const date = card[by];
                        return date?.toString().toLowerCase().includes(value?.toLowerCase());
                    },
                },
            ],
        },
        "spacer",
        {
            type: "sort",
            options: [
                {
                    by: "label",
                    dir: "asc",
                    text: "Sort by label",
                },
            ],
        },
        "addRow",
        "addColumn",
        `<div style="margin-left: auto; padding-left: 10px;"><button id="addBtn" class="dhx_sample-btn dhx_sample-btn--cta">Add card</button></div>`,
    ],
});

document.querySelector("#addBtn").addEventListener("click", () => {
    board.addCard({ columnId: "backlog", card: { label:"Untitled" } });
});
<link rel="stylesheet" href="https://snippet.dhtmlx.com/codebase/assets/css/auxiliary_controls.css">

<!-- component containers -->
<div id="toolbar"></div>
<div id="root" style="height: calc(100% - 56px);"></div>

<!-- dataset -->

<script>
const users = [
		{
			id: 1,
			label: "Steve Smith",
			avatar: "https://snippet.dhtmlx.com/codebase/data/kanban/01/img/user-1.jpg",
		},
		{
			id: 2,
			label: "Aaron Long",
			avatar: "https://snippet.dhtmlx.com/codebase/data/kanban/01/img/user-2.jpg",
		},
		{
			id: 3,
			label: "Angela Allen",
			avatar: "https://snippet.dhtmlx.com/codebase/data/kanban/01/img/user-3.jpg",
		},
		{
			id: 4,
			label: "Angela Long",
			avatar: "https://snippet.dhtmlx.com/codebase/data/kanban/01/img/user-4.jpg",
		},
		{
			id: 5,
			label: "John Doe",
		},
	];

	const cardShape = {
		label: true,
		description: true,
		progress: true,
		start_date: true,
		end_date: true,
		users: {
			show: true,
			values: users,
		},
		priority: {
			show: true,
			values: [
				{ id: 1, color: "#FF5252", label: "High", value: 1 },
				{ id: 2, color: "#FFC975", label: "Medium", value: 2 },
				{ id: 3, color: "#65D3B3", label: "Low", value: 3 },
			],
		},
		color: true,
		menu: true,
		cover: true,
		attached: false,
	};

	const editorShape = [
		{
			type: "multiselect",
			key: "users",
			label: "Users",
			options: users,
		},
	];

	const columns = [
		{
			label: "Backlog",
			id: "backlog",
		},
		{
			label: "In progress",
			id: "inprogress",
		},
		{
			label: "Testing",
			id: "testing",
		},
		{
			label: "Done",
			id: "done",
		},
	];

	const rows = [
		{
			label: "Feature",
			id: "feature",
		},
		{
			label: "Task",
			id: "task",
		},
	];

	const cards = [
		{
			label: "Integration with Angular/React",
			priority: 1,
			color: "#65D3B3",
			start_date: new Date("01/07/2021"),
			users: [3, 2],
			column: "backlog",
			type: "feature",
		},
		{
			label: "Archive the cards/boards ",
			priority: 3,
			color: "#58C3FE",
			users: [5],
			progress: 1,
			column: "backlog",
			type: "feature",
		},
		{
			label: "Searching and filtering",
			priority: 1,
			color: "#58C3FE",
			start_date: new Date("01/09/2021"),
			users: [3, 1],
			progress: 1,
			column: "backlog",
			type: "task",
		},
		{
			label: "Set the tasks priorities",
			color: "#FFC975",
			start_date: new Date("12/21/2020"),
			users: [4],
			progress: 75,
			column: "inprogress",
			type: "feature",
			attached: [
				{
					isCover: true,
					coverURL:
						"https://snippet.dhtmlx.com/codebase/data/kanban/01/img/img-1.jpg",
					previewURL:
						"https://snippet.dhtmlx.com/codebase/data/kanban/01/img/img-1.jpg",
					url: "https://snippet.dhtmlx.com/codebase/data/kanban/01/img/img-1.jpg",
					name: "img-1.jpg",
				},
			],
		},
		{
			label: "Custom icons",
			color: "#65D3B3",
			start_date: new Date("01/07/2021"),
			users: [3, 2],
			column: "inprogress",
			type: "task",
		},
		{
			label: "Integration with Gantt",
			color: "#FFC975",
			start_date: new Date("12/21/2020"),
			users: [4],
			progress: 75,
			column: "inprogress",
			type: "task",
		},
		{
			label: "Drag and drop",
			priority: 1,
			color: "#58C3FE",
			users: [3, 1],
			progress: 100,
			column: "testing",
			type: "feature",
		},
		{
			label: "Adding images",
			color: "#58C3FE",
			users: [4],
			column: "testing",
			type: "task",
			attached: [
				{
					isCover: true,
					coverURL:
						"https://snippet.dhtmlx.com/codebase/data/kanban/01/img/img-2.jpg",
					previewURL:
						"https://snippet.dhtmlx.com/codebase/data/kanban/01/img/img-2.jpg",
					url: "https://snippet.dhtmlx.com/codebase/data/kanban/01/img/img-2.jpg",
					name: "img-2.jpg",
				},
			],
		},
		{
			label: "Create cards and lists from the UI and from code",
			priority: 3,
			color: "#65D3B3",
			start_date: new Date("01/07/2021"),
			users: [3, 2],
			column: "done",
			type: "feature",
		},
		{
			label: "Draw swimlanes",
			color: "#FFC975",
			users: [2],
			column: "done",
			type: "feature",
		},
		{
			label: "Progress bar",
			priority: 1,
			color: "#FFC975",
			start_date: new Date("12/9/2020"),
			users: [1, 4, 3],
			progress: 100,
			column: "done",
			type: "task",
		},
	];
</script>

The code configures the Toolbar with a custom items array that includes: a function returning HTML for a logo, a search control with custom options (search by label or by date with a custom searchRule), a "spacer" to push remaining items right, a sort control with a label-based sort option, the built-in "addRow" and "addColumn" items, and a raw HTML string with a custom "Add card" button. The date search uses a custom searchRule function that converts the date to a string before matching.

Solution overview

  1. Pass items array to the Toolbar constructor
  2. Use functions () => "<html>" for dynamic custom elements
  3. Use { type: "search", options: [...] } with custom searchRule functions for non-string fields
  4. Use { type: "sort", options: [...] } for sort options
  5. Mix in built-in items like "spacer", "addRow", "addColumn"
  6. Use raw HTML strings for custom buttons, wiring them up with addEventListener

Key points

  • searchRule for non-string fields: The default search compares strings. For dates or other types, provide a searchRule(card, value, by) function that handles the comparison
  • Item forms: Toolbar items can be built-in name strings ("addColumn"), configuration objects ({ type: "search" }), functions returning an HTML string (() => "<div>..."), or raw HTML string literals
  • "spacer" for layout: Insert "spacer" to push subsequent items to the right side of the toolbar
  • Custom buttons need manual wiring: HTML string items don't auto-bind to Kanban actions. Use addEventListener after toolbar creation

API reference

Additional resources