Created | ![]() |
Favourites | Opened | Upvotes | Comments |
2. May 2020 | 1 | 0 | 426 | 0 | 0 |
My favourite Sort UX is the stacked up-down arrows.
Unified ascending & descending sort in a single UX unit renders itself particulary handy in case of tabular data with multiple sortable columns.
Here I show how to create the stacked Sort UX using FontAwesome for the arrow symbols & Javascript for the mouse events altering the arrow symbol colors to signify sort action & sort state.
Note that here I only create the Sort UX, for code to actually sort see Sort Arrays in Javascript.
I can think of 3 methods to create the above sorting UX :
Here I will use the FontAwesome PRO duo-tone icon, "fad fa-sort", because it exist of 2 layers, which easily can be individually manipulated :
Since the FontAwesome icon itself is 2 layered, we cannot directly attach mouse events to the layers, instead I will create 2 absolute positioned divs, 1 div on top of each arrow - I then register mouse events on these divs and manipulate the FontAwesome icon depending on which absolute div the mouse event fired.
First here is the HTML markup of a single Sort UX :
<div id="divSortContainer">
<i id="iconSort" class="fad fa-sort" style="--fa-primary-color: #ccc;--fa-secondary-color: #ccc;--fa-secondary-opacity: 1.0;"></i>
<div id="btnSortUp" onclick="Sorting.sort('up')" onmouseover="Sorting.mouseover(this)" onmouseout="Sorting.mouseout(this)"></div>
<div id="btnSortDown" onclick="Sorting.sort('down')" onmouseover="Sorting.mouseover(this)" onmouseout="Sorting.mouseout(this)"></div>
</div>
The HTML consist of :
While I set the initial icon styles inline, the rest of the Sort UX styles I set using a style sheet :
<style>
#divSortContainer {
position: relative; // to create a parent for the absolute positioned divs
display: inline-block; // to fit perfectly around the font
font-size: 48px;
width: 27px; // must fit the font width
height: 48px; // must fit the font height
}
#btnSortUp {
position:absolute; // don't create space in the natural flow
width: 27px; // must fit the font width
height: 24px; // must fit half the font height
left: 0;
top: 0; // must expand the top half of the font
}
#btnSortDown {
position: absolute;
width: 27px;
height: 24px;
left: 0;
top: 26px; // must expand the bottom half of the font
}
</style>
The Sort UX is now structurally created, however to make it come alive with mouse events, we need some Javascript :
<script>
var Sorting = {
CurrentSort: {}, // keeps the sorting state
mouseover: function (btnSort) {
var btnId = btnSort.getAttribute("id");
var iconSort = document.querySelector("#iconSort");
var colorUp = this.CurrentSort.sortDirection == "up" ? "red" : btnId == "btnSortUp" ? "red" : "#ccc";
var colorDown = this.CurrentSort.sortDirection == "down" ? "red" : btnId == "btnSortDown" ? "red" : "#ccc";
iconSort.setAttribute("style", "--fa-primary-color:" + colorUp + ";--fa-secondary-color:" + colorDown + ";--fa-secondary-opacity:1.0;");
},
mouseout: function (btnSort) {
var btnId = btnSort.getAttribute("id");
var iconSort = document.querySelector("#iconSort");
var colorUp = this.CurrentSort.sortDirection == "up" ? "red" : "#ccc";
var colorDown = this.CurrentSort.sortDirection == "down" ? "red" : "#ccc";
iconSort.setAttribute("style", "--fa-primary-color:" + colorUp + ";--fa-secondary-color:" + colorDown + ";--fa-secondary-opacity:1.0;");
},
sort: function (sortDirection) {
var iconSort = document.querySelector("#iconSort");
if (sortDirection == "up") {
// .. do the ascending sort ..
this.CurrentSort.sortDirection = "up";
iconSort.setAttribute("style", "--fa-primary-color:red;--fa-secondary-color:#ccc;--fa-secondary-opacity:1.0;");
}
else { // sortDirection == "down"
// .. do the descending sort
this.CurrentSort.sortDirection = "down";
iconSort.setAttribute("style", "--fa-primary-color:#ccc;--fa-secondary-color:red;--fa-secondary-opacity:1.0;");
}
}
}
</script>
Ok, the Sort UX is finished. To actually do some sorting with this UX, see Sort Arrays in Javascript.