Overview
Hide the built-in sort icon for selected columns, but keep the column sortable using the API.
Use custom sort icons from Font Awesome.
Customize the sort icon behavior.
Includes a trial version of DayPilot Pro for JavaScript (see License below)
License
Licensed for testing and evaluation purposes. Please see the license agreement included in the sample project. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for JavaScript.
Live Demo
Row Sorting Cofiguration
We are going to display two columns in the row header of the JavaScript Scheduler component:
Name
Capacity
The columns are defined using rowHeaderColumns property. The array items specify the column title (name), column content field name (display) and field used for sorting (sort).
This enables row sorting using the built-in sort icons.
dp.resources = [
{name: "Resource 1", id: "R1", capacity: 10},
{name: "Resource 2", id: "R2", capacity: 5},
{name: "Resource 3", id: "R3", capacity: 15},
{name: "Resource 4", id: "R4", capacity: 20},
{name: "Resource 5", id: "R5", capacity: 10},
{name: "Resource 6", id: "R6", capacity: 30},
{name: "Resource 7", id: "R7", capacity: 10},
{name: "Resource 8", id: "R8", capacity: 20},
{name: "Resource 9", id: "R9", capacity: 15},
];
dp.rowHeaderColumns = [
{name: "Name", display: "name", sort: "name", width: 100},
{name: "Capacity", display: "capacity", sort: "capacity"},
];
Hiding the Sort Icon
It is possible to hide the built-in sort icon for specified columns using onBeforeRowHeaderColumnRender event handler.
The following example hides the sort icon for the "Capacity" column:
dp.onBeforeRowHeaderColumnRender = function(args) {
if (args.column.data.name === "Capacity") {
args.column.sortingEnabled = false;
}
};
The demo project uses a checkbox which lets you change the sort icon visibility on the fly:
HTML
<label><input type="checkbox" id="allowCapacity" checked>Allow sorting by "Capacity"</label>
<div id="dp"></div>
JavaScript
var elements = {
allowCapacity: document.getElementById("allowCapacity"),
customIcons: document.getElementById("customIcons"),
};
elements.allowCapacity.addEventListener("click", function() {
dp.update();
});
// ...
dp.onBeforeRowHeaderColumnRender = function(args) {
if (args.column.data.name === "Capacity") {
args.column.sortingEnabled = !elements.disableCapacity.checked;
}
};
Custom Icons and Sort Logic
You can also use the onBeforeRowHeaderColumnRender event handler to display a custom sort icon.
First, it is necessary to hide the default sort icon:
dp.onBeforeRowHeaderColumnRender = function(args) {
args.column.sortingEnabled = false;
// ...
};
Now you can define your own icons using active areas. The active areas support font icons using icon property so we can use a sorting icon from Font Awesome easily (fa-sort).
dp.onBeforeRowHeaderColumnRender = function(args) {
var useCustomIcons = elements.customIcons.checked;
if (useCustomIcons) {
args.column.sortingEnabled = false;
args.column.areas = [
{
right: 4,
top: 10,
height: 17,
width: 10,
icon: "fa fa-sort",
style: "cursor: pointer",
onClick: function() {
dp.rows.sort({
field: args.column.data.sort,
order: (dp.rows.sortParam.field === args.column.data.sort && dp.rows.sortParam.order === "asc") ? "desc": "asc"
});
}
}
];
}
};
Full Source Code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>JavaScript Scheduler: Row Sorting Customization</title>
<style type="text/css">
// ...
</style>
<style>
input[type=checkbox], input[type=radio] {
vertical-align: middle;
position: relative;
bottom: .08em;
}
</style>
<!-- DayPilot library -->
<script src="js/daypilot/daypilot-all.min.js"></script>
<!-- font awesome -->
<link type="text/css" rel="stylesheet" href="fa-5.9.0/css/all.min.css" />
</head>
<body>
<div class="header">
<h1><a href='https://code.daypilot.org/43915/javascript-scheduler-row-sorting-customization'>JavaScript Scheduler: Row Sorting Customization</a></h1>
<div><a href="https://javascript.daypilot.org/">DayPilot for JavaScript</a> - HTML5 Calendar/Scheduling Components for JavaScript/Angular/React</div>
</div>
<div class="main">
<div class="space">
<label><input type="checkbox" id="disableCapacity">Disable sorting by "Capacity"</label>
<label><input type="checkbox" id="customIcons" >Use custom icons</label>
</div>
<div id="dp"></div>
<div class="generated">Generated using <a href="https://builder.daypilot.org/">DayPilot UI Builder</a>.</div>
</div>
<script>
var elements = {
disableCapacity: document.getElementById("disableCapacity"),
customIcons: document.getElementById("customIcons"),
};
elements.disableCapacity.addEventListener("click", function() {
dp.update();
});
elements.customIcons.addEventListener("click", function() {
var useCustomIcons = elements.customIcons.checked;
elements.disableCapacity.disabled = useCustomIcons;
if (useCustomIcons) {
elements.disableCapacity.checked = false;
}
dp.update();
});
</script>
<script>
var dp = new DayPilot.Scheduler("dp", {
timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
scale: "Day",
days: DayPilot.Date.today().daysInMonth(),
startDate: DayPilot.Date.today().firstDayOfMonth(),
timeRangeSelectedHandling: "Enabled",
onTimeRangeSelected: function (args) {
var dp = this;
DayPilot.Modal.prompt("Create a new event:", "Event 1").then(function(modal) {
dp.clearSelection();
if (!modal.result) { return; }
dp.events.add(new DayPilot.Event({
start: args.start,
end: args.end,
id: DayPilot.guid(),
resource: args.resource,
text: modal.result
}));
});
},
treeEnabled: true,
});
dp.resources = [
{name: "Resource 1", id: "R1", capacity: 10},
{name: "Resource 2", id: "R2", capacity: 5},
{name: "Resource 3", id: "R3", capacity: 15},
{name: "Resource 4", id: "R4", capacity: 20},
{name: "Resource 5", id: "R5", capacity: 10},
{name: "Resource 6", id: "R6", capacity: 30},
{name: "Resource 7", id: "R7", capacity: 10},
{name: "Resource 8", id: "R8", capacity: 20},
{name: "Resource 9", id: "R9", capacity: 15},
];
dp.events.list = [];
dp.rowHeaderColumns = [
{name: "Name", display: "name", sort: "name", width: 100},
{name: "Capacity", display: "capacity", sort: "capacity"},
];
dp.onBeforeRowHeaderColumnRender = function(args) {
var useCustomIcons = elements.customIcons.checked;
if (useCustomIcons) {
args.column.sortingEnabled = false;
args.column.areas = [
{
right: 4,
top: 10,
height: 17,
width: 10,
icon: "fa fa-sort",
style: "cursor: pointer",
onClick: function() {
dp.rows.sort({
field: args.column.data.sort,
order: (dp.rows.sortParam.field === args.column.data.sort && dp.rows.sortParam.order === "asc") ? "desc": "asc"
});
}
}
];
}
else {
if (args.column.data.name === "Capacity") {
args.column.sortingEnabled = !elements.disableCapacity.checked;
}
}
};
dp.init();
</script>
</body>
</html>