diff --git a/.eslintrc b/.eslintrc index 0281ac1a..e3b021d1 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,18 +1,20 @@ { "parser": "babel-eslint", "parserOptions": { - "sourceType": "module" + "sourceType": "module", + "ecmaFeatures": { "modules": true } }, "rules": { "max-len": [2, 80, 2, {"ignoreUrls": true}], "indent": [2, 4, {"SwitchCase": 1}], + "semi": ["error", "always"], "no-trailing-spaces": 2, "no-multi-spaces": 2, "array-bracket-spacing": 2, "keyword-spacing": ["error", { "after": true, "before": true }], "max-depth": [2, 7], - "max-statements": [2, 144], - "complexity": [2, 78], + "max-statements": [2, 143], + "complexity": [2, 32], "no-unused-vars": 2, "no-eval": 2, "no-underscore-dangle": 0, @@ -24,9 +26,6 @@ "new-cap": 2, "radix": [2, "always"] }, - "ecmaFeatures": { - "modules": true - }, "env": { "es6": true, "browser": true, diff --git a/.travis.yml b/.travis.yml index 59fc266f..e657aaf7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ script: branches: only: - master + - /^greenkeeper/.*$/ env: global: - secure: A1G8GvJkV0rjy7XCTVdOpTHy3xaoSZZAbMWhI+ikrqBqd8mRz+sB71FhRusouTcYdsT5VfF9Io2doS8LKAeP0TNC34Pp0uvjtsvarzn8a/oNEOuqR3Ub0ws2bmbZIZc+wOpgErKOj1H1QSJAUpd6ZjIuEAbOVXlhGBJz3zUCmcpRDh32CpFKC62oFWeGlvttxPciLLzBfKgkVKEGhPtdGP/xCHL1MCQptYVHZiXwWsaIQ5wHFO6KCVlRrPgdfOL+Yce3mT02iXH6ZjW6U6zA6vYQVQZVD873AkU5RmirYblW+jW1wdvu4UXI71lSH6Z3uXRVnrw1b0TsLVTjP9ZUbCtkTHtLbxYzeDjEukxKoCjpAppIhOtaNIxrdA8oKJAabQYp5X+QK6lkosy0zdT5u2B1+g8unZhsf0y//7lgLUe04iQ7sc1Q6AHiiEGtByaXg4BHNW53bUfKgNnbV4+IbXf8rz5wWOxL2/yWAU/GoiszjqRQfajAXCpSf6SyMjXjhhvQdeFn+Cz6FwdtaxH+tOIY0Hq9Gqy1xrLIkv/httd3O+AbhLrU1c/M0MwlFQue7GeJb7ZyF3KsK7bXvoz2dEqvzHd98NZXiQEqFXCIs77uVh4eZMoYrbEyrkOAgkUZNQYhHh9fuvfynJ/zgUvyA0v3GUvBebq3ybYKD/vqX7s= diff --git a/README.md b/README.md index e41c177c..e3384f7a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ [![Build Status](https://api.travis-ci.org/koalyptus/TableFilter.svg?branch=master)](https://travis-ci.org/koalyptus/TableFilter) -[![Document](http://koalyptus.github.io/TableFilter/docs/badge.svg)](https://koalyptus.github.io/TableFilter/docs/source) +[![Document](https://koalyptus.github.io/TableFilter/docs/badge.svg)](https://koalyptus.github.io/TableFilter/docs/source.html) [![codecov](https://codecov.io/gh/koalyptus/TableFilter/branch/master/graph/badge.svg)](https://codecov.io/gh/koalyptus/TableFilter) +[![Greenkeeper badge](https://badges.greenkeeper.io/koalyptus/TableFilter.svg)](https://greenkeeper.io/) # TableFilter @@ -32,23 +33,40 @@ git clone https://github.com/koalyptus/TableFilter.git * You can [download](https://github.com/koalyptus/TableFilter/archive/master.zip) this repository. -* Alternatively, install TableFilter files in your npm enabled project using: +* TableFilter is available on [npm repository](https://www.npmjs.com/package/tablefilter), you can install it from the command line using the following command: ```shell npm install tablefilter --save-dev -``` +``` * or get the future features from the ``next`` release channel: ```shell npm install tablefilter@next --save-dev ``` -* If you don't use `npm`, you can also -[access these files on unpkg](https://unpkg.com/tablefilter/), download them -or point your package manager to them. +* Alternatively you can also [access these files from unpkg CDN](https://unpkg.com/tablefilter/), download them or point your package manager to them. ## Setup +### Using modules +Require `TableFilter`: +```javascript +// ES2015 modules +import TableFilter from 'tablefilter'; + +// CommonJS or AMD modules +var TableFilter = require('tablefilter'); +``` + +### Using distribution scripts +If you are not using a module system, you can reference the distribution scripts directly in your html pages: +```html + +``` + +### Placing manually the distribution scripts in your project Copy the ``tablefilter`` directory under ``dist`` and place it at desired location in your project. Then include the main js file in your page: ```shell ``` + +### Usage Place the following snippet just under the HTML table and always define a ``base_path`` property in the configuration object to reflect the path to the script ```shell + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FromDestinationRoad Distance (km)By Air (hrs)By Rail (hrs)
SydneyAdelaide14121.425.3
SydneyBrisbane9821.516
SydneyCanberra286.64.3
SydneyMelbourne8721.110.5
AdelaidePerth27813.138
AdelaideAlice Springs1533220.25
AdelaideBrisbane20452.1540
+ + + + +
+
+ + diff --git a/test/test-no-config.js b/test/test-no-config.js new file mode 100644 index 00000000..1828363e --- /dev/null +++ b/test/test-no-config.js @@ -0,0 +1,63 @@ +(function(win, TableFilter){ + + var tf = new TableFilter('demo'); + tf.basePath = '../dist/tablefilter/'; + tf.init(); + + module('Sanity checks'); + test('Features', function() { + deepEqual(tf instanceof TableFilter, true, 'TableFilter instanciated'); + deepEqual(tf.fltGrid, true, 'fltGrid property'); + notEqual(tf.getFilterElement(0), null, + 'Filter element for column 0'); + deepEqual(tf.refRow, 2, 'Reference row index'); + deepEqual(Object.keys(tf.Mod).length, 14, 'Features instantiated'); + notEqual(tf.feature('rowsCounter'), null, 'RowsCounter instantiated'); + deepEqual(tf.rowsCounter, false, 'RowsCounter not enabled'); + }); + + module('Feature life cycle'); + test('Can init', function() { + // setup + var rowsCounter = tf.feature('rowsCounter'); + tf.rowsCounter = true; + rowsCounter.enable(); + + // act + rowsCounter.init(); + + // assert + deepEqual(rowsCounter.enabled, true, 'rowsCounter enabled'); + deepEqual(rowsCounter.initialized, true, 'rowsCounter initialized'); + }); + + test('Can destroy', function() { + // setup + var rowsCounter = tf.feature('rowsCounter'); + + // act + rowsCounter.destroy(); + + // assert + deepEqual(rowsCounter.initialized, false, 'rowsCounter initialized'); + }); + + test('Can reset', function() { + // setup + var rowsCounter = tf.feature('rowsCounter'); + + // act + rowsCounter.reset(); + + // assert + deepEqual(rowsCounter.enabled, true, 'rowsCounter enabled'); + deepEqual(rowsCounter.initialized, true, 'rowsCounter initialized'); + }); + + module('Tear-down'); + test('TableFilter removed', function() { + tf.destroy(); + deepEqual(tf.isInitialized(), false, 'Filters removed'); + }); + +})(window, TableFilter); diff --git a/test/test-no-filters.js b/test/test-no-filters.js index 54199a0f..a1141c86 100644 --- a/test/test-no-filters.js +++ b/test/test-no-filters.js @@ -137,9 +137,10 @@ tf = null; tf = new TableFilter('demo', { base_path: '../dist/tablefilter/', - grid_enable_default_filters: false, col_width: ['100px','100px','100px','100px','100px'], - grid_layout: true + grid_layout: { + filters: false + } }); // act diff --git a/test/test-no-headers.js b/test/test-no-headers.js index 08c5f172..c0734fe2 100644 --- a/test/test-no-headers.js +++ b/test/test-no-headers.js @@ -49,8 +49,9 @@ test('Grid layout with no header', function() { tf.destroy(); tf = new TableFilter('demo', { base_path: '../dist/tablefilter/', - grid_layout: true, - grid_no_headers: true + grid_layout: { + no_headers: true + } }); tf.init(); diff --git a/test/test-no-results-message.js b/test/test-no-results-message.js index 9d05ee5a..1e8b79d0 100644 --- a/test/test-no-results-message.js +++ b/test/test-no-results-message.js @@ -143,7 +143,7 @@ test('Sanity checks', function() { deepEqual(tfGl.noResults, true, 'noResults property'); deepEqual(noResultsGl.cont.nodeName, 'DIV', 'Container element'); deepEqual(noResultsGl.cont.className, 'no-results', - 'Container element default CSS class'); + 'Container element default CSS class'); test('Can display no results message in grid layout', function() { tfGl.setFilterValue(0, 'sadasd'); @@ -154,7 +154,7 @@ test('Sanity checks', function() { 'No results message displayed'); deepEqual( parseInt(noResultsGl.cont.style.width, 10), - gridLayout.tblCont.clientWidth, + gridLayout.headTbl.clientWidth, 'Container element width' ); }); diff --git a/test/test-no-rows.js b/test/test-no-rows.js index 642dc212..40ef963f 100644 --- a/test/test-no-rows.js +++ b/test/test-no-rows.js @@ -3,7 +3,7 @@ module('TableFilter with no rows'); test('throws when no rows', function() { throws( - function() { new TableFilter('demo') }, + function() { new TableFilter('demo'); }, Error, 'Throws Error when DOM table does not contain rows' ); diff --git a/test/test-paging.js b/test/test-paging.js index c30dcd11..f9833119 100644 --- a/test/test-paging.js +++ b/test/test-paging.js @@ -1,9 +1,10 @@ var tf = new TableFilter('demo', { base_path: '../dist/tablefilter/', - paging: true, - paging_length: 2, - results_per_page: ['Results per page ', [2, 4, 6]] + paging: { + length: 2, + results_per_page: ['Results per page ', [2, 4, 6]] + } }); tf.init(); @@ -11,7 +12,7 @@ var paging = tf.feature('paging'); module('Sanity checks'); test('Paging component', function() { notEqual(paging, null, 'Paging instanciated'); - deepEqual(paging.pagingLength, 2, 'Paging length'); + deepEqual(paging.pageLength, 2, 'Paging length'); deepEqual(paging.nbPages, 4, 'Number of pages'); }); module('Feature interface'); @@ -33,7 +34,7 @@ test('Properties', function() { }); test('Can destroy', function() { paging.destroy(); - deepEqual(paging.enabled, false, 'disabled'); + deepEqual(paging.initialized, false, 'not initialized'); }); test('Can reset', function() { paging.reset(); @@ -60,8 +61,8 @@ test('Can check is enabled', function() { module('UI elements'); test('Paging UI elements', function() { - notEqual(paging.pagingSlc, null, 'Paging drop-down element'); - notEqual(paging.resultsPerPageSlc, null, + notEqual(paging.pageSlc, null, 'Paging drop-down element'); + notEqual(paging.pageLengthSlc, null, 'Number of results per page drop-down element'); notEqual(paging.btnNextCont, null, 'Next button container element'); notEqual(paging.btnPrevCont, null, 'Previous button container element'); @@ -71,8 +72,8 @@ test('Paging UI elements', function() { test('Destroy Paging component', function() { paging.destroy(); - deepEqual(paging.pagingSlc, null, 'Paging drop-down element'); - deepEqual(paging.resultsPerPageSlc, null, 'Paging drop-down element'); + deepEqual(paging.pageSlc, null, 'Paging drop-down element'); + deepEqual(paging.pageLengthSlc, null, 'Paging drop-down element'); deepEqual(paging.btnNextCont, null, 'Next button container element'); deepEqual(paging.btnPrevCont, null, 'Previous button container element'); deepEqual(paging.btnLastCont, null, 'Last button container element'); @@ -83,7 +84,7 @@ test('Destroy Paging component', function() { test('Reset Paging component', function() { paging.reset(); paging.setPage(2); - notEqual(paging.pagingSlc, null, 'Paging drop-down element'); + notEqual(paging.pageSlc, null, 'Paging drop-down element'); }); module('Behaviour'); @@ -92,7 +93,7 @@ test('Set page', function() { deepEqual(paging.getPage(), 1, 'Expected page number'); paging.setPage(3); deepEqual(paging.getPage(), 3, 'Expected page number'); - deepEqual(paging.pagingSlc.selectedIndex, 2, + deepEqual(paging.pageSlc.selectedIndex, 2, 'Expected page number in paging drop-down selector'); }); @@ -121,8 +122,8 @@ test('Can set page with command', function() { }); test('Set page via drop-down page selector', function() { - paging.pagingSlc.selectedIndex = 3; - paging.changePage(paging.pagingSlc.selectedIndex); + paging.pageSlc.selectedIndex = 3; + paging.changePage(paging.pageSlc.selectedIndex); deepEqual(paging.getPage(), 4, 'Expected page number'); }); @@ -145,10 +146,10 @@ test('Filter with dummy value', function() { test('Set results per page', function() { tf.clearFilters(); paging.changeResultsPerPage('4'); - deepEqual(paging.pagingLength, 4, 'Expected page length'); + deepEqual(paging.pageLength, 4, 'Expected page length'); deepEqual(paging.nbPages, 2, 'Expected number of pages'); paging.changeResultsPerPage('6'); - deepEqual(paging.pagingLength, 6, 'Expected page length'); + deepEqual(paging.pageLength, 6, 'Expected page length'); deepEqual(paging.nbPages, 2, 'Expected number of pages'); }); @@ -159,16 +160,17 @@ test('Grid layout with paging', function() { tf = new TableFilter('demo', { base_path: '../dist/tablefilter/', grid_layout: true, - paging: true, - paging_length: 2, - results_per_page: ['Results per page ', [2,4,6]] + paging: { + length: 2, + results_per_page: ['Results per page ', [2, 4, 6]] + } }); tf.init(); paging = tf.feature('paging'); - notEqual(paging.pagingSlc, null, 'Paging drop-down element'); - notEqual(paging.resultsPerPageSlc, null, + notEqual(paging.pageSlc, null, 'Paging drop-down element'); + notEqual(paging.pageLengthSlc, null, 'Number of results per page drop-down element'); notEqual(paging.btnNextCont, null, 'Next button container element'); notEqual(paging.btnPrevCont, null, 'Previous button container element'); @@ -209,8 +211,8 @@ test('Can set page with command', function() { }); test('Set page via drop-down page selector', function() { - paging.pagingSlc.selectedIndex = 3; - paging.changePage(paging.pagingSlc.selectedIndex); + paging.pageSlc.selectedIndex = 3; + paging.changePage(paging.pageSlc.selectedIndex); deepEqual(paging.getPage(), 4, 'Expected page number'); }); @@ -233,10 +235,10 @@ test('Filter with dummy value', function() { test('Set results per page', function() { tf.clearFilters(); paging.changeResultsPerPage('4'); - deepEqual(paging.pagingLength, 4, 'Expected page length'); + deepEqual(paging.pageLength, 4, 'Expected page length'); deepEqual(paging.nbPages, 2, 'Expected number of pages'); paging.changeResultsPerPage('6'); - deepEqual(paging.pagingLength, 6, 'Expected page length'); + deepEqual(paging.pageLength, 6, 'Expected page length'); deepEqual(paging.nbPages, 2, 'Expected number of pages'); }); @@ -251,7 +253,7 @@ test('Set results per page when no valid rows', function() { paging.changeResultsPerPage('4'); // assert - deepEqual(paging.resultsPerPageSlc.value, '4', 'Select page length option'); + deepEqual(paging.pageLengthSlc.value, '4', 'Select page length option'); deepEqual(paging.getPage(), 1, 'Expected page number'); }); @@ -260,7 +262,7 @@ test('can destroy and init TableFilter', function() { tf.destroy(); tf.init(); notEqual(paging, null, 'Paging instanciated'); - deepEqual(paging.pagingLength, 2, 'Paging length'); + deepEqual(paging.pageLength, 2, 'Paging length'); deepEqual(paging.nbPages, 4, 'Number of pages'); }); diff --git a/test/test-popup-filter.js b/test/test-popup-filter.js index 6eb3ccde..01691bdc 100644 --- a/test/test-popup-filter.js +++ b/test/test-popup-filter.js @@ -33,6 +33,8 @@ test('Pop-up filter component', function() { 'By Air (hrs)', 'Expected header text for multiple filter type' ); + deepEqual(tf.dom().rows[tf.headersRow-1].style.display, 'none', + 'Extra row hidden'); }); module('UI elements'); @@ -156,7 +158,7 @@ test('Pop-up filter auto-closes when user clicks away', function() { // act var evObj = document.createEvent('HTMLEvents'); evObj.initEvent('mouseup', true, true); - tf.tbl.rows[4].cells[2].dispatchEvent(evObj); + tf.dom().rows[4].cells[2].dispatchEvent(evObj); // assert deepEqual(popupFilter.isOpen(0), false, @@ -164,6 +166,19 @@ test('Pop-up filter auto-closes when user clicks away', function() { ); }); +test('Can close all popup filters', function() { + // setup + popupFilter.open(0); + + // act + popupFilter.closeAll(); + + // assert + deepEqual(popupFilter.isOpen(0), false, + 'Pop-up filter closed after closeAll' + ); +}); + test('Can destroy and reset', function(){ // setup popupFilter.destroy(); @@ -191,6 +206,38 @@ test('TableFilter re-initialised', function() { deepEqual(id(tf.fltIds[3]).nodeName, 'SELECT', 'Filter exists'); }); +module('Properties'); +test('Can set icon HTML', function() { + // setup + tf.destroy(); + tf = new TableFilter('demo', { + base_path: '../dist/tablefilter/', + col_2: 'multiple', + col_3: 'select', + col_4: 'none', + popup_filters: { + image_html: 'hello world' + } + }); + tf.init(); + + var feature = tf.feature('popupFilter'); + feature.filtersCache = []; + feature.fltElms = []; + + // act + tf.init(); + var headersRow = tf.dom().rows[tf.getHeadersRowIndex()]; + + // assert + deepEqual( + headersRow.cells[1].innerHTML + .indexOf('hello world') !== -1, + true, + 'Custom HTML element present' + ); +}); + module('Grid-layout'); test('Re-instantiated with grid-layout', function() { tf.destroy(); @@ -287,6 +334,46 @@ test('Properties', function() { 'function', 'Feature enable method'); }); +module('Overrides'); +test('Configuration settings overrides', function() { + // setup + tf.destroy(); + tf = new TableFilter('demo', { + base_path: '../dist/tablefilter/', + popup_filters: true, + filters_row_index: 1 + }); + + // assert + deepEqual(tf.filtersRowIndex, 1, 'Filters row index config setting value'); + deepEqual( + tf.externalFltTgtIds, + [], + 'External filters container ids config setting value' + ); + deepEqual(tf.headersRow, 0, 'Headers row index config setting value'); + + test('Overrides after init', function() { + // act + tf.init(); + + // assert + deepEqual(tf.filtersRowIndex, 0, 'Filters row index override'); + deepEqual( + tf.externalFltTgtIds, + [ + 'popup_demo_0', + 'popup_demo_1', + 'popup_demo_2', + 'popup_demo_3', + 'popup_demo_4' + ], + 'External filters container ids config setting value' + ); + deepEqual(tf.headersRow, 1, 'Headers row index override'); + }); +}); + module('Tear-down'); test('TableFilter removed', function() { tf.destroy(); diff --git a/test/test-popup-filters-grouped-headers.html b/test/test-popup-filters-grouped-headers.html new file mode 100644 index 00000000..de0d8aaa --- /dev/null +++ b/test/test-popup-filters-grouped-headers.html @@ -0,0 +1,104 @@ + + + + + TableFilter pop-up filters with grouped headers + + + + + +

+ Tests for + https://jsfiddle.net/wLexc6pt/6/ fiddle +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Colspan HeaderColspan Header
SubHeaderSubHeaderSubHeaderSubHeaderSubHeaderSubHeaderSubHeader
ValueValueValueFilter Value 1Filter Value 1Filter Value 1Filter Value 1
ValueValueValueFilter Value 1Filter Value 1Filter Value 1Filter Value 1
ValueValueValueFilter Value 2Filter Value 2Filter Value 2Filter Value 2
ValueValueValueFilter Value 3Filter Value 3Filter Value 3Filter Value 3
ValueValueValueFilter Value 3Filter Value 3Filter Value 3Filter Value 3
ValueValueValueFilter Value 4Filter Value 4Filter Value 4Filter Value 4
ValueValueValueFilter Value 5Filter Value 5Filter Value 5Filter Value 5
+ + + + +
+
+ + diff --git a/test/test-popup-filters-grouped-headers.js b/test/test-popup-filters-grouped-headers.js new file mode 100644 index 00000000..7f5dac81 --- /dev/null +++ b/test/test-popup-filters-grouped-headers.js @@ -0,0 +1,206 @@ + +var id = function (id){ return document.getElementById(id); }; + +var _tf = new TableFilter('demo', { + base_path: '../dist/tablefilter/', + col_0: 'none', + col_1: 'none', + col_2: 'none', + col_3: 'checklist', + col_4: 'checklist', + col_5: 'checklist', + col_6: 'checklist', + headers_row_index: 1, + popup_filters: true, + mark_active_columns: true +}, 2); +_tf.init(); + +var popupFilter = _tf.feature('popupFilter'); +module('Sanity checks'); +test('Pop-up filter component', function() { + notEqual(popupFilter, null, 'PopupFilter instanciated'); + deepEqual(popupFilter.fltElms instanceof Array, + true, 'Type of fltElms property'); + deepEqual( + popupFilter.adjustToContainer, + true, + 'Popup filter width adjusts to container' + ); + deepEqual(_tf.headersRow, 2, 'Headers row index'); +}); + +module('UI elements'); +test('Pop-up filter UI elements', function() { + var flt3 = popupFilter.fltElms[3]; + var flt4 = popupFilter.fltElms[4]; + var fltIcn3 = popupFilter.fltIcons[3]; + var fltIcn4 = popupFilter.fltIcons[4]; + var fltIcn0 = popupFilter.fltIcons[0]; + var fltIcn1 = popupFilter.fltIcons[0]; + + notEqual(flt3, null, 'Filter element exists'); + notEqual(flt4, null, 'Filter element exists'); + deepEqual(fltIcn3.nodeName, 'IMG', 'Filter icon exists'); + deepEqual(fltIcn4.nodeName, 'IMG', 'Filter icon exists'); + deepEqual(fltIcn0, undefined, 'Filter icon does not exist for column 0'); + deepEqual(fltIcn1, undefined, 'Filter icon does not exist for column 1'); +}); + +test('Pop-up filter state after filtering', function(){ + var fltIcn4 = popupFilter.fltIcons[4]; + _tf.setFilterValue(4, 'Filter Value 4'); + _tf.filter(); + + deepEqual(fltIcn4.src.indexOf('icn_filterActive') !== -1, + true, 'Icon state'); +}); + +test('Pop-up filter state after clearing', function(){ + var fltIcn3 = popupFilter.fltIcons[3]; + var fltIcn4 = popupFilter.fltIcons[4]; + var fltIcn5 = popupFilter.fltIcons[5]; + var fltIcn6 = popupFilter.fltIcons[6]; + _tf.clearFilters(); + + deepEqual(fltIcn3.src.indexOf('icn_filterActive') === -1, + true, 'Icon state'); + deepEqual(fltIcn4.src.indexOf('icn_filterActive') === -1, + true, 'Icon state'); + deepEqual(fltIcn5.src.indexOf('icn_filterActive') === -1, + true, 'Icon state'); + deepEqual(fltIcn6.src.indexOf('icn_filterActive') === -1, + true, 'Icon state'); +}); + +test('Can open pop-up filter', function(){ + // act + popupFilter.open(5); + + // assert + deepEqual(popupFilter.isOpen(5), true, + 'Popup filter is open'); +}); + +test('Can close pop-up filter', function(){ + // act + popupFilter.close(5); + + // assert + deepEqual(popupFilter.isOpen(5), false, + 'Popup filter is open'); +}); + +test('Can toggle pop-up filter (initially closed)', function(){ + // setup + popupFilter.close(6); + + // act + popupFilter.toggle(6); + + // assert + deepEqual(popupFilter.isOpen(6), true, + 'Popup filter is toggled'); +}); + +test('Can toggle pop-up filter (initially opened)', function(){ + // setup + popupFilter.open(6); + + // act + popupFilter.toggle(6); + + // assert + deepEqual(popupFilter.isOpen(6), false, + 'Popup filter is toggled'); +}); + +test('Checklist pop-up filter remains open upon filtering', function(){ + // setup + popupFilter.open(4); + + // act + _tf.setFilterValue(4, ['Filter Value 4']); + _tf.filter(); + + // assert + deepEqual( + popupFilter.isOpen(4), + true, + 'Checklist pop-up filter still open after filtering' + ); +}); + +test('Pop-up filter auto-closes when user clicks away', function() { + // setup + popupFilter.open(5); + + // act + var evObj = document.createEvent('HTMLEvents'); + evObj.initEvent('mouseup', true, true); + _tf.dom().rows[4].cells[2].dispatchEvent(evObj); + + // assert + deepEqual(popupFilter.isOpen(5), false, + 'Pop-up filter closed after user clicks away' + ); +}); + +test('Can close all popup filters', function() { + // setup + popupFilter.open(3); + + // act + popupFilter.closeAll(4); + + // assert + deepEqual(popupFilter.isOpen(3), false, + 'Pop-up filter closed after closeAll' + ); +}); + +test('Does not close popup filter if closeOnFiltering false', function() { + // setup + popupFilter.closeOnFiltering = false; + popupFilter.open(4); + + // act + popupFilter.close(4); + + // assert + deepEqual(popupFilter.isOpen(4), false, + 'Pop-up filter closed after closeAll' + ); +}); + +// TODO: fix reset popupFilter component with grouped headers +// test('Can destroy and reset', function(){ +// // setup +// _tf.clearFilters(); +// _tf.filter(); +// popupFilter.destroy(); + +// // act +// popupFilter.reset(); + +// // assert +// deepEqual(popupFilter.fltElms.length, 7, 'Filters are generated'); +// deepEqual(popupFilter.fltIcons.length, 4, 'Icons are generated'); +// deepEqual(popupFilter.fltSpans.length, 4, +// 'Icon containers are generated'); +// }); + +test('TableFilter removed', function() { + _tf.destroy(); + var fltIcn1 = popupFilter.fltIcons[3]; + deepEqual(fltIcn1, undefined, 'Filter icon is removed'); + deepEqual(id(_tf.fltIds[3]), null, 'Filter is removed'); +}); + +// test('TableFilter re-initialised', function() { +// _tf.init(); +// var fltIcn1 = popupFilter.fltIcons[3]; +// deepEqual(fltIcn1.nodeName, 'IMG', 'Filter icon exists'); +// deepEqual(_tf.getFilterType(3), 'checklist', 'Filter type'); +// }); + diff --git a/test/test-rows-counter.js b/test/test-rows-counter.js index 87d8c70f..23002067 100644 --- a/test/test-rows-counter.js +++ b/test/test-rows-counter.js @@ -80,13 +80,18 @@ test('RowsCounter component with paging', function() { tf = null; tf = new TableFilter('demo', { base_path: '../dist/tablefilter/', - rows_counter: true, - paging: true, - paging_length: 3 + rows_counter: { + text: 'Records: ', + separator: '~', + over_text: ' \\ ' + }, + paging: { + length: 3 + } }); tf.init(); equal(tf.feature('rowsCounter').label.innerHTML, - '1-3 / 7', 'Counter value with paging'); + '1~3 \\ 7', 'Counter value with paging'); }); test('Can calculate page on page change', function() { //setup @@ -97,7 +102,7 @@ test('Can calculate page on page change', function() { //assert equal(tf.feature('rowsCounter').label.innerHTML, - '4-6 / 7', 'Counter value with paging'); + '4~6 \\ 7', 'Counter value with paging'); }); module('Tear-down'); diff --git a/test/test-single-filter.js b/test/test-single-filter.js index 27234ca8..d2a207f4 100644 --- a/test/test-single-filter.js +++ b/test/test-single-filter.js @@ -27,7 +27,6 @@ test('Sanity checks', function() { tf = new TableFilter('demo', { base_path: '../dist/tablefilter/', single_filter: true, - external_flt_grid: true, external_flt_grid_ids: ['single-search'] }); tf.init(); diff --git a/test/test-sort-custom-sorter.js b/test/test-sort-custom-sorter.js index 66f11963..38f1d49f 100644 --- a/test/test-sort-custom-sorter.js +++ b/test/test-sort-custom-sorter.js @@ -47,7 +47,7 @@ function startTest(tf, sort){ deepEqual(indicator.length, 1, 'Sort indicator in header element'); deepEqual( - (tf.tbl.rows[validRows[0]].cells[1]).innerHTML, + (tf.dom().rows[validRows[0]].cells[1]).innerHTML, 'AUY78', 'First custom key cell text before sorting'); }); @@ -58,7 +58,7 @@ function startTest(tf, sort){ deepEqual(sort.sorted, true, 'Table column sorted'); deepEqual( - (tf.tbl.rows[validRows[0]].cells[1]).innerHTML, + (tf.dom().rows[validRows[0]].cells[1]).innerHTML, 'QT1', 'First custom key cell text after sorting'); }); diff --git a/test/test-sort-key.js b/test/test-sort-key.js index e3626e3b..77d965fc 100644 --- a/test/test-sort-key.js +++ b/test/test-sort-key.js @@ -39,7 +39,7 @@ function start(tf, sort){ deepEqual(indicator.length, 1, 'Sort indicator in header element'); deepEqual( - (tf.tbl.rows[validRows[0]].cells[1]).innerHTML, + (tf.dom().rows[validRows[0]].cells[1]).innerHTML, 'AUY78', 'First custom key cell text before sorting'); }); @@ -50,7 +50,7 @@ function start(tf, sort){ deepEqual(sort.sorted, true, 'Table column sorted'); deepEqual( - (tf.tbl.rows[validRows[0]].cells[1]).innerHTML, + (tf.dom().rows[validRows[0]].cells[1]).innerHTML, 'QT1', 'First custom key cell text after sorting'); }); diff --git a/test/test-storage-cookie.js b/test/test-storage-cookie.js index 8396b85b..4416f4b1 100644 --- a/test/test-storage-cookie.js +++ b/test/test-storage-cookie.js @@ -7,8 +7,9 @@ var tf = new TableFilter('demo', { page_number: true, page_length: true }, - paging: true, - results_per_page: ['Records: ', [2, 4, 6]], + paging: { + results_per_page: ['Records: ', [2, 4, 6]] + } }); tf.init(); var state = tf.feature('state'); diff --git a/test/test-storage-local.js b/test/test-storage-local.js index c44969a1..b4dc4cce 100644 --- a/test/test-storage-local.js +++ b/test/test-storage-local.js @@ -7,8 +7,9 @@ var tf = new TableFilter('demo', { page_number: true, page_length: true }, - paging: true, - results_per_page: ['Records: ', [2, 4, 6]], + paging: { + results_per_page: ['Records: ', [2, 4, 6]], + } }); tf.init(); var state = tf.feature('state'); diff --git a/test/test.js b/test/test.js index 9c991ed4..b0e4e951 100644 --- a/test/test.js +++ b/test/test.js @@ -15,10 +15,14 @@ module('Table 1: DOM tests'); test('Filters row', function() { - equal(tf.tbl.rows[0].className, 'fltrow', 'Filters row CSS class name'); + equal( + tf.dom().rows[0].className, + 'fltrow', + 'Filters row CSS class name' + ); equal(tf.getFilterElement(0).nodeName, 'INPUT', 'Filter DOM element'); deepEqual( - tf.tbl.scrollWidth === tf.tbl.clientWidth, + tf.dom().scrollWidth === tf.dom().clientWidth, true, 'Horizontal scrollbar is not displayed' ); @@ -40,7 +44,7 @@ module('Table 2: sanity checks'); test('TableFilter instance', function() { notEqual(tf1.id, null, 'id check'); - deepEqual(tf1.tbl.classList.contains(tf1.prfxResponsive), true, + deepEqual(tf1.dom().classList.contains(tf1.prfxResponsive), true, 'Responsive CSS class'); equal(tf1.filtersRowIndex, 1, 'Filters row index'); deepEqual(tf1.getCellsNb(), 5, 'filters type collection length'); @@ -49,13 +53,13 @@ module('Table 2: DOM tests'); test('Filters row', function() { equal( - tf1.tbl.rows[1].className, + tf1.dom().rows[1].className, 'fltrow', 'Filters row CSS class name' ); equal(tf1.getFilterElement(0).nodeName, 'INPUT', 'Filter DOM element'); deepEqual( - tf1.tbl.scrollWidth > tf1.tbl.clientWidth, + tf1.dom().scrollWidth > tf1.dom().clientWidth, true, 'Horizontal scrollbar is displayed' ); @@ -74,7 +78,7 @@ // setup var importFile = tf1.import; var hit = 0; - tf1.import = function() { hit++ }; + tf1.import = function() { hit++; }; tf1.initialized = true; // act diff --git a/webpack.config.js b/webpack.config.js index 3437aec1..450a640a 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -30,7 +30,8 @@ module.exports = { options: { compact: false, presets: ['es2015'], - plugins: [['transform-es2015-classes', {loose: true}]] + // plugins: [['transform-es2015-classes', {loose: true}]] + plugins: 'transform-es2015-classes' }, loader: 'babel-loader' }, {