Commit acdcaf88 authored by Carsten  Rose's avatar Carsten Rose
Browse files

Merge branch 'F1261-tablesorter' into 'master'

Feature #1261 - Tablesorter, incl. saved sort, combined column sort, filters, pagination

See merge request !81

refs #1261
parents 17341efd 01c1e7be
Pipeline #890 passed with stage
in 1 minute and 37 seconds
......@@ -132,7 +132,9 @@ module.exports = function (grunt) {
{
cwd: 'node_modules/tablesorter/dist/js/',
src: [
'jquery.tablesorter.min.js'
'jquery.tablesorter.combined.min.js',
'extras/jquery.tablesorter.pager.min.js',
'widgets/widget-columnSelector.min.js'
],
expand: true,
dest: typo3_js,
......@@ -141,9 +143,9 @@ module.exports = function (grunt) {
{
cwd: 'node_modules/tablesorter/dist/js/',
src: [
'jquery.tablesorter.min.js',
'jquery.tablesorter.widgets.min.js',
'widgets/widget-grouping.min.js'
'jquery.tablesorter.combined.min.js',
'extras/jquery.tablesorter.pager.min.js',
'widgets/widget-columnSelector.min.js'
],
expand: true,
dest: 'js/',
......@@ -517,7 +519,7 @@ module.exports = function (grunt) {
"extension/Resources/Public/Css/qfq-bs.css": "less/qfq-bs.css.less",
"extension/Resources/Public/Css/qfq-letter.css": "less/qfq-letter.css.less",
"extension/Resources/Public/Css/qfq-plain.css": "less/qfq-plain.css.less",
"extension/Resources/Public/Css/bs-tablesorter.css": "less/bs-tablesorter.less"
"extension/Resources/Public/Css/tablesorter-bootstrap.css": "less/tablesorter-bootstrap.less"
},
options: {
compress: true
......@@ -528,7 +530,7 @@ module.exports = function (grunt) {
"css/qfq-bs.css": "less/qfq-bs.css.less",
"css/qfq-letter.css": "less/qfq-letter.css.less",
"css/qfq-plain.css": "less/qfq-plain.css.less",
"css/bs-tablesorter.css": "less/bs-tablesorter.less"
"css/tablesorter-bootstrap.css": "less/tablesorter-bootstrap.less"
},
options: {
banner: "/* Change qfq-bs.css.less, not qfq-bs.css */"
......
......@@ -203,6 +203,9 @@ Setup CSS & JS
file3 = typo3conf/ext/qfq/Resources/Public/Css/jqx.base.css
file4 = typo3conf/ext/qfq/Resources/Public/Css/jqx.bootstrap.css
file5 = typo3conf/ext/qfq/Resources/Public/Css/qfq-bs.css
# Needed for tablesorter
file6 = typo3conf/ext/qfq/Resources/Public/Css/tablesorter-bootstrap.css
}
page.includeJS {
......@@ -219,6 +222,11 @@ Setup CSS & JS
# Only needed in case FormElement 'annotate' is used.
file10 = typo3conf/ext/qfq/Resources/Public/JavaScript/fabric.min.js
file11 = typo3conf/ext/qfq/Resources/Public/JavaScript/qfq.fabric.min.js
# Needed for tablesorter
file12 = typo3conf/ext/qfq/Resources/Public/JavaScript/jquery.tablesorter.combined.min.js
file13 = typo3conf/ext/qfq/Resources/Public/JavaScript/jquery.tablesorter.pager.min.js
file14 = typo3conf/ext/qfq/Resources/Public/JavaScript/widget-columnSelector.min.js
}
......@@ -6763,6 +6771,56 @@ E.g.::
10.sql = SELECT "p:home&r=0|t:Home|c:qfq-100 qfq-left" AS _pagev
Tablesorter
-----------
QFQ includes a third-party client-side table sorter. tablesorter 2.31.0 is used, see official docs here: https://mottie.github.io/tablesorter/docs/index.html
To turn any table into a sortable table, use this simple setup:
* Ensure that your QFQ installation is importing the appropriate js/css files, see setup-css-js_.
* Add the `class="tablesorter"` to your `<table>` element.
* Make sure your `<table>` has a `<thead>` and `<tbody>`.
In addition to the *tablesorter* class, there are the following additional options:
* Adding the class `tablesorter-filter` enables table filtering.
* Adding the class `tablesorter-pager` adds table paging functionality. With this option the html for the page navigation
is dynamically injected.
* Adding the class `tablesorter-column-selector` adds a column selector widget. With this option the html for the column
selector is dynamically injected.
For additional customization there are the following options:
* Add the desired classes or data attributes to your table html, e.g.:
* `data-sorter="false"` on a <th> to disable sorting on that column
* `class="filter-false"` on a <th> to hide the filter field for that column
* see docs for more options: https://mottie.github.io/tablesorter/docs/index.html
* You can pass in a default configuration object for the main `tablesorter()` function by using the attribute
`data-tablesorter-config` on the table.
Use JSON syntax when passing in your own configuration, such as:
data-tablesorter-config='{"theme":"bootstrap","widthFixed":true,"headerTemplate":"{content} {icon}","dateFormat":"ddmmyyyy","widgets":["uitheme","filter","saveSort","columnSelector"],"widgetOptions":{"filter_columnFilters":true,"filter_reset":".reset","filter_cssFilter":"form-control","columnSelector_mediaquery":false} }'
* If the above customization options are not enough, you can output your own HTML for the pager and/or column selector,
as well as your own `$(document).ready()` function with the desired config. In this case, it is recommended not to
use the above *tablesorter* classes since the QFQ javascript code could interfere with your javascript code.
Example: ::
10 {
sql = SELECT id, CONCAT('form&form=person&r=', id) AS _Pagee, lastName, title FROM person
head = <table class="table tablesorter tablesorter-filter tablesorter-pager tablesorter-column-selector">
<thead><tr><th>Id</th><th data-sorter="false" class="filter-false">Edit</th>
<th>Name</th><th class="filter-select" data-placeholder="Select a title">Title</th>
</tr></thead><tbody>
tail = </tbody></table>
rbeg = <tr>
rend = </tr>
fbeg = <td>
fend = </td>
}
.. _monitor:
Monitor
......
/**
* @author Elias Villiger <elias.villiger@uzh.ch>
*/
/* global $ */
/* global EventEmitter */
/* @depend QfqEvents.js */
$(document).ready( function () {
$.tablesorter.themes.bootstrap.table = "";
$('.tablesorter').each(function(i) {
var hasFilter = $(this).hasClass('tablesorter-filter');
var hasPager = $(this).hasClass('tablesorter-pager');
var hasColumnSelector = $(this).hasClass('tablesorter-column-selector');
var columnSelectorId = "qfq-column-selector-" + i;
var columnSelectorTargetId = "qfq-column-selector-target-" + i;
var pagerId = "qfq-pager-" + i;
var tablesorterConfig = $(this).data("tablesorterConfig");
if (!tablesorterConfig) { // revert to default
tablesorterConfig = {
theme: "bootstrap",
widthFixed: true,
headerTemplate: "{content} {icon}",
dateFormat: "ddmmyyyy",
widgets: ["uitheme", "filter", "saveSort", "columnSelector"],
widgetOptions: {
filter_columnFilters: hasFilter, // turn filters on/off with true/false
filter_reset: ".reset",
filter_cssFilter: "form-control",
columnSelector_mediaquery: false
} };
}
$(this).tablesorter(tablesorterConfig);
if (hasColumnSelector) {
var columnSelectorHtml = '<button id="' + columnSelectorId + '" class="btn btn-default qfq-column-selector" ' +
'type="button" style="float:right;">' +
'<span class="dropdown-text"><span class="icon glyphicon glyphicon-th-list"></span></span>' +
'<span class="caret"></span></button>' +
'<div class="hidden"><div id="' + columnSelectorTargetId + '" class="qfq-column-selector-target"> </div></div>';
$(columnSelectorHtml).insertBefore($(this));
$.tablesorter.columnSelector.attachTo($(this), '#' + columnSelectorTargetId);
$('#' + columnSelectorId).popover({
placement: 'left',
html: true, // required if content has HTML
content: $('#' + columnSelectorTargetId)
});
}
if (hasPager) {
var pagerHtml = '<div id="' + pagerId + '" class="form-inline" style="margin-top:-20px; margin-bottom:20px;">' +
'<div class="btn-group btn-group-sm" role="group">' +
'<button type="button" class="btn btn-default first"><span class="glyphicon glyphicon-step-backward"></span></button>' +
'<button type="button" class="btn btn-default prev"><span class="glyphicon glyphicon-backward"></span></button>' +
'</div><span class="pagedisplay"></span>' +
'<div class="btn-group btn-group-sm" role="group">' +
'<button type="button" class="btn btn-default next"><span class="glyphicon glyphicon-forward"></span></button>' +
'<button type="button" class="btn btn-default last"><span class="glyphicon glyphicon-step-forward"></span></button>' +
'</div>' +
'<select class="form-control input-sm pagesize" title="Select page size">' +
'<option selected="selected" value="10">10</option>' +
'<option value="25">25</option>' +
'<option value="50">50</option>' +
'<option value="100">100</option>' +
'<option value="all">All Rows</option>' +
'</select>' +
'<select class="form-control input-sm pagenum" title="Select page number"></select>' +
'</div>';
$(pagerHtml).insertAfter($(this));
$(this).tablesorterPager({
container: $("#" + pagerId),
cssGoto: ".pagenum",
removeRows: false,
output: '{startRow} - {endRow} / {filteredRows}'
});
}
}); // end .each()
} );
\ No newline at end of file
/* Tablesorter Custom LESS Theme by Rob Garrison
To create your own theme, modify the code below and run it through
a LESS compiler, like this one: http://leafo.net/lessphp/editor.html
or download less.js from http://lesscss.org/
Test out these custom less files live
Basic Theme : http://codepen.io/Mottie/pen/eqBbn
Bootstrap : http://codepen.io/Mottie/pen/Ltzpi
Metro Style : http://codepen.io/Mottie/pen/gCslk
*/
/*** theme ***/
@theme : tablesorter-bootstrap;
/*** fonts ***/
@tableHeaderFont : inherit;
@tableBodyFont : inherit;
/*** color definitions ***/
/* for best results, only change the hue (120),
leave the saturation (60%) and luminosity (75%) alone
pick the color from here: http://hslpicker.com/#99E699 */
@headerBackground : white;
@borderAndBackground : #cdcdcd;
@overallBorder : inherit;
@headerTextColor : #000;
@bodyBackground : #fff;
@bodyTextColor : #000;
@headerAsc : darken(spin(@headerBackground, 5), 10%);
/* darken(@headerBackground, 10%); */
@headerDesc : lighten(spin(@headerBackground, -5), 10%);
/* desaturate(@headerAsc, 5%); */
@captionBackground : #fff;
/* it might be best to match the document body background color here */
@errorBackground : #e6bf99;
/* ajax error message (added to thead) */
@filterCellBackground : #eee;
@filterElementTextColor: #333;
@filterElementBkgd : #fff;
@filterElementBorder : 1px solid #bbb;
@filterTransitionTime : 0.1s;
@filterRowHiddenHeight : 4px;
/* becomes height using padding (so it's divided by 2) */
@overallPadding : inherit;
/* 20px should be slightly wider than the icon width to avoid overlap */
@headerPadding : inherit;
/* url(icons/loading.gif); */
@processingIcon : url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=');
/* zebra striping */
.allRows {
background-color: @bodyBackground;
color: @bodyTextColor;
}
.evenRows {
background-color: lighten(@headerBackground, 40%);
color: @bodyTextColor;
}
.oddRows {
background-color: lighten(@headerBackground, 20%);
}
/* hovered rows */
.oddHovered {
background-color: desaturate(@headerBackground, 60%);
color: @bodyTextColor;
}
.evenHovered {
background-color: lighten(desaturate(@headerBackground, 60%), 10%);
color: @bodyTextColor;
}
/* Columns widget */
@primaryOdd : spin(@headerBackground, 10);
/* saturate( darken( desaturate(@headerBackground, 10%), 10% ), 30%); */
@primaryEven : lighten(@primaryOdd, 10%);
@secondaryOdd : @primaryEven;
@secondaryEven : lighten(@primaryEven, 5%);
@tertiaryOdd : @secondaryEven;
@tertiaryEven : lighten(@secondaryEven, 5%);
/* Filter widget transition */
.filterWidgetTransition {
-webkit-transition: line-height @filterTransitionTime ease;
-moz-transition: line-height @filterTransitionTime ease;
-o-transition: line-height @filterTransitionTime ease;
transition: line-height @filterTransitionTime ease;
}
/*** Arrows ***/
@arrowPosition : right 5px center;
/* black */
@unsortedBlack : url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);
@sortAscBlack : url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
@sortDescBlack : url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
/* white */
@unsortedWhite : url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);
@sortAscWhite : url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
@sortDescWhite : url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
/* automatically choose the correct arrow/text color */
.headerText (@a) when (lightness(@a) >= 50%) {
color: @headerTextColor;
}
.headerText (@a) when (lightness(@a) < 50%) {
color: lighten(@headerTextColor, 90%);
}
.unsorted (@a) when (lightness(@a) >= 50%) {
background-image: @unsortedBlack;
}
.unsorted (@a) when (lightness(@a) < 50%) {
background-image: @unsortedWhite;
}
.sortAsc (@a) when (lightness(@a) >= 50%) {
background-image: @sortAscBlack;
}
.sortAsc (@a) when (lightness(@a) < 50%) {
background-image: @sortAscWhite;
}
.sortDesc (@a) when (lightness(@a) >= 50%) {
background-image: @sortDescBlack;
}
.sortDesc (@a) when (lightness(@a) < 50%) {
background-image: @sortDescWhite;
}
/* variable theme name - requires less.js 1.3+;
or just replace (!".@{theme}") with the contents of @theme
*/
.@{theme} {
/* style header */
.tablesorter-header {
.unsorted(@headerBackground);
background-repeat: no-repeat;
background-position: @arrowPosition;
cursor: pointer;
}
.tablesorter-header.sorter-false {
background-image: none;
cursor: default;
}
.tablesorter-headerAsc {
background-color: @headerAsc;
.sortAsc(@headerBackground);
}
.tablesorter-headerDesc {
background-color: @headerDesc;
.sortDesc(@headerBackground);
}
/* tfoot */
tfoot .tablesorter-headerAsc,
tfoot .tablesorter-headerDesc {
/* remove sort arrows from footer */
background-image: none;
}
/* optional disabled input styling */
.disabled {
opacity: 0.5;
filter: alpha(opacity=50);
cursor: not-allowed;
}
/* body */
tbody {
td {
.allRows;
}
/* Zebra Widget - row alternating colors */
tr.odd > td {
.oddRows;
}
tr.even > td {
.evenRows;
}
tr.group-hidden {
display: none;
}
tr.group-header {
td {
i {
display: inline-block;
width: 0;
height: 0;
border-top: 4px solid transparent;
border-bottom: 4px solid #888;
border-right: 4px solid #888;
border-left: 4px solid transparent;
margin-right: 7px;
user-select: none;
-moz-user-select: none;
}
}
}
tr.group-header.collapsed {
td {
i {
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 5px solid #888;
border-right: 0;
margin-right: 10px;
}
}
}
}
/* hovered row colors
you'll need to add additional lines for
rows with more than 2 child rows
*/
tbody > tr.hover td,
tbody > tr:hover td,
tbody > tr:hover + tr.tablesorter-childRow > td,
tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td,
tbody > tr.even.hover > td,
tbody > tr.even:hover > td,
tbody > tr.even:hover + tr.tablesorter-childRow > td,
tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
.evenHovered;
}
tbody > tr.odd.hover > td,
tbody > tr.odd:hover > td,
tbody > tr.odd:hover + tr.tablesorter-childRow > td,
tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
.oddHovered;
}
/* table processing indicator - indeterminate spinner */
.tablesorter-processing {
background-image: @processingIcon;
background-position: center center;
background-repeat: no-repeat;
}
/* Column Widget - column sort colors */
tr.odd td.primary {
background-color: @primaryOdd;
}
td.primary, tr.even td.primary {
background-color: @primaryEven;
}
tr.odd td.secondary {
background-color: @secondaryOdd;
}
td.secondary, tr.even td.secondary {
background-color: @secondaryEven;
}
tr.odd td.tertiary {
background-color: @tertiaryOdd;
}
td.tertiary, tr.even td.tertiary {
background-color: @tertiaryEven;
}
/* caption (non-theme matching) */
caption {
background-color: @captionBackground;
}
/* filter widget */
.tablesorter-filter-row input,
.tablesorter-filter-row select {
width: 98%;
height: auto;
margin: 0;
padding: @overallPadding;
color: @filterElementTextColor;
background-color: @filterElementBkgd;
border: @filterElementBorder;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
.filterWidgetTransition;
}
.tablesorter-filter-row {
background-color: @filterCellBackground;
}
.tablesorter-filter-row td {
text-align: center;
background-color: @filterCellBackground;
line-height: normal;
text-align: center; /* center the input */
.filterWidgetTransition;
}
/* hidden filter row */
.tablesorter-filter-row.hideme td {
padding: @filterRowHiddenHeight / 2;
margin: 0;
line-height: 0;
cursor: pointer;
}
.tablesorter-filter-row.hideme * {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* rows hidden by filtering (needed for child rows) */
.filtered {
display: none;
}
/* ajax error row */
.tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: @errorBackground;
}
}
/* Based on Tablesorter Custom Bootstrap v3 LESS Theme by Rob Garrison
Modified into minimal bootstrap theme by Elias Villiger
To create your own theme, modify the code below and run it through
a LESS compiler, like this one: http://leafo.net/lessphp/editor.html
or download less.js from http://lesscss.org/
Test out these customization files live
Basic LESS Theme : http://codepen.io/Mottie/pen/eqBbn
Bootstrap LESS : http://codepen.io/Mottie/pen/Ltzpi
Metro LESS Style : http://codepen.io/Mottie/pen/gCslk
Basic SCSS : http://codepen.io/Mottie/pen/LbXdNR
*/
/*** theme ***/
@theme : tablesorter-bootstrap;
/*** fonts ***/
//@tableHeaderFont : 14px bold Arial, Sans-serif;
//@tableBodyFont : 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
/*** color definitions ***/
/* for best results, only change the hue (240),
leave the saturation (60%) and luminosity (80%) alone
pick the color from here: http://hslpicker.com/#99E699 */
//@headerBackground : hsl(240, 60%, 80%);
//@borderAndBackground : #cdcdcd;
//@overallBorder : @borderAndBackground 1px solid;
//@headerTextColor : #000;
//
//@bodyBackground : #fff;
//@bodyTextColor : #000;
//@headerAsc : darken(spin(@headerBackground, 5), 10%); /* darken(@headerBackground, 10%); */
//@headerDesc : lighten(spin(@headerBackground, -5), 10%); /* desaturate(@headerAsc, 5%); */
@captionBackground : #fff; /* it might be best to match the document body background color here */
@errorBackground : #e6bf99; /* ajax error message (added to thead) */
//@filterCellBackground : #eee;
//@filterElementTextColor: #333;
//@filterElementBkgd : #fff;
//@filterElementBorder : 1px solid #bbb;
@filterTransitionTime : 0.1s;
@filterRowHiddenHeight : 4px; /* becomes height using padding (so it's divided by 2) */
//@overallPadding : 4px;
/* 20px should be slightly wider than the icon width to avoid overlap */
@headerPadding : 0px 18px 0px 0px;
@headerMargin : 0 0 18px;
/* url(icons/loading.gif); */
@processingIcon : url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=');
/* zebra striping */
//.allRows {
// background-color: @bodyBackground;
// color: @bodyTextColor;
//}
//.evenRows {
// background-color: lighten(@headerBackground, 35%);
//}
//.oddRows {
// background-color: lighten(@headerBackground, 18%);
//}
/* hovered rows */
//.oddHovered {
// background-color: desaturate(@headerBackground, 60%);
//}
//.evenHovered {
// background-color: lighten( desaturate(@headerBackground, 60%), 10% );
//}
/* Columns widget */
//@primaryOdd : spin(@headerBackground, 10); /* saturate( darken( desaturate(@headerBackground, 10%), 10% ), 30%); */
//@primaryEven : lighten( @primaryOdd, 10% );
//@secondaryOdd : @primaryEven;
//@secondaryEven : lighten( @primaryEven, 5% );
//@tertiaryOdd : @secondaryEven;
//@tertiaryEven : lighten( @secondaryEven, 5% );
/* Filter widget transition */
.filterWidgetTransition {
-webkit-transition: line-height @filterTransitionTime ease;
-moz-transition: line-height @filterTransitionTime ease;
-o-transition: line-height @filterTransitionTime ease;
transition: line-height @filterTransitionTime ease;
}