From 8086b76f3a1c07d14930b12dd0316f489ac74ce0 Mon Sep 17 00:00:00 2001 From: Martin Bohal Date: Tue, 26 Jul 2016 14:35:26 +0200 Subject: [PATCH 1/2] Make sortable-table use locale aware sorting if supported --- src/js/sortable-table.js | 8 ++- src/js/tests/unit/sortable-table.js | 66 +++++++++++++++++++ .../components/javascript/sortable-table.less | 7 +- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/js/sortable-table.js b/src/js/sortable-table.js index b96d4c9e..5f894623 100644 --- a/src/js/sortable-table.js +++ b/src/js/sortable-table.js @@ -98,7 +98,13 @@ if ($.isNumeric(valA) && $.isNumeric(valB)) { result = valA - valB; } else { - result = valA.localeCompare(valB); + try { + result = valA.localeCompare(valB, $('html').attr('lang')); + } catch (err) { + if (err instanceof RangeError) { + result = valA.localeCompare(valB); + } + } } return sortDir === 'desc' ? result * -1 : result; diff --git a/src/js/tests/unit/sortable-table.js b/src/js/tests/unit/sortable-table.js index da21ff6a..cbb16f55 100644 --- a/src/js/tests/unit/sortable-table.js +++ b/src/js/tests/unit/sortable-table.js @@ -17,6 +17,7 @@ $(function () { teardown: function () { $.fn.sortableTable = $.fn.buiSortableTable; delete $.fn.buiSortableTable; + $('html').attr('lang', null); }, }); @@ -447,6 +448,71 @@ $(function () { } ); + QUnit.test('should sort with invalid html language', function () { + var $table = $('' + + '' + + '' + + '' + + '' + + '' + + '' + + '
HeaderA
šb
sa
sc
'); + + QUnit.stop(); + $('html').attr('lang', 'some-invalid-language-code'); + $table.on('sorted.bui.sortableTable', function () { + var $rows = $(this).find('tbody tr'); + $(this).off('sorted.bui.sortableTable'); + QUnit.ok($($rows[0]).attr('id') === 'row2'); + QUnit.ok($($rows[1]).attr('id') === 'row1'); + QUnit.ok($($rows[2]).attr('id') === 'row3'); + QUnit.start(); + }) + .buiSortableTable({ 'sorted-th': $(this).find('#headerA'), 'sort-direction': 'asc' }); + }); + + QUnit.test('should sort based on html language ', function () { + var $table = $('' + + '' + + '' + + '' + + '' + + '' + + '' + + '
HeaderA
šb
sa
sc
'); + + QUnit.stop(); + $('html').attr('lang', 'cs'); + $table.on('sorted.bui.sortableTable', function () { + var $rows = $(this).find('tbody tr'); + var validateNoLocale = function ($rows) { + QUnit.ok($($rows[0]).attr('id') === 'row2'); + QUnit.ok($($rows[1]).attr('id') === 'row1'); + QUnit.ok($($rows[2]).attr('id') === 'row3'); + }; + + $(this).off('sorted.bui.sortableTable'); + + // Test should pass regardless weather browser supports locales + // https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#Check_browser_support_for_extended_arguments + try { + 'foo'.localeCompare('bar', 'i'); + validateNoLocale($rows); + } catch (err) { + if (err instanceof RangeError) { + QUnit.ok($($rows[0]).attr('id') === 'row2'); + QUnit.ok($($rows[1]).attr('id') === 'row3'); + QUnit.ok($($rows[2]).attr('id') === 'row1'); + } else { + validateNoLocale($rows); + } + } + + QUnit.start(); + }) + .buiSortableTable({ 'sorted-th': $(this).find('#headerA'), 'sort-direction': 'asc' }); + }); + // Data-api tests // ============== QUnit.test('should order table by the column whoms element was clicked', function () { diff --git a/src/less/components/javascript/sortable-table.less b/src/less/components/javascript/sortable-table.less index dba3cdd2..52e1e6f5 100644 --- a/src/less/components/javascript/sortable-table.less +++ b/src/less/components/javascript/sortable-table.less @@ -1,8 +1,11 @@ /* Sortable Table -Provides client-side sorting functionality. To ensure keyboard accessibility, remember to add `tabindex="0"` to all -sortable column headers. +Provides client-side sorting functionality. If browser supports language argument to the +`String.prototype.localeCompare()` function, the ordering will be locale aware. +If the argument is not supported or if the supplied argument is not a valid locale the ordering will not be locale aware. + +To ensure keyboard accessibility, remember to add `tabindex="0"` to all sortable column headers. If a given cell has the attribute `data-sort-value="someValue"` specified, the value of this element is used as opposed to the value of the cell. From c93c20c80fd28fce71d9de6af423fa033b6f510a Mon Sep 17 00:00:00 2001 From: Martin Bohal Date: Tue, 26 Jul 2016 15:45:55 +0200 Subject: [PATCH 2/2] Make js components comaptible with jQuery > 3.0.0 --- src/js/ckeditor-loader.js | 2 +- src/js/datetimepicker-loader.js | 2 +- src/js/disable.js | 2 +- src/js/filterable.js | 2 +- src/js/select2-loader.js | 2 +- src/js/sortable-table.js | 2 +- src/js/tests/unit/select2-loader.js | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/js/ckeditor-loader.js b/src/js/ckeditor-loader.js index c654e7f4..0819d7b9 100644 --- a/src/js/ckeditor-loader.js +++ b/src/js/ckeditor-loader.js @@ -7,7 +7,7 @@ (function ($, window) { // We have to use $(winodow).load() as $(document).ready() can not be triggered manually // and thus it would make it impossible to test this part of the code. - $(window).load(function () { + $(window).on('load', function () { $('[data-onload-ckeditor]').each(function () { var language = $('html').attr('lang'); var confObj = {}; diff --git a/src/js/datetimepicker-loader.js b/src/js/datetimepicker-loader.js index 532cacf0..4f9ae881 100644 --- a/src/js/datetimepicker-loader.js +++ b/src/js/datetimepicker-loader.js @@ -16,7 +16,7 @@ // We have to use $(winodow).load() as $(document).ready() can not be triggered manually // and thus it would make it impossible to test this part of the code. - $(window).load(function () { + $(window).on('load', function () { var initComponentFn = function (inlineConf) { var datetimePickerLoader = new DatetimePickerLoader($(this)); var conf = { diff --git a/src/js/disable.js b/src/js/disable.js index 0de626be..113c04e8 100644 --- a/src/js/disable.js +++ b/src/js/disable.js @@ -51,7 +51,7 @@ (function (Plugin, $, window) { // We have to use $(window).load() as $(document).ready() can not be triggered manually // and thus it would make it impossible to test this part of the code. - $(window).load(function () { + $(window).on('load', function () { var $controls = $('[data-toggle=disable]'); $controls.each(function () { diff --git a/src/js/filterable.js b/src/js/filterable.js index a6e05a64..5c314cb0 100644 --- a/src/js/filterable.js +++ b/src/js/filterable.js @@ -139,7 +139,7 @@ var lastEventTarget; var lastEventValue; - $(window).load(function () { + $(window).on('load', function () { $.each($('form'), function () { var $this = $(this); var filterData; diff --git a/src/js/select2-loader.js b/src/js/select2-loader.js index ef1a3fa1..98363304 100644 --- a/src/js/select2-loader.js +++ b/src/js/select2-loader.js @@ -7,7 +7,7 @@ (function ($, window) { // We have to use $(winodow).load() as $(document).ready() can not be triggered manually // and thus it would make it impossible to test this part of the code. - $(window).load(function () { + $(window).on('load', function () { $('[data-onload-select2]').each(function () { var confObj = {}; var $this = $(this); diff --git a/src/js/sortable-table.js b/src/js/sortable-table.js index 5f894623..8d7fe4f7 100644 --- a/src/js/sortable-table.js +++ b/src/js/sortable-table.js @@ -168,7 +168,7 @@ // We have to use $(winodow).load() as $(document).ready() can not be triggered manually // and thus it would make it impossible to test this part of the code. - $(window).load(function () { + $(window).on('load', function () { var $sortedTh = $('th[data-sort-onload]'); $sortedTh.each(function (i) { var $sortedTable = $($sortedTh[i]).closest('table'); diff --git a/src/js/tests/unit/select2-loader.js b/src/js/tests/unit/select2-loader.js index 451c0fc7..b07e3f21 100644 --- a/src/js/tests/unit/select2-loader.js +++ b/src/js/tests/unit/select2-loader.js @@ -66,7 +66,7 @@ $(function () { })); QUnit.ok(jQuery.fn.select2 .calledWithMatch(function (value) { - var testOpt = { element: $('option'), text: 'optionText' }; + var testOpt = { element: $(''), text: 'optionText' }; return value.formatResult(testOpt) === 'optionText'; }));