From 38045b8845b1452266d97c31e9141cdeb292b462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Serra?= Date: Tue, 15 Dec 2015 20:50:42 +0000 Subject: [PATCH] Allow to filter by column: value This Branch improves the way filterBy workes, by allowing it to be set with and hash like {'Column': 'search query'} programatically. Another improvement, that still needs to be touched is the ability to do the same from the search box in a form of 'Column: search query' that will be split by the ':' and use each side as column to filter, and value. --- Gruntfile.js | 4 +- build/reactable.js | 173 +- build/tests/reactable_test.js | 2359 +------------------------ lib/reactable/filterer.js | 12 +- lib/reactable/lib/array_intersect.js | 47 + lib/reactable/table.js | 96 +- src/reactable/filterer.jsx | 16 +- src/reactable/lib/array_intersect.jsx | 32 + src/reactable/table.jsx | 73 +- tests/reactable_test.jsx | 182 +- 10 files changed, 601 insertions(+), 2393 deletions(-) create mode 100644 lib/reactable/lib/array_intersect.js create mode 100644 src/reactable/lib/array_intersect.jsx diff --git a/Gruntfile.js b/Gruntfile.js index 728df8df..4680505f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -35,6 +35,7 @@ module.exports = function(grunt) { 'tmp/reactable/lib/filter_props_from.js': 'src/reactable/lib/filter_props_from.jsx', 'tmp/reactable/lib/extract_data_from.js': 'src/reactable/lib/extract_data_from.jsx', 'tmp/reactable/lib/is_react_component.js': 'src/reactable/lib/is_react_component.jsx', + 'tmp/reactable/lib/array_intersect.js': 'src/reactable/lib/array_intersect.jsx', 'tmp/reactable/lib/stringable.js': 'src/reactable/lib/stringable.jsx', 'tmp/reactable/filterer.js': 'src/reactable/filterer.jsx', 'tmp/reactable/sort.js': 'src/reactable/sort.jsx', @@ -59,6 +60,7 @@ module.exports = function(grunt) { 'lib/reactable/lib/filter_props_from.js': 'src/reactable/lib/filter_props_from.jsx', 'lib/reactable/lib/extract_data_from.js': 'src/reactable/lib/extract_data_from.jsx', 'lib/reactable/lib/is_react_component.js': 'src/reactable/lib/is_react_component.jsx', + 'lib/reactable/lib/array_intersect.js': 'src/reactable/lib/array_intersect.jsx', 'lib/reactable/lib/stringable.js': 'src/reactable/lib/stringable.jsx', 'lib/reactable/filterer.js': 'src/reactable/filterer.jsx', 'lib/reactable/sort.js': 'src/reactable/sort.jsx', @@ -82,6 +84,7 @@ module.exports = function(grunt) { dist: { src: [ 'tmp/reactable/lib/filter_props_from.js', + 'tmp/reactable/lib/array_intersect.js', 'tmp/reactable/lib/to_array.js', 'tmp/reactable/lib/stringable.js', 'tmp/reactable/lib/extract_data_from.js', @@ -131,4 +134,3 @@ module.exports = function(grunt) { grunt.registerTask('build', ['babel:common', 'buildBrowser']); grunt.registerTask('default', ['build', 'watch:build']); }; - diff --git a/build/reactable.js b/build/reactable.js index f4a7b148..5be48be6 100644 --- a/build/reactable.js +++ b/build/reactable.js @@ -42,6 +42,65 @@ window.ReactDOM["default"] = window.ReactDOM; } }); +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["exports"], factory); + } else if (typeof exports !== "undefined") { + factory(exports); + } else { + var mod = { + exports: {} + }; + factory(mod.exports); + global.array_intersect = mod.exports; + } +})(this, function (exports) { + "use strict"; + + exports.array_intersect = array_intersect; + + function array_intersect() { + var i, + all, + shortest, + nShortest, + n, + len, + ret = [], + obj = {}, + nOthers; + nOthers = arguments.length - 1; + nShortest = arguments[0].length; + shortest = 0; + for (i = 0; i <= nOthers; i++) { + n = arguments[i].length; + if (n < nShortest) { + shortest = i; + nShortest = n; + } + } + + for (i = 0; i <= nOthers; i++) { + n = i === shortest ? 0 : i || shortest; //Read the shortest array first. Read the first array instead of the shortest + len = arguments[n].length; + for (var j = 0; j < len; j++) { + var elem = arguments[n][j]; + if (obj[elem] === i - 1) { + if (i === nOthers) { + ret.push(elem); + obj[elem] = 0; + } else { + obj[elem] = i; + } + } else if (i === 0) { + obj[elem] = 0; + } + } + } + return ret; + } +}); + (function (global, factory) { if (typeof define === "function" && define.amd) { define(["exports"], factory); @@ -239,10 +298,20 @@ window.ReactDOM["default"] = window.ReactDOM; }, { key: 'render', value: function render() { + var value = ''; + if (typeof this.props.value != 'string') { + for (var key in this.props.value) { + value += key + ': ' + this.props.value[key] + ', '; + } + value = value.slice(0, -2); + } else { + value = this.props.value; + } + value = value.trim(); return _react['default'].createElement('input', { type: 'text', className: 'reactable-filter-input', placeholder: this.props.placeholder, - value: this.props.value, + value: value, onKeyUp: this.onChange.bind(this), onChange: this.onChange.bind(this) }); } @@ -960,17 +1029,17 @@ window.ReactDOM["default"] = window.ReactDOM; (function (global, factory) { if (typeof define === 'function' && define.amd) { - define(['exports', 'react', './lib/filter_props_from', './lib/extract_data_from', './unsafe', './thead', './th', './tr', './tfoot', './paginator'], factory); + define(['exports', 'react', './lib/filter_props_from', './lib/extract_data_from', './lib/array_intersect', './unsafe', './thead', './th', './tr', './tfoot', './paginator'], factory); } else if (typeof exports !== 'undefined') { - factory(exports, require('react'), require('./lib/filter_props_from'), require('./lib/extract_data_from'), require('./unsafe'), require('./thead'), require('./th'), require('./tr'), require('./tfoot'), require('./paginator')); + factory(exports, require('react'), require('./lib/filter_props_from'), require('./lib/extract_data_from'), require('./lib/array_intersect'), require('./unsafe'), require('./thead'), require('./th'), require('./tr'), require('./tfoot'), require('./paginator')); } else { var mod = { exports: {} }; - factory(mod.exports, global.React, global.filter_props_from, global.extract_data_from, global.unsafe, global.thead, global.th, global.tr, global.tfoot, global.paginator); + factory(mod.exports, global.React, global.filter_props_from, global.extract_data_from, global.array_intersect, global.unsafe, global.thead, global.th, global.tr, global.tfoot, global.paginator); global.table = mod.exports; } -})(this, function (exports, _react, _libFilter_props_from, _libExtract_data_from, _unsafe, _thead, _th, _tr, _tfoot, _paginator) { +})(this, function (exports, _react, _libFilter_props_from, _libExtract_data_from, _libArray_intersect, _unsafe, _thead, _th, _tr, _tfoot, _paginator) { 'use strict'; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; @@ -1204,24 +1273,90 @@ window.ReactDOM["default"] = window.ReactDOM; }, { key: 'applyFilter', value: function applyFilter(filter, children) { - // Helper function to apply filter text to a list of table rows - filter = filter.toLowerCase(); - var matchedChildren = []; + if (typeof filter === 'string') { + // Helper function to apply filter text to a list of table rows + filter = filter.toLowerCase(); + var matchedChildren = []; - for (var i = 0; i < children.length; i++) { - var data = children[i].props.data; + for (var i = 0; i < children.length; i++) { + var data = children[i].props.data; - for (var j = 0; j < this.props.filterable.length; j++) { - var filterColumn = this.props.filterable[j]; + for (var j = 0; j < this.props.filterable.length; j++) { + var filterColumn = this.props.filterable[j]; - if (typeof data[filterColumn] !== 'undefined' && (0, _libExtract_data_from.extractDataFrom)(data, filterColumn).toString().toLowerCase().indexOf(filter) > -1) { - matchedChildren.push(children[i]); - break; + if (typeof data[filterColumn] !== 'undefined' && (0, _libExtract_data_from.extractDataFrom)(data, filterColumn).toString().toLowerCase().indexOf(filter) > -1) { + matchedChildren.push(children[i]); + break; + } } } + + return matchedChildren; + } else { + var _ret = (function () { + + var filterCount = Object.keys(filter).length; + var matchedChildren = []; + + for (var filterColumn in filter) { + var val = filter[filterColumn]; + for (var i = 0; i < children.length; i++) { + var data = children[i].props.data; + if (typeof data[filterColumn] !== 'undefined' && (0, _libExtract_data_from.extractDataFrom)(data, filterColumn).toString().toLowerCase().indexOf(val) > -1) { + matchedChildren.push(children[i]); + } + } + } + + if (filterCount > 1) { + var result = []; + return { + v: matchedChildren.map(function (children) { + var occurrences = matchedChildren.filter(function (value) { + return value.key === children.key; + }).length; + if (occurrences == filterCount) { + return children; + } + }) + }; + } else { + return { + v: matchedChildren + }; + } + })(); + + if (typeof _ret === 'object') return _ret.v; + } + } + }, { + key: 'onFilter', + value: function onFilter(filters) { + if (typeof filters === 'string' && filters.indexOf(':') != -1) { + (function () { + var filterObj = {}; + filters = filters.trim(); + var col = ''; + var val = ''; + filters = filters.split(','); + + filters.map(function (filter) { + filter = filter.split(':'); + if (filter[0]) { + col = filter[0].trim(); + } + if (filter[1]) { + val = filter[1].trim(); + } + filterObj[col] = val; + }); + + filters = filterObj; + })(); } - return matchedChildren; + this.setState({ filter: filters }); } }, { key: 'sortByCurrentSort', @@ -1284,7 +1419,7 @@ window.ReactDOM["default"] = window.ReactDOM; this.setState({ currentSort: currentSort }); this.sortByCurrentSort(); - if (this.props.onSort) { + if (typeof this.props.onSort === 'function') { this.props.onSort(currentSort); } } @@ -1410,9 +1545,7 @@ window.ReactDOM["default"] = window.ReactDOM; props, columns && columns.length > 0 ? _react['default'].createElement(_thead.Thead, { columns: columns, filtering: filtering, - onFilter: function (filter) { - _this.setState({ filter: filter }); - }, + onFilter: this.onFilter.bind(this), filterPlaceholder: this.props.filterPlaceholder, currentFilter: this.state.filter, sort: this.state.currentSort, diff --git a/build/tests/reactable_test.js b/build/tests/reactable_test.js index 77cf3e06..e03657a9 100644 --- a/build/tests/reactable_test.js +++ b/build/tests/reactable_test.js @@ -1,2336 +1,23 @@ -(function (global, factory) { - if (typeof define === 'function' && define.amd) { - define(['exports'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports); - } else { - var mod = { - exports: {} - }; - factory(mod.exports); - global.reactable_test = mod.exports; - } -})(this, function (exports) { - 'use strict'; - - var ReactTestUtils = React.addons.TestUtils; - var expect = chai.expect; - - var ReactableTestUtils = { - resetTestEnvironment: function resetTestEnvironment() { - ReactDOM.unmountComponentAtNode($('div#test-node')[0]); - $('div#test-node').remove(); - }, - - // Expect the row specified to have the specified class - expectRowClass: function expectRowClass(rowIndex, className) { - var row = $($('#table tbody.reactable-data tr')[rowIndex]); - expect(row).to.have['class'](className); - }, - - // Expect the columns of a the data row specified to have the values in the array as their text values - expectRowText: function expectRowText(rowIndex, textArray) { - var row = $($('#table tbody.reactable-data tr')[rowIndex]).find('td'); - - expect(row.length).to.equal(textArray.length); - - for (var i = 0; i < row.length; i++) { - expect($(row[i])).to.have.text(textArray[i]); - } - }, - - testNode: function testNode() { - var testNode = $('
').attr('id', 'test-node'); - $('body').append(testNode); - testNode.empty(); - return testNode[0]; - } - }; - - describe('Reactable', function () { - describe('directly passing a data array', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ Name: 'Griffin Smith', Age: '18' }, { Age: '23', Name: 'Lee Salminen' }, { Age: '28', Position: 'Developer' }, { Name: 'Leonor Hyatt', Position: null }] }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the table', function () { - expect($('table#table.table')).to.exist; - }); - - it('renders the column headers in the table', function () { - var headers = []; - $('thead th').each(function () { - headers.push($(this).text()); - }); - - expect(headers).to.eql(['Name', 'Age', 'Position']); - }); - - it('renders the first row with the correct data', function () { - ReactableTestUtils.expectRowText(0, ['Griffin Smith', '18', '']); - }); - - it('renders the second row with the correct data', function () { - ReactableTestUtils.expectRowText(1, ['Lee Salminen', '23', '']); - }); - - it('renders the third row with the correct data', function () { - ReactableTestUtils.expectRowText(2, ['', '28', 'Developer']); - }); - - it('handles null values', function () { - ReactableTestUtils.expectRowText(3, ['Leonor Hyatt', '', '']); - }); - }); - - describe('adding s to the ', function () { - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table' }, - React.createElement(Reactable.Tr, { data: { Name: 'Griffin Smith', Age: '18' } }), - React.createElement(Reactable.Tr, { data: { Age: '23', Name: 'Lee Salminen' } }), - React.createElement(Reactable.Tr, { data: { Age: '28', Position: 'Developer' } }) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the table', function () { - expect($('table#table.table')).to.exist; - }); - - it('renders the column headers in the table', function () { - var headers = []; - $('thead th').each(function () { - headers.push($(this).text()); - }); - - expect(headers).to.eql(['Name', 'Age', 'Position']); - }); - - it('renders the first row with the correct data', function () { - ReactableTestUtils.expectRowText(0, ['Griffin Smith', '18', '']); - }); - - it('renders the second row with the correct data', function () { - ReactableTestUtils.expectRowText(1, ['Lee Salminen', '23', '']); - }); - - it('renders the third row with the correct data', function () { - ReactableTestUtils.expectRowText(2, ['', '28', 'Developer']); - }); - }); - - describe('adding s', function () { - context('with only one s', function () { - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table' }, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name' }, - React.createElement( - 'b', - null, - 'Griffin Smith' - ) - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - React.createElement( - 'em', - null, - '18' - ) - ) - ), - null, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Position' }, - React.createElement( - 'b', - null, - 'Developer' - ) - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - React.createElement( - 'em', - null, - '28' - ) - ) - ) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the table', function () { - expect($('table#table.table')).to.exist; - }); - - it('renders the column headers in the table', function () { - var headers = []; - $('thead th').each(function () { - headers.push($(this).text()); - }); - - expect(headers).to.eql(['Name', 'Age', 'Position']); - }); - - it('renders the first row with the correct data', function () { - ReactableTestUtils.expectRowText(0, ['Griffin Smith', '18', '']); - }); - - it('renders the second row with the correct data', function () { - ReactableTestUtils.expectRowText(1, ['', '28', 'Developer']); - }); - }); - }); - - describe('Adding a ', function () { - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table', sortable: ['Name'], filterable: ['Name', 'Age'] }, - React.createElement(Reactable.Tr, { className: 'rowClass1', data: { Name: 'Griffin Smith', Age: '18' } }), - React.createElement(Reactable.Tr, { className: 'rowClass2', data: { Age: '23', Name: 'Lee Salminen' } }), - React.createElement(Reactable.Tr, { className: 'rowClass3', data: { Age: '28', Position: 'Developer' } }), - React.createElement( - Reactable.Tfoot, - { id: 'tfoot' }, - React.createElement( - 'tr', - null, - React.createElement( - 'td', - { id: 'tfoot-stuff' }, - 'Test' - ) - ) - ) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the table', function () { - expect($('#table')).to.exist; - }); - - it('renders the regular data rows', function () { - ReactableTestUtils.expectRowText(0, ['Griffin Smith', '18', '']); - ReactableTestUtils.expectRowText(1, ['Lee Salminen', '23', '']); - ReactableTestUtils.expectRowText(2, ['', '28', 'Developer']); - }); - - it('renders the tfoot', function () { - expect($('#tfoot')).to.exist; - }); - - it('renders the children of the tfoot', function () { - expect($('#tfoot-stuff')).to.exist; - }); - - context('when sorting', function () { - before(function () { - ReactTestUtils.Simulate.click($('th')[0]); - }); - - it('leaves the tfoot alone', function () { - expect($('table :last-child')).to.match('tfoot'); - }); - }); - - context('when filtering', function () { - before(function () { - var $filter = $('.reactable-filter-input'); - - $filter.val('griffin'); - ReactTestUtils.Simulate.keyUp($filter[0]); - }); - - it('leaves the tfoot alone', function () { - expect($('table :last-child')).to.match('tfoot'); - }); - }); - }); - - describe('passing through HTML props', function () { - describe('adding s with className to the
s to the
', function () { - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table' }, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name' }, - 'Griffin Smith' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name' }, - 'Lee Salminen' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name' }, - 'Ian Zhang' - ) - ) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the table', function () { - expect($('table#table.table')).to.exist; - }); - - it('renders the column headers in the table', function () { - var headers = []; - $('thead th').each(function () { - headers.push($(this).text()); - }); - - expect(headers).to.eql(['Name']); - }); - - it('renders the first row with the correct data', function () { - ReactableTestUtils.expectRowText(0, ['Griffin Smith']); - }); - - it('renders the second row with the correct data', function () { - ReactableTestUtils.expectRowText(1, ['Lee Salminen']); - }); - - it('renders the third row with the correct data', function () { - ReactableTestUtils.expectRowText(2, ['Ian Zhang']); - }); - }); - - context('with multiple s', function () { - context('with plain text', function () { - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table' }, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name' }, - 'Griffin Smith' - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - '18' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name' }, - 'Lee Salminen' - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - '23' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Position' }, - 'Developer' - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - '28' - ) - ) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the table', function () { - expect($('table#table.table')).to.exist; - }); - - it('renders the column headers in the table', function () { - var headers = []; - $('thead th').each(function () { - headers.push($(this).text()); - }); - - expect(headers).to.eql(['Name', 'Age', 'Position']); - }); - - it('renders the first row with the correct data', function () { - ReactableTestUtils.expectRowText(0, ['Griffin Smith', '18', '']); - }); - - it('renders the second row with the correct data', function () { - ReactableTestUtils.expectRowText(1, ['Lee Salminen', '23', '']); - }); - - it('renders the third row with the correct data', function () { - ReactableTestUtils.expectRowText(2, ['', '28', 'Developer']); - }); - }); - }); - - context('with React.DOM nodes inside', function () { - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table' }, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name' }, - React.createElement( - 'b', - null, - 'Griffin Smith' - ) - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - React.createElement( - 'em', - null, - '18' - ) - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name' }, - React.createElement( - 'b', - null, - 'Lee Salminen' - ) - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - React.createElement( - 'em', - null, - '23' - ) - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Position' }, - React.createElement( - 'b', - null, - 'Developer' - ) - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - React.createElement( - 'em', - null, - '28' - ) - ) - ) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the table', function () { - expect($('table#table.table')).to.exist; - }); - - it('renders the column headers in the table', function () { - var headers = []; - $('thead th').each(function () { - headers.push($(this).text()); - }); - - expect(headers).to.eql(['Name', 'Age', 'Position']); - }); - - it('renders the first row with the correct data', function () { - ReactableTestUtils.expectRowText(0, ['Griffin Smith', '18', '']); - }); - - it('renders the second row with the correct data', function () { - ReactableTestUtils.expectRowText(1, ['Lee Salminen', '23', '']); - }); - - it('renders the third row with the correct data', function () { - ReactableTestUtils.expectRowText(2, ['', '28', 'Developer']); - }); - }); - - context('with null s', function () { - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table' }, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name' }, - React.createElement( - 'b', - null, - 'Griffin Smith' - ) - ), - null - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name' }, - React.createElement( - 'b', - null, - 'Lee Salminen' - ) - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - React.createElement( - 'em', - null, - '23' - ) - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Position' }, - React.createElement( - 'b', - null, - 'Developer' - ) - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - React.createElement( - 'em', - null, - '28' - ) - ) - ) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the table', function () { - expect($('table#table.table')).to.exist; - }); - - it('renders the column headers in the table', function () { - var headers = []; - $('thead th').each(function () { - headers.push($(this).text()); - }); - - expect(headers).to.eql(['Name', 'Age', 'Position']); - }); - - it('renders the first row with the correct data', function () { - ReactableTestUtils.expectRowText(0, ['Griffin Smith', '', '']); - }); - - it('renders the second row with the correct data', function () { - ReactableTestUtils.expectRowText(1, ['Lee Salminen', '23', '']); - }); - - it('renders the third row with the correct data', function () { - ReactableTestUtils.expectRowText(2, ['', '28', 'Developer']); - }); - }); - - context('with null
', function () { - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table' }, - React.createElement(Reactable.Tr, { className: 'rowClass1', data: { Name: 'Griffin Smith', Age: '18' } }), - React.createElement(Reactable.Tr, { className: 'rowClass2', data: { Age: '23', Name: 'Lee Salminen' } }), - React.createElement(Reactable.Tr, { className: 'rowClass3', data: { Age: '28', Position: 'Developer' } }) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the table', function () { - expect($('table#table.table')).to.exist; - }); - - it('renders the column headers in the table', function () { - var headers = []; - $('thead th').each(function () { - headers.push($(this).text()); - }); - - expect(headers).to.eql(['Name', 'Age', 'Position']); - }); - - it('renders the first row with the correct class name', function () { - ReactableTestUtils.expectRowClass(0, 'rowClass1'); - }); - - it('renders the second row with the correct class name', function () { - ReactableTestUtils.expectRowClass(1, 'rowClass2'); - }); - - it('renders the third row with the correct class name', function () { - ReactableTestUtils.expectRowClass(2, 'rowClass3'); - }); - }); - - describe('adding
s with classNames to the ', function () { - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table' }, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name', className: 'name-1' }, - 'Griffin Smith' - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - '18' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name', className: 'name-2' }, - 'Lee Salminen' - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - '23' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Position', className: 'position' }, - 'Developer' - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - '28' - ) - ) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the first column with the correct class name', function () { - expect($('td.name-1')).to.have.text('Griffin Smith'); - }); - - it('renders the second column with the correct class name', function () { - expect($('td.name-2')).to.have.text('Lee Salminen'); - }); - - it('renders the third column with the correct class name', function () { - expect($('td.position')).to.have.text('Developer'); - }); - }); - }); - - describe('specifying an array of columns', function () { - describe('as strings', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ Name: 'Griffin Smith', Age: '18', HideThis: 'one' }, { Age: '23', Name: 'Lee Salminen', HideThis: 'two' }, { Age: '28', Position: 'Developer' }], columns: ['Name', 'Age'] }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('omits columns not in the list', function () { - var columns = $('tr.reactable-column-header th'); - expect(columns.length).to.equal(2); - expect($(columns[0])).to.have.text('Name'); - expect($(columns[1])).to.have.text('Age'); - }); - - it('adds class name for each column base on its label', function () { - var columns = $('tr.reactable-column-header th'); - expect($(columns[0])).to.have['class']('reactable-th-name'); - expect($(columns[1])).to.have['class']('reactable-th-age'); - }); - }); - - describe('as objects', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ name: 'Griffin Smith', age: '18', HideThis: 'one' }, { age: '23', name: 'Lee Salminen', HideThis: 'two' }, { age: '28', Position: 'Developer' }], columns: [{ key: 'name', label: 'Name' }, { key: 'age', label: 'Age' }] }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('omits columns not in the list', function () { - var columns = $('tr.reactable-column-header th'); - expect(columns.length).to.equal(2); - }); - - it('allows changing the labels of the columns', function () { - var columns = $('tr.reactable-column-header th'); - expect($(columns[0])).to.have.text('Name'); - expect($(columns[1])).to.have.text('Age'); - }); - - it('adds class name for each column base on its key', function () { - var columns = $('tr.reactable-column-header th'); - expect($(columns[0])).to.have['class']('reactable-th-name'); - expect($(columns[1])).to.have['class']('reactable-th-age'); - }); - }); - }); - - describe('specifying columns using a ', function () { - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { id: 'table', data: [{ Name: Reactable.unsafe('Griffin Smith'), Age: '18' }, { Age: '28', Position: Reactable.unsafe('Developer') }, { Age: '23', Name: Reactable.unsafe('Lee Salminen') }] }, - React.createElement( - Reactable.Thead, - null, - React.createElement( - Reactable.Th, - { column: 'Name', id: 'my-name' }, - React.createElement( - 'strong', - null, - 'name' - ) - ) - ) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders only the columns in the Thead', function () { - expect($('#table tbody tr:first td')).to.exist; - expect($('#table thead tr:first th')).to.exist; - }); - - it('renders the contents of the Th', function () { - expect($('#table>thead>tr>th>strong')).to.exist; - }); - - it('passes through the properties of the Th', function () { - expect($('#table>thead>tr>th')).to.have.id('my-name'); - }); - }); - - describe('unsafe() strings', function () { - context('in the
directly', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ Name: Reactable.unsafe('Griffin Smith'), Age: '18' }, { Age: '28', Position: Reactable.unsafe('Developer') }, { Age: '23', Name: Reactable.unsafe('Lee Salminen') }], sortable: ['Name'] }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the HTML in the table cells', function () { - var griffins_name = $('span#griffins-name'); - expect(griffins_name.length).to.equal(1); - expect(griffins_name).to.have.text('Griffin Smith'); - - var lees_name = $('span#lees-name'); - expect(lees_name.length).to.equal(1); - expect(lees_name).to.have.text('Lee Salminen'); - - var who_knows_job = $('span#who-knows-job'); - expect(who_knows_job.length).to.equal(1); - expect(who_knows_job).to.have.text('Developer'); - }); - - it('still allows sorting', function () { - var nameHeader = $('#table thead tr.reactable-column-header th')[0]; - ReactTestUtils.Simulate.click(nameHeader); - - ReactableTestUtils.expectRowText(0, ['28', 'Developer', '']); - ReactableTestUtils.expectRowText(1, ['18', '', 'Griffin Smith']); - ReactableTestUtils.expectRowText(2, ['23', '', 'Lee Salminen']); - }); - }); - - context('in column labels', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ Name: 'Griffin Smith', Age: '18' }, { Age: '23', Name: 'Lee Salminen' }, { Age: '28', Position: 'Developer' }], columns: [{ key: 'Name', label: Reactable.unsafe('Name') }, { key: 'Age', label: Reactable.unsafe('Age') }, { key: 'Position', label: Reactable.unsafe('Position') }] }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the HTML in the column headers', function () { - var headers = []; - $('thead th').each(function () { - headers.push($(this).html()); - }); - - expect(headers).to.eql(['Name', 'Age', 'Position']); - }); - }); - - context('in the s', function () { - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table' }, - React.createElement(Reactable.Tr, { data: { Name: Reactable.unsafe('Griffin Smith'), Age: '18' } }), - React.createElement(Reactable.Tr, { data: { Age: '23', Name: Reactable.unsafe('Lee Salminen') } }), - React.createElement(Reactable.Tr, { data: { Age: '28', Position: Reactable.unsafe('Developer') } }) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the HTML in the table cells', function () { - var griffins_name = $('span#griffins-name'); - expect(griffins_name.length).to.equal(1); - expect(griffins_name).to.have.text('Griffin Smith'); - - var lees_name = $('span#lees-name'); - expect(lees_name.length).to.equal(1); - expect(lees_name).to.have.text('Lee Salminen'); - - var who_knows_job = $('span#who-knows-job'); - expect(who_knows_job.length).to.equal(1); - expect(who_knows_job).to.have.text('Developer'); - }); - }); - - context('in the s', function () { - before(function () { - this.component = ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', columns: ['State', 'Description', 'Tag'], noDataText: 'No matching records found.' }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('shows the "no data" message', function () { - var $text = $('.reactable-no-data').text(); - expect($text).to.eq('No matching records found.'); - }); - }); - - context('when filtered without any matches', function () { - before(function () { - this.component = ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table', - filterable: ['State', 'Tag'], - filterPlaceholder: 'Filter Results', - filterBy: 'xxxxx', - noDataText: 'No matching records found.', - columns: ['State', 'Description', 'Tag'] }, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'State' }, - 'New York' - ), - React.createElement( - Reactable.Td, - { column: 'Description' }, - 'this is some text' - ), - React.createElement( - Reactable.Td, - { column: 'Tag' }, - 'new' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'State' }, - 'New Mexico' - ), - React.createElement( - Reactable.Td, - { column: 'Description' }, - 'lorem ipsum' - ), - React.createElement( - Reactable.Td, - { column: 'Tag' }, - 'old' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'State' }, - 'Colorado' - ), - React.createElement( - Reactable.Td, - { column: 'Description' }, - 'new description that shouldnt match filter' - ), - React.createElement( - Reactable.Td, - { column: 'Tag' }, - 'old' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'State' }, - 'Alaska' - ), - React.createElement( - Reactable.Td, - { column: 'Description' }, - 'bacon' - ), - React.createElement( - Reactable.Td, - { column: 'Tag' }, - 'renewed' - ) - ) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('shows the "no data" message', function () { - var text = $('.reactable-no-data').text(); - expect(text).to.eq('No matching records found.'); - }); - }); - - context('when initialized with an empty array for `data` prop', function () { - before(function () { - this.component = ReactDOM.render(React.createElement(Reactable.Table, { data: [], className: 'table', id: 'table', columns: ['State', 'Description', 'Tag'], noDataText: 'No matching records found.' }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('shows the "no data" message', function () { - var $text = $('.reactable-no-data').text(); - expect($text).to.eq('No matching records found.'); - }); - }); - }); - }); -}); +(function(global,factory){if(typeof define === 'function' && define.amd){define(['exports'],factory);}else if(typeof exports !== 'undefined'){factory(exports);}else {var mod={exports:{}};factory(mod.exports);global.reactable_test = mod.exports;}})(this,function(exports){'use strict';var ReactTestUtils=React.addons.TestUtils;var expect=chai.expect;var ReactableTestUtils={resetTestEnvironment:function resetTestEnvironment(){ReactDOM.unmountComponentAtNode($('div#test-node')[0]);$('div#test-node').remove();}, // Expect the row specified to have the specified class +expectRowClass:function expectRowClass(rowIndex,className){var row=$($('#table tbody.reactable-data tr')[rowIndex]);expect(row).to.have['class'](className);}, // Expect the columns of a the data row specified to have the values in the array as their text values +expectRowText:function expectRowText(rowIndex,textArray){var row=$($('#table tbody.reactable-data tr')[rowIndex]).find('td');expect(row.length).to.equal(textArray.length);for(var i=0;i < row.length;i++) {expect($(row[i])).to.have.text(textArray[i]);}},testNode:function testNode(){var testNode=$('
').attr('id','test-node');$('body').append(testNode);testNode.empty();return testNode[0];}};describe('Reactable',function(){describe('directly passing a data array',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{Name:'Griffin Smith',Age:'18'},{Age:'23',Name:'Lee Salminen'},{Age:'28',Position:'Developer'},{Name:'Leonor Hyatt',Position:null}]}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the table',function(){expect($('table#table.table')).to.exist;});it('renders the column headers in the table',function(){var headers=[];$('thead th').each(function(){headers.push($(this).text());});expect(headers).to.eql(['Name','Age','Position']);});it('renders the first row with the correct data',function(){ReactableTestUtils.expectRowText(0,['Griffin Smith','18','']);});it('renders the second row with the correct data',function(){ReactableTestUtils.expectRowText(1,['Lee Salminen','23','']);});it('renders the third row with the correct data',function(){ReactableTestUtils.expectRowText(2,['','28','Developer']);});it('handles null values',function(){ReactableTestUtils.expectRowText(3,['Leonor Hyatt','','']);});});describe('adding
s to the
s', function () { - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table' }, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name' }, - Reactable.unsafe('Griffin Smith') - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - '18' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name' }, - Reactable.unsafe('Lee Salminen') - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - '23' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Position' }, - Reactable.unsafe('Developer') - ), - React.createElement( - Reactable.Td, - { column: 'Age' }, - '28' - ) - ) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the HTML in the table cells', function () { - var griffins_name = $('span#griffins-name'); - expect(griffins_name.length).to.equal(1); - expect(griffins_name).to.have.text('Griffin Smith'); - - var lees_name = $('span#lees-name'); - expect(lees_name.length).to.equal(1); - expect(lees_name).to.have.text('Lee Salminen'); - - var who_knows_job = $('span#who-knows-job'); - expect(who_knows_job.length).to.equal(1); - expect(who_knows_job).to.have.text('Developer'); - }); - }); - }); - - describe('pagination', function () { - describe('specifying pageButtonLimit', function () { - - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ 'Name': 'Griffin Smith', 'Age': '18' }, { 'Age': '23', 'Name': 'Lee Salminen' }, { 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18' }, { 'Age': '23', 'Name': 'Test Person' }, { 'Name': 'Ian Zhang', 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18', 'Position': 'Software Developer' }, { 'Age': '23', 'Name': 'Lee Salminen' }, { 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18' }, { 'Age': '23', 'Name': 'Lee Salminen' }, { 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18' }, { 'Age': '23', 'Name': 'Test Person' }, { 'Name': 'Ian Zhang', 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18', 'Position': 'Software Developer' }, { 'Age': '23', 'Name': 'Lee Salminen' }, { 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18' }, { 'Age': '23', 'Name': 'Lee Salminen' }, { 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18' }, { 'Age': '23', 'Name': 'Test Person' }, { 'Name': 'Ian Zhang', 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18', 'Position': 'Software Developer' }, { 'Age': '23', 'Name': 'Lee Salminen' }, { 'Age': '28', 'Position': 'Developer' }], itemsPerPage: 2, pageButtonLimit: 8 }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('shows no more page buttons than the pageButtonLimit', function () { - var pageButtons = $('#table tbody.reactable-pagination a.reactable-page-button'); - expect(pageButtons.length).to.equal(8); - }); - }); - describe('specifying itemsPerPage', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ 'Name': 'Griffin Smith', 'Age': '18' }, { 'Age': '23', 'Name': 'Lee Salminen' }, { 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18' }, { 'Age': '23', 'Name': 'Test Person' }, { 'Name': 'Ian Zhang', 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18', 'Position': 'Software Developer' }, { 'Age': '23', 'Name': 'Lee Salminen' }, { 'Age': '28', 'Position': 'Developer' }], itemsPerPage: 4 }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('provides buttons for each page', function () { - var pageButtons = $('#table tbody.reactable-pagination a.reactable-page-button'); - expect(pageButtons.length).to.equal(3); - expect($(pageButtons[0])).to.have.text('1'); - expect($(pageButtons[1])).to.have.text('2'); - expect($(pageButtons[2])).to.have.text('3'); - }); - - it('displays only the first n rows', function () { - expect($('#table tbody.reactable-data tr').length).to.equal(4); - }); - - it('specifies a class on the currently active page', function () { - var activePage = $('#table tbody.reactable-pagination a.reactable-page-button.reactable-current-page'); - expect(activePage.length).to.equal(1); - expect(activePage).to.have.text('1'); - }); - - it('does not show previous button', function () { - var previousButton = $('#table tbody.reactable-pagination a.reactable-previous-page'); - expect(previousButton.length).to.equal(0); - }); - - it('shows next button', function () { - var nextButton = $('#table tbody.reactable-pagination a.reactable-next-page'); - expect(nextButton.length).to.equal(1); - }); - - describe('clicking page buttons', function () { - beforeEach(function () { - var page2 = $('#table tbody.reactable-pagination a.reactable-page-button')[1]; - ReactTestUtils.Simulate.click(page2); - }); - - it('loads the next n rows', function () { - var rows = $('#table tbody.reactable-data tr'); - expect($($(rows[0]).find('td')[0])).to.have.text('Test Person'); - expect($($(rows[1]).find('td')[0])).to.have.text('Ian Zhang'); - expect($($(rows[2]).find('td')[0])).to.have.text('Griffin Smith'); - expect($($(rows[3]).find('td')[0])).to.have.text('Lee Salminen'); - }); - - it('puts an active class on the new active page', function () { - var activePage = $('#table tbody.reactable-pagination a.reactable-page-button.reactable-current-page'); - expect(activePage.length).to.equal(1); - expect(activePage).to.have.text('2'); - }); - - it('can go back to the original page', function () { - var page1 = $('#table tbody.reactable-pagination a.reactable-page-button')[0]; - ReactTestUtils.Simulate.click(page1); - - var rows = $('#table tbody.reactable-data tr'); - expect($($(rows[0]).find('td')[0])).to.have.text('Griffin Smith'); - expect($($(rows[1]).find('td')[0])).to.have.text('Lee Salminen'); - expect($($(rows[2]).find('td')[0])).to.have.text(''); - expect($($(rows[3]).find('td')[0])).to.have.text('Griffin Smith'); - }); - - it('shows previous button', function () { - var previousButton = $('#table tbody.reactable-pagination a.reactable-previous-page'); - expect(previousButton.length).to.equal(1); - }); - }); - }); - - describe('specifying more itemsPerPage than items', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ 'Name': 'Griffin Smith', 'Age': '18' }, { 'Age': '23', 'Name': 'Lee Salminen' }, { 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18' }, { 'Age': '23', 'Name': 'Test Person' }, { 'Name': 'Ian Zhang', 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18', 'Position': 'Software Developer' }, { 'Age': '23', 'Name': 'Lee Salminen' }, { 'Age': '28', 'Position': 'Developer' }], itemsPerPage: 20 }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders all rows', function () { - expect($('#table tbody.reactable-data tr').length).to.equal(9); - }); - - it('provides buttons for 1 page', function () { - var pageButtons = $('#table tbody.reactable-pagination a.reactable-page-button'); - expect(pageButtons.length).to.equal(1); - expect($(pageButtons[0])).to.have.text('1'); - }); - - it('does not show previous and next buttons', function () { - var previousButton = $('#table tbody.reactable-pagination a.reactable-previous-page'); - var nextButton = $('#table tbody.reactable-pagination a.reactable-next-page'); - expect(previousButton.length + nextButton.length).to.equal(0); - }); - }); - - describe('not specifying itemsPerPage', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ 'Name': 'Griffin Smith', 'Age': '18' }, { 'Age': '23', 'Name': 'Lee Salminen' }, { 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18' }, { 'Age': '23', 'Name': 'Test Person' }, { 'Name': 'Ian Zhang', 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18', 'Position': 'Software Developer' }, { 'Age': '23', 'Name': 'Lee Salminen' }, { 'Age': '28', 'Position': 'Developer' }] }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders all rows', function () { - expect($('#table tbody.reactable-data tr').length).to.equal(9); - }); - }); - - describe('specifying 0 itemsPerPage', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ 'Name': 'Griffin Smith', 'Age': '18' }, { 'Age': '23', 'Name': 'Lee Salminen' }, { 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18' }, { 'Age': '23', 'Name': 'Test Person' }, { 'Name': 'Ian Zhang', 'Age': '28', 'Position': 'Developer' }, { 'Name': 'Griffin Smith', 'Age': '18', 'Position': 'Software Developer' }, { 'Age': '23', 'Name': 'Lee Salminen' }, { 'Age': '28', 'Position': 'Developer' }], itemsPerPage: 0 }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders all rows', function () { - expect($('#table tbody.reactable-data tr').length).to.equal(9); - }); - }); - }); - - describe('sorting', function () { - describe('no default sort', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ Name: 'Lee Salminen', Age: '23', Position: 'Programmer' }, { Name: 'Griffin Smith', Age: '18', Position: 'Engineer' }, { Name: 'Ian Zhang', Age: '28', Position: 'Developer' }], - sortable: [{ - column: 'Name', - sortFunction: function sortFunction(a, b) { - // Sort by last name - var nameA = a.split(' '); - var nameB = b.split(' '); - - return nameA[1].localeCompare(nameB[1]); - } - }, 'Age', 'Position'] }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders all rows with no sort', function () { - ReactableTestUtils.expectRowText(0, ['Lee Salminen', '23', 'Programmer']); - ReactableTestUtils.expectRowText(1, ['Griffin Smith', '18', 'Engineer']); - ReactableTestUtils.expectRowText(2, ['Ian Zhang', '28', 'Developer']); - }); - - it('adds reactable-header-sortable to all headers', function () { - var header = $('#table thead tr.reactable-column-header th')[0]; - expect($(header)).to.have['class']('reactable-header-sortable'); - - header = $('#table thead tr.reactable-column-header th')[1]; - expect($(header)).to.have['class']('reactable-header-sortable'); - - header = $('#table thead tr.reactable-column-header th')[2]; - expect($(header)).to.have['class']('reactable-header-sortable'); - }); - - it('sorts by text in ascending order', function () { - var positionHeader = $('#table thead tr.reactable-column-header th')[2]; - ReactTestUtils.Simulate.click(positionHeader); - - ReactableTestUtils.expectRowText(0, ['Ian Zhang', '28', 'Developer']); - ReactableTestUtils.expectRowText(1, ['Griffin Smith', '18', 'Engineer']); - ReactableTestUtils.expectRowText(2, ['Lee Salminen', '23', 'Programmer']); - - // Make sure the headers have the right classes - expect($(positionHeader)).to.have['class']('reactable-header-sort-asc'); - }); - - it('sorts by text in descending order', function () { - var positionHeader = $('#table thead tr.reactable-column-header th')[2]; - ReactTestUtils.Simulate.click(positionHeader); - - ReactableTestUtils.expectRowText(0, ['Lee Salminen', '23', 'Programmer']); - ReactableTestUtils.expectRowText(1, ['Griffin Smith', '18', 'Engineer']); - ReactableTestUtils.expectRowText(2, ['Ian Zhang', '28', 'Developer']); - - // Make sure the headers have the right classes - expect($(positionHeader)).to.have['class']('reactable-header-sort-desc'); - }); - - it('sorts by last name in ascending order', function () { - var nameHeader = $('#table thead tr.reactable-column-header th')[0]; - ReactTestUtils.Simulate.click(nameHeader); - - ReactableTestUtils.expectRowText(0, ['Lee Salminen', '23', 'Programmer']); - ReactableTestUtils.expectRowText(1, ['Griffin Smith', '18', 'Engineer']); - ReactableTestUtils.expectRowText(2, ['Ian Zhang', '28', 'Developer']); - - // Make sure the headers have the right classes - expect($(nameHeader)).to.have['class']('reactable-header-sort-asc'); - }); - - it('sorts by last name in descending order', function () { - var nameHeader = $('#table thead tr.reactable-column-header th')[0]; - ReactTestUtils.Simulate.click(nameHeader); - - ReactableTestUtils.expectRowText(0, ['Ian Zhang', '28', 'Developer']); - ReactableTestUtils.expectRowText(1, ['Griffin Smith', '18', 'Engineer']); - ReactableTestUtils.expectRowText(2, ['Lee Salminen', '23', 'Programmer']); - - // Make sure the headers have the right classes - expect($(nameHeader)).to.have['class']('reactable-header-sort-desc'); - }); - }); - - describe('passing `true` to sortable', function () { - var component; - before(function () { - this.render = function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ Name: 'Lee Salminen', Age: '23', Position: 'Programmer' }, { Name: 'Griffin Smith', Age: '18', Position: 'Engineer' }, { Name: 'Ian Zhang', Age: '28', Position: 'Developer' }], - sortable: true }), ReactableTestUtils.testNode()); - }; - - this.render(); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('sorts by the first column in ascending order', function () { - var nameHeader = $('#table thead tr.reactable-column-header th')[0]; - ReactTestUtils.Simulate.click(nameHeader); - - ReactableTestUtils.expectRowText(0, ['Griffin Smith', '18', 'Engineer']); - ReactableTestUtils.expectRowText(1, ['Ian Zhang', '28', 'Developer']); - ReactableTestUtils.expectRowText(2, ['Lee Salminen', '23', 'Programmer']); - - // Make sure the headers have the right classes - expect($(nameHeader)).to.have['class']('reactable-header-sort-asc'); - }); - - it('sorts by the first column in descending order', function () { - var nameHeader = $('#table thead tr.reactable-column-header th')[0]; - ReactTestUtils.Simulate.click(nameHeader); - - ReactableTestUtils.expectRowText(0, ['Lee Salminen', '23', 'Programmer']); - ReactableTestUtils.expectRowText(1, ['Ian Zhang', '28', 'Developer']); - ReactableTestUtils.expectRowText(2, ['Griffin Smith', '18', 'Engineer']); - - // Make sure the headers have the right classes - expect($(nameHeader)).to.have['class']('reactable-header-sort-desc'); - }); - - it('sorts by the second column in ascending order', function () { - var nameHeader = $('#table thead tr.reactable-column-header th')[1]; - ReactTestUtils.Simulate.click(nameHeader); - - ReactableTestUtils.expectRowText(0, ['Griffin Smith', '18', 'Engineer']); - ReactableTestUtils.expectRowText(1, ['Lee Salminen', '23', 'Programmer']); - ReactableTestUtils.expectRowText(2, ['Ian Zhang', '28', 'Developer']); - - // Make sure the headers have the right classes - expect($(nameHeader)).to.have['class']('reactable-header-sort-asc'); - }); - - it('sorts by the second column in descending order', function () { - var nameHeader = $('#table thead tr.reactable-column-header th')[1]; - ReactTestUtils.Simulate.click(nameHeader); - - ReactableTestUtils.expectRowText(0, ['Ian Zhang', '28', 'Developer']); - ReactableTestUtils.expectRowText(1, ['Lee Salminen', '23', 'Programmer']); - ReactableTestUtils.expectRowText(2, ['Griffin Smith', '18', 'Engineer']); - - // Make sure the headers have the right classes - expect($(nameHeader)).to.have['class']('reactable-header-sort-desc'); - }); - - it('sorts by the third column in ascending order', function () { - var positionHeader = $('#table thead tr.reactable-column-header th')[2]; - ReactTestUtils.Simulate.click(positionHeader); - - ReactableTestUtils.expectRowText(0, ['Ian Zhang', '28', 'Developer']); - ReactableTestUtils.expectRowText(1, ['Griffin Smith', '18', 'Engineer']); - ReactableTestUtils.expectRowText(2, ['Lee Salminen', '23', 'Programmer']); - - // Make sure the headers have the right classes - expect($(positionHeader)).to.have['class']('reactable-header-sort-asc'); - }); - - it('sorts by the third column in descending order', function () { - var positionHeader = $('#table thead tr.reactable-column-header th')[2]; - ReactTestUtils.Simulate.click(positionHeader); - - ReactableTestUtils.expectRowText(0, ['Lee Salminen', '23', 'Programmer']); - ReactableTestUtils.expectRowText(1, ['Griffin Smith', '18', 'Engineer']); - ReactableTestUtils.expectRowText(2, ['Ian Zhang', '28', 'Developer']); - - // Make sure the headers have the right classes - expect($(positionHeader)).to.have['class']('reactable-header-sort-desc'); - }); - - it('Keeps the same sort after rerendering', function () { - expect(this.render).to.not['throw'](Error); - - ReactableTestUtils.expectRowText(0, ['Lee Salminen', '23', 'Programmer']); - ReactableTestUtils.expectRowText(1, ['Griffin Smith', '18', 'Engineer']); - ReactableTestUtils.expectRowText(2, ['Ian Zhang', '28', 'Developer']); - }); - }); - - describe('default sort', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ Name: 'Lee Salminen', Age: '23', Position: 'Programmer' }, { Name: 'Griffin Smith', Age: '18', Position: 'Engineer' }, { Name: 'Ian Zhang', Age: '28', Position: 'Developer' }], - sortable: [{ - column: 'Name', - sortFunction: function sortFunction(a, b) { - // Sort by last name - var nameA = a.split(' '); - var nameB = b.split(' '); - - return nameA[1].localeCompare(nameB[1]); - } - }, 'Age', 'Position'], - defaultSort: { column: 'Age', direction: 'desc' } }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders all rows sorted by default column age descending', function () { - ReactableTestUtils.expectRowText(0, ['Ian Zhang', '28', 'Developer']); - ReactableTestUtils.expectRowText(1, ['Lee Salminen', '23', 'Programmer']); - ReactableTestUtils.expectRowText(2, ['Griffin Smith', '18', 'Engineer']); - }); - }); - - describe('default sort no direction specified', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ Name: 'Lee Salminen', Age: '23', Position: 'Programmer' }, { Name: 'Griffin Smith', Age: '18', Position: 'Engineer' }, { Name: 'Ian Zhang', Age: '28', Position: 'Developer' }], - sortable: [{ - column: 'Name', - sortFunction: function sortFunction(a, b) { - // Sort by last name - var nameA = a.split(' '); - var nameB = b.split(' '); - - return nameA[1].localeCompare(nameB[1]); - } - }, 'Age', 'Position'], - defaultSort: 'Age' }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders all rows sorted by default column age ascending', function () { - ReactableTestUtils.expectRowText(0, ['Griffin Smith', '18', 'Engineer']); - ReactableTestUtils.expectRowText(1, ['Lee Salminen', '23', 'Programmer']); - ReactableTestUtils.expectRowText(2, ['Ian Zhang', '28', 'Developer']); - }); - }); - - describe('unsortable column', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ Name: 'Lee Salminen', Age: '23', Position: 'Programmer' }, { Name: 'Griffin Smith', Age: '18', Position: 'Engineer' }, { Name: 'Ian Zhang', Age: '28', Position: 'Developer' }], - sortable: ['Age', 'Position'] }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('leaves columns unsorted', function () { - var nameHeader = $('#table thead tr.reactable-column-header th')[0]; - ReactTestUtils.Simulate.click(nameHeader); - - ReactableTestUtils.expectRowText(0, ['Lee Salminen', '23', 'Programmer']); - ReactableTestUtils.expectRowText(1, ['Griffin Smith', '18', 'Engineer']); - ReactableTestUtils.expectRowText(2, ['Ian Zhang', '28', 'Developer']); - }); - }); - - [Reactable.Sort.Numeric, Reactable.Sort.NumericInteger].forEach(function (method) { - describe('numeric sort', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ Count: '23' }, { Count: '18' }, { Count: '28' }, { Count: '1.23' }, { Count: 'a' }, { Count: 'z' }, { Count: '123' }], - columns: [{ key: 'Count', sortable: method }] }), ReactableTestUtils.testNode()); - }); - - after(function () { - ReactableTestUtils.resetTestEnvironment(); - }); - - it('sorts columns numerically', function () { - var sortHeader = $('#table thead tr.reactable-column-header th')[0]; - ReactTestUtils.Simulate.click(sortHeader); - - ReactableTestUtils.expectRowText(0, ['1.23']); - ReactableTestUtils.expectRowText(1, ['18']); - ReactableTestUtils.expectRowText(2, ['23']); - ReactableTestUtils.expectRowText(3, ['28']); - ReactableTestUtils.expectRowText(4, ['123']); - ReactableTestUtils.expectRowText(5, ['a']); - ReactableTestUtils.expectRowText(6, ['z']); - }); - }); - }); - - describe('numeric sort with Tr and Td specified', function () { - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { - className: 'table', - id: 'table', - columns: [{ key: 'Count', sortable: Reactable.Sort.Numeric }] }, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Count' }, - '23' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Count' }, - '18' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Count' }, - '28' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Count' }, - '1.23' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Count' }, - 'a' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Count' }, - 'z' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Count' }, - '123' - ) - ) - ), ReactableTestUtils.testNode()); - }); - - after(function () { - ReactableTestUtils.resetTestEnvironment(); - }); - - it('sorts columns numerically', function () { - var sortHeader = $('#table thead tr.reactable-column-header th')[0]; - ReactTestUtils.Simulate.click(sortHeader); - - ReactableTestUtils.expectRowText(0, ['1.23']); - ReactableTestUtils.expectRowText(1, ['18']); - ReactableTestUtils.expectRowText(2, ['23']); - ReactableTestUtils.expectRowText(3, ['28']); - ReactableTestUtils.expectRowText(4, ['123']); - ReactableTestUtils.expectRowText(5, ['a']); - ReactableTestUtils.expectRowText(6, ['z']); - }); - }); - - describe('numeric sort with Tr and Td specified and custom value', function () { - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { - className: 'table', - id: 'table', - columns: [{ key: 'Count', sortable: Reactable.Sort.Numeric }] }, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Count', value: 23 }, - 'twenty-three' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Count', value: 18 }, - 'eighteen' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Count', value: 28 }, - 'twenty-eight' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Count', value: 1.23 }, - 'one point two three' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Count', value: 'a' }, - 'a' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Count', value: 'z' }, - 'z' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Count', value: 123 }, - 'one hundred twenty-three' - ) - ) - ), ReactableTestUtils.testNode()); - }); - - after(function () { - ReactableTestUtils.resetTestEnvironment(); - }); - - it('sorts columns numerically', function () { - var sortHeader = $('#table thead tr.reactable-column-header th')[0]; - ReactTestUtils.Simulate.click(sortHeader); - - ReactableTestUtils.expectRowText(0, ['one point two three']); - ReactableTestUtils.expectRowText(1, ['eighteen']); - ReactableTestUtils.expectRowText(2, ['twenty-three']); - ReactableTestUtils.expectRowText(3, ['twenty-eight']); - ReactableTestUtils.expectRowText(4, ['one hundred twenty-three']); - ReactableTestUtils.expectRowText(5, ['a']); - ReactableTestUtils.expectRowText(6, ['z']); - }); - }); - - describe('currency sort', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ Price: '1.25' }, { Price: '$1.01' }, { Price: '1' }, { Price: '$10,000' }, { Price: '$10,500' }, { Price: '$10' }, { Price: 'a' }, { Price: 'z' }, { Price: '$2' }, { Price: '$.5' }, { Price: '$0.60' }, { Price: '.1' }], - columns: [{ key: 'Price', sortable: Reactable.Sort.Currency }] }), ReactableTestUtils.testNode()); - }); - - after(function () { - ReactableTestUtils.resetTestEnvironment(); - }); - - it('sorts columns numerically. parsing out currency symbols', function () { - var sortHeader = $('#table thead tr.reactable-column-header th')[0]; - ReactTestUtils.Simulate.click(sortHeader); - - ReactableTestUtils.expectRowText(0, ['.1']); - ReactableTestUtils.expectRowText(1, ['$.5']); - ReactableTestUtils.expectRowText(2, ['$0.60']); - ReactableTestUtils.expectRowText(3, ['1']); - ReactableTestUtils.expectRowText(4, ['$1.01']); - ReactableTestUtils.expectRowText(5, ['1.25']); - ReactableTestUtils.expectRowText(6, ['$2']); - ReactableTestUtils.expectRowText(7, ['$10']); - ReactableTestUtils.expectRowText(8, ['$10,000']); - ReactableTestUtils.expectRowText(9, ['$10,500']); - ReactableTestUtils.expectRowText(10, ['a']); - ReactableTestUtils.expectRowText(11, ['z']); - }); - }); - - describe('date sort', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ 'Date': '1/1/2014 11:00 AM' }, { 'Date': '1/1/2013 11:00 AM' }, { 'Date': '1/1/2014 4:30 PM' }, { 'Date': '4/3/2013' }, { 'Date': 'a' }, { 'Date': 'z' }], - columns: [{ key: 'Date', sortable: Reactable.Sort.Date }] }), ReactableTestUtils.testNode()); - }); - - after(function () { - ReactableTestUtils.resetTestEnvironment(); - }); - - it('sorts columns by date', function () { - var sortHeader = $('#table thead tr.reactable-column-header th')[0]; - ReactTestUtils.Simulate.click(sortHeader); - - ReactableTestUtils.expectRowText(0, ['1/1/2013 11:00 AM']); - ReactableTestUtils.expectRowText(1, ['4/3/2013']); - ReactableTestUtils.expectRowText(2, ['1/1/2014 11:00 AM']); - ReactableTestUtils.expectRowText(3, ['1/1/2014 4:30 PM']); - ReactableTestUtils.expectRowText(4, ['a']); - ReactableTestUtils.expectRowText(5, ['z']); - }); - }); - - describe('case insensitive sorting', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ 'Name': 'Lee Salminen' }, { 'Name': 'Griffin Smith' }, { 'Name': 'Ian Zhang' }, { 'Name': 'lee Salminen' }, { 'Name': 'griffin smith' }, { 'Name': 'Ian zhang' }], - columns: [{ key: 'Name', sortable: Reactable.Sort.CaseInsensitive }] }), ReactableTestUtils.testNode()); - }); - - after(function () { - ReactableTestUtils.resetTestEnvironment(); - }); - - it('sorts columns by value - case insensitive', function () { - var sortHeader = $('#table thead tr.reactable-column-header th')[0]; - ReactTestUtils.Simulate.click(sortHeader); - - ReactableTestUtils.expectRowText(0, ['Griffin Smith']); - ReactableTestUtils.expectRowText(1, ['griffin smith']); - ReactableTestUtils.expectRowText(2, ['Ian Zhang']); - ReactableTestUtils.expectRowText(3, ['Ian zhang']); - ReactableTestUtils.expectRowText(4, ['Lee Salminen']); - ReactableTestUtils.expectRowText(5, ['lee Salminen']); - }); - }); - - describe('custom sort with React Components', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ 'Rank': React.createElement( - 'span', - { className: '3' }, - 'Third' - ) }, { 'Rank': React.createElement( - 'span', - { className: '1' }, - 'First' - ) }, { 'Rank': React.createElement( - 'span', - { className: '2' }, - 'Second' - ) }], - columns: [{ - key: 'Rank', sortable: function sortable(a, b) { - // sort based on classname - return a.props.className.localeCompare(b.props.className); - } - }] }), ReactableTestUtils.testNode()); - }); - - after(function () { - ReactableTestUtils.resetTestEnvironment(); - }); - - it('sorts columns by value', function () { - var sortHeader = $('#table thead tr.reactable-column-header th')[0]; - ReactTestUtils.Simulate.click(sortHeader); - - ReactableTestUtils.expectRowText(0, ['First']); - ReactableTestUtils.expectRowText(1, ['Second']); - ReactableTestUtils.expectRowText(2, ['Third']); - }); - }); - - describe('sorts and calls onSort callback via props', function () { - var sortColumn = null; - - var callback = function callback(sortObject) { - console.log(sortObject); - sortColumn = sortObject.column; - }; - - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ 'Rank': React.createElement( - 'span', - { className: '3' }, - 'Third' - ) }, { 'Rank': React.createElement( - 'span', - { className: '1' }, - 'First' - ) }, { 'Rank': React.createElement( - 'span', - { className: '2' }, - 'Second' - ) }], - columns: [{ - key: 'Rank', sortable: function sortable(a, b) { - // sort based on classname - return a.props.className.localeCompare(b.props.className); - } - }], - onSort: callback }), ReactableTestUtils.testNode()); - }); - - after(function () { - ReactableTestUtils.resetTestEnvironment(); - }); - - it('returns currentSort object to callback for utilization', function () { - var sortHeader = $('#table thead tr.reactable-column-header th')[0]; - ReactTestUtils.Simulate.click(sortHeader); - - console.log(sortColumn); - expect(sortColumn).to.equal('Rank'); - }); - }); - }); - - describe('filtering', function () { - describe('filtering with javascript objects for data', function () { - var data = [{ name: "Lee SomeoneElse", age: 18 }, { name: "Lee Salminen", age: 23 }, { name: "No Age", age: null }]; - before(function () { - ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table', - filterable: ['Name', 'Age'] }, - React.createElement( - Reactable.Tr, - null, - React.createElement(Reactable.Td, { column: 'Name', data: data[0].name }), - React.createElement(Reactable.Td, { column: 'Age', data: data[0].age }) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement(Reactable.Td, { column: 'Name', data: data[1].name }), - React.createElement(Reactable.Td, { column: 'Age', data: data[1].age }) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement(Reactable.Td, { column: 'Name', data: data[2].name }), - React.createElement(Reactable.Td, { column: 'Age', data: data[2].age }) - ) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('filters case insensitive on specified columns', function () { - var $filter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); - - $filter.val('lee'); - React.addons.TestUtils.Simulate.keyUp($filter[0]); - - ReactableTestUtils.expectRowText(0, ['Lee SomeoneElse', '18']); - ReactableTestUtils.expectRowText(1, ['Lee Salminen', '23']); - }); - }); - - describe('basic case-insensitive filtering', function () { - before(function () { - this.component = ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table', - filterable: ['State', 'Tag'], - filterPlaceholder: 'Filter Results', - columns: ['State', 'Description', 'Tag'] }, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'State' }, - 'New York' - ), - React.createElement( - Reactable.Td, - { column: 'Description' }, - 'this is some text' - ), - React.createElement( - Reactable.Td, - { column: 'Tag' }, - 'new' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'State' }, - 'New Mexico' - ), - React.createElement( - Reactable.Td, - { column: 'Description' }, - 'lorem ipsum' - ), - React.createElement( - Reactable.Td, - { column: 'Tag' }, - 'old' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'State' }, - 'Colorado' - ), - React.createElement( - Reactable.Td, - { column: 'Description' }, - 'new description that shouldnt match filter' - ), - React.createElement( - Reactable.Td, - { column: 'Tag' }, - 'old' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'State' }, - 'Alaska' - ), - React.createElement( - Reactable.Td, - { column: 'Description' }, - 'bacon' - ), - React.createElement( - Reactable.Td, - { column: 'Tag' }, - 'renewed' - ) - ) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - context('from the filterer field', function () { - it('filters case insensitive on specified columns', function () { - var $filter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); - - $filter.val('new'); - React.addons.TestUtils.Simulate.keyUp($filter[0]); - - ReactableTestUtils.expectRowText(0, ['New York', 'this is some text', 'new']); - ReactableTestUtils.expectRowText(1, ['New Mexico', 'lorem ipsum', 'old']); - ReactableTestUtils.expectRowText(2, ['Alaska', 'bacon', 'renewed']); - }); - - it('filter placeholder is set', function () { - var $filter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); - expect($filter.attr("placeholder")).to.equal('Filter Results'); - }); - }); - - context('from the function', function () { - before(function () { - this.component.filterBy('york'); - }); - - it('applies the filtering', function () { - ReactableTestUtils.expectRowText(0, ['New York', 'this is some text', 'new']); - }); - - it('updates the value of the filterer', function () { - var $filter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); - expect($filter).to.have.value('york'); - }); - }); - - context('from filterBy prop', function () { - before(function () { - ReactableTestUtils.resetTestEnvironment(); - - var ParentComponent = React.createClass({ - displayName: 'ParentComponent', - - getInitialState: function getInitialState() { - return { customFilterText: 'new' }; - }, - - handleChange: function handleChange(event) { - this.setState({ customFilterText: event.target.value }); - }, - - render: function render() { - return React.createElement( - 'div', - null, - React.createElement('input', { type: 'text', ref: 'customFilterInput', id: 'customFilterInput', value: this.state.customFilterText, onChange: this.handleChange }), - React.createElement( - Reactable.Table, - { className: 'table', id: 'table', - filterable: ['State', 'Tag'], - filterPlaceholder: 'Filter Results', - filterBy: this.state.customFilterText, - columns: ['State', 'Description', 'Tag'] }, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'State' }, - 'New York' - ), - React.createElement( - Reactable.Td, - { column: 'Description' }, - 'this is some text' - ), - React.createElement( - Reactable.Td, - { column: 'Tag' }, - 'new' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'State' }, - 'New Mexico' - ), - React.createElement( - Reactable.Td, - { column: 'Description' }, - 'lorem ipsum' - ), - React.createElement( - Reactable.Td, - { column: 'Tag' }, - 'old' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'State' }, - 'Colorado' - ), - React.createElement( - Reactable.Td, - { column: 'Description' }, - 'new description that shouldnt match filter' - ), - React.createElement( - Reactable.Td, - { column: 'Tag' }, - 'old' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'State' }, - 'Alaska' - ), - React.createElement( - Reactable.Td, - { column: 'Description' }, - 'bacon' - ), - React.createElement( - Reactable.Td, - { column: 'Tag' }, - 'renewed' - ) - ) - ) - ); - } - }); - - this.component = ReactDOM.render(React.createElement(ParentComponent), ReactableTestUtils.testNode()); - }); - - it('filters case insensitive on specified columns', function () { - ReactableTestUtils.expectRowText(0, ['New York', 'this is some text', 'new']); - ReactableTestUtils.expectRowText(1, ['New Mexico', 'lorem ipsum', 'old']); - ReactableTestUtils.expectRowText(2, ['Alaska', 'bacon', 'renewed']); - var $builtInFilter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); - expect($builtInFilter).to.have.value('new'); - - // Simulate changing input on parent component and re-rendering Reactable.Table with new props. - var node = this.component.refs.customFilterInput; - node.value = 'alaska'; - ReactTestUtils.Simulate.change(customFilterInput); - - ReactableTestUtils.expectRowText(0, ['Alaska', 'bacon', 'renewed']); - expect($builtInFilter).to.have.value('alaska'); - }); - }); - }); - - context('filtering with prop and hiding filter input', function () { - before(function () { - this.component = ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table', - filterable: ['State', 'Tag'], - filterPlaceholder: 'Filter Results', - filterBy: 'new', - hideFilterInput: true, - columns: ['State', 'Description', 'Tag'] }, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'State' }, - 'New York' - ), - React.createElement( - Reactable.Td, - { column: 'Description' }, - 'this is some text' - ), - React.createElement( - Reactable.Td, - { column: 'Tag' }, - 'new' - ) - ), - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'State' }, - 'New Mexico' - ), - React.createElement( - Reactable.Td, - { column: 'Description' }, - 'lorem ipsum' - ), - React.createElement( - Reactable.Td, - { column: 'Tag' }, - 'old' - ) - ) - ), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('does not render the filter input box', function () { - expect($('#table thead tr.reactable-filterer input.reactable-filter-input').length).to.equal(0); - }); - }); - - context('filtering and pagination together', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ 'State': 'New York', 'Description': 'this is some text', 'Tag': 'new' }, { 'State': 'New Mexico', 'Description': 'lorem ipsum', 'Tag': 'old' }, { 'State': 'Colorado', 'Description': 'new description that shouldn\'t match filter', - 'Tag': 'old' }, { 'State': 'Alaska', 'Description': 'bacon', 'Tag': 'renewed' }], - filterable: ['State', 'Tag'], - columns: ['State', 'Description', 'Tag'], - itemsPerPage: 2 }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - afterEach(function () { - var $filter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); - $filter.val(''); - React.addons.TestUtils.Simulate.keyUp($filter[0]); - }); - - it('updates the pagination links', function () { - var $filter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); - - $filter.val('colorado'); - React.addons.TestUtils.Simulate.keyUp($filter[0]); - - var pageButtons = $('#table tbody.reactable-pagination a.reactable-page-button'); - expect(pageButtons.length).to.equal(1); - expect($(pageButtons[0])).to.have.text('1'); - }); - - it('updates the current page if necessary', function () { - var $filter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); - var $pageButtons = $('#table tbody.reactable-pagination a.reactable-page-button'); - - // Go to the last page - React.addons.TestUtils.Simulate.click($pageButtons[1]); - - // Then filter so that that page doesn't exist anymore - $filter.val('colorado'); - React.addons.TestUtils.Simulate.keyUp($filter[0]); - - ReactableTestUtils.expectRowText(0, ['Colorado', "new description that shouldn't match filter", 'old']); - var activePage = $('#table tbody.reactable-pagination ' + 'a.reactable-page-button.reactable-current-page'); - expect(activePage.length).to.equal(1); - expect(activePage).to.have.text('1'); - }); - }); - }); - - describe('directly passing a data array with non-string data', function () { - before(function () { - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table', data: [{ Name: 'Griffin Smith', Age: 18 }, { Age: 23, Name: { toString: function toString() { - return 'Lee Salminen'; - } } }, { Age: 28.45, Position: 'Developer' }] }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('renders the table', function () { - expect($('table#table.table')).to.exist; - }); - - it('renders the column headers in the table', function () { - var headers = []; - $('thead th').each(function () { - headers.push($(this).text()); - }); - - expect(headers).to.eql(['Name', 'Age', 'Position']); - }); - - it('renders the first row with the correct data', function () { - ReactableTestUtils.expectRowText(0, ['Griffin Smith', '18', '']); - }); - - it('renders the second row with the correct data', function () { - ReactableTestUtils.expectRowText(1, ['Lee Salminen', '23', '']); - }); - - it('renders the third row with the correct data', function () { - ReactableTestUtils.expectRowText(2, ['', '28.45', 'Developer']); - }); - }); - - describe('multiple tables on a page', function () { - before(function () { - this.parentTestNode = ReactableTestUtils.testNode(); - this.testNode1 = $('
').attr('id', 'test-node-1'); - this.testNode2 = $('
').attr('id', 'test-node-2'); - - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table1', data: [{ Name: 'Griffin Smith', Age: '18' }, { Age: '23', Name: 'Lee Salminen' }, { Age: '28', Position: 'Developer' }] }), this.testNode1[0]); - - ReactDOM.render(React.createElement(Reactable.Table, { className: 'table', id: 'table2', data: [{ Moniker: 'Griffin Smith', Elderliness: '18' }, { Elderliness: '23', Moniker: 'Lee Salminen' }, { Elderliness: '28', Title: 'Developer' }] }), this.testNode2[0]); - }); - - after(function () { - $(this.parentTestNode).empty().remove(); - }); - - it('renders the column headers in the first table', function () { - var headers = []; - this.testNode1.find('thead th').each(function () { - headers.push($(this).text()); - }); - - expect(headers).to.eql(['Name', 'Age', 'Position']); - }); - - it('renders the column headers in the second table', function () { - var headers = []; - this.testNode2.find('thead th').each(function () { - headers.push($(this).text()); - }); - - expect(headers).to.eql(['Moniker', 'Elderliness', 'Title']); - }); - }); - - describe('handleClick callbacks', function () { - before(function () { - this.clicked = false; - - ReactDOM.render(React.createElement( - Reactable.Table, - { className: 'table', id: 'table' }, - React.createElement( - Reactable.Tr, - null, - React.createElement( - Reactable.Td, - { column: 'Name', handleClick: (function () { - this.clicked = true; - }).bind(this) }, - React.createElement( - 'b', - null, - 'Griffin Smith' - ) - ) - ) - ), ReactableTestUtils.testNode()); - - ReactTestUtils.Simulate.click($('td')[0]); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('calls the callbacks on click', function () { - expect(this.clicked).to.eq(true); - }); - }); - - describe('table with no data', function () { - context('when noDataText prop is null', function () { - before(function () { - this.component = ReactDOM.render(React.createElement(Reactable.Table, { data: [], columns: ['State', 'Description', 'Tag'] }), ReactableTestUtils.testNode()); - }); - - after(ReactableTestUtils.resetTestEnvironment); - - it('does not render the reactable-no-data element', function () { - expect($('.reactable-no-data').length).to.eq(0); - }); - }); - - context('when initialized without
',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table'},React.createElement(Reactable.Tr,{data:{Name:'Griffin Smith',Age:'18'}}),React.createElement(Reactable.Tr,{data:{Age:'23',Name:'Lee Salminen'}}),React.createElement(Reactable.Tr,{data:{Age:'28',Position:'Developer'}})),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the table',function(){expect($('table#table.table')).to.exist;});it('renders the column headers in the table',function(){var headers=[];$('thead th').each(function(){headers.push($(this).text());});expect(headers).to.eql(['Name','Age','Position']);});it('renders the first row with the correct data',function(){ReactableTestUtils.expectRowText(0,['Griffin Smith','18','']);});it('renders the second row with the correct data',function(){ReactableTestUtils.expectRowText(1,['Lee Salminen','23','']);});it('renders the third row with the correct data',function(){ReactableTestUtils.expectRowText(2,['','28','Developer']);});});describe('adding s',function(){context('with only one s',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table'},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name'},React.createElement('b',null,'Griffin Smith')),React.createElement(Reactable.Td,{column:'Age'},React.createElement('em',null,'18'))),null,React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Position'},React.createElement('b',null,'Developer')),React.createElement(Reactable.Td,{column:'Age'},React.createElement('em',null,'28')))),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the table',function(){expect($('table#table.table')).to.exist;});it('renders the column headers in the table',function(){var headers=[];$('thead th').each(function(){headers.push($(this).text());});expect(headers).to.eql(['Name','Age','Position']);});it('renders the first row with the correct data',function(){ReactableTestUtils.expectRowText(0,['Griffin Smith','18','']);});it('renders the second row with the correct data',function(){ReactableTestUtils.expectRowText(1,['','28','Developer']);});});});describe('Adding a ',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',sortable:['Name'],filterable:['Name','Age']},React.createElement(Reactable.Tr,{className:'rowClass1',data:{Name:'Griffin Smith',Age:'18'}}),React.createElement(Reactable.Tr,{className:'rowClass2',data:{Age:'23',Name:'Lee Salminen'}}),React.createElement(Reactable.Tr,{className:'rowClass3',data:{Age:'28',Position:'Developer'}}),React.createElement(Reactable.Tfoot,{id:'tfoot'},React.createElement('tr',null,React.createElement('td',{id:'tfoot-stuff'},'Test')))),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the table',function(){expect($('#table')).to.exist;});it('renders the regular data rows',function(){ReactableTestUtils.expectRowText(0,['Griffin Smith','18','']);ReactableTestUtils.expectRowText(1,['Lee Salminen','23','']);ReactableTestUtils.expectRowText(2,['','28','Developer']);});it('renders the tfoot',function(){expect($('#tfoot')).to.exist;});it('renders the children of the tfoot',function(){expect($('#tfoot-stuff')).to.exist;});context('when sorting',function(){before(function(){ReactTestUtils.Simulate.click($('th')[0]);});it('leaves the tfoot alone',function(){expect($('table :last-child')).to.match('tfoot');});});context('when filtering',function(){before(function(){var $filter=$('.reactable-filter-input');$filter.val('griffin');ReactTestUtils.Simulate.keyUp($filter[0]);});it('leaves the tfoot alone',function(){expect($('table :last-child')).to.match('tfoot');});});});describe('passing through HTML props',function(){describe('adding s with className to the
s to the
',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table'},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name'},'Griffin Smith')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name'},'Lee Salminen')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name'},'Ian Zhang'))),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the table',function(){expect($('table#table.table')).to.exist;});it('renders the column headers in the table',function(){var headers=[];$('thead th').each(function(){headers.push($(this).text());});expect(headers).to.eql(['Name']);});it('renders the first row with the correct data',function(){ReactableTestUtils.expectRowText(0,['Griffin Smith']);});it('renders the second row with the correct data',function(){ReactableTestUtils.expectRowText(1,['Lee Salminen']);});it('renders the third row with the correct data',function(){ReactableTestUtils.expectRowText(2,['Ian Zhang']);});});context('with multiple s',function(){context('with plain text',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table'},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name'},'Griffin Smith'),React.createElement(Reactable.Td,{column:'Age'},'18')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name'},'Lee Salminen'),React.createElement(Reactable.Td,{column:'Age'},'23')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Position'},'Developer'),React.createElement(Reactable.Td,{column:'Age'},'28'))),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the table',function(){expect($('table#table.table')).to.exist;});it('renders the column headers in the table',function(){var headers=[];$('thead th').each(function(){headers.push($(this).text());});expect(headers).to.eql(['Name','Age','Position']);});it('renders the first row with the correct data',function(){ReactableTestUtils.expectRowText(0,['Griffin Smith','18','']);});it('renders the second row with the correct data',function(){ReactableTestUtils.expectRowText(1,['Lee Salminen','23','']);});it('renders the third row with the correct data',function(){ReactableTestUtils.expectRowText(2,['','28','Developer']);});});});context('with React.DOM nodes inside',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table'},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name'},React.createElement('b',null,'Griffin Smith')),React.createElement(Reactable.Td,{column:'Age'},React.createElement('em',null,'18'))),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name'},React.createElement('b',null,'Lee Salminen')),React.createElement(Reactable.Td,{column:'Age'},React.createElement('em',null,'23'))),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Position'},React.createElement('b',null,'Developer')),React.createElement(Reactable.Td,{column:'Age'},React.createElement('em',null,'28')))),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the table',function(){expect($('table#table.table')).to.exist;});it('renders the column headers in the table',function(){var headers=[];$('thead th').each(function(){headers.push($(this).text());});expect(headers).to.eql(['Name','Age','Position']);});it('renders the first row with the correct data',function(){ReactableTestUtils.expectRowText(0,['Griffin Smith','18','']);});it('renders the second row with the correct data',function(){ReactableTestUtils.expectRowText(1,['Lee Salminen','23','']);});it('renders the third row with the correct data',function(){ReactableTestUtils.expectRowText(2,['','28','Developer']);});});context('with null s',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table'},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name'},React.createElement('b',null,'Griffin Smith')),null),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name'},React.createElement('b',null,'Lee Salminen')),React.createElement(Reactable.Td,{column:'Age'},React.createElement('em',null,'23'))),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Position'},React.createElement('b',null,'Developer')),React.createElement(Reactable.Td,{column:'Age'},React.createElement('em',null,'28')))),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the table',function(){expect($('table#table.table')).to.exist;});it('renders the column headers in the table',function(){var headers=[];$('thead th').each(function(){headers.push($(this).text());});expect(headers).to.eql(['Name','Age','Position']);});it('renders the first row with the correct data',function(){ReactableTestUtils.expectRowText(0,['Griffin Smith','','']);});it('renders the second row with the correct data',function(){ReactableTestUtils.expectRowText(1,['Lee Salminen','23','']);});it('renders the third row with the correct data',function(){ReactableTestUtils.expectRowText(2,['','28','Developer']);});});context('with null
',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table'},React.createElement(Reactable.Tr,{className:'rowClass1',data:{Name:'Griffin Smith',Age:'18'}}),React.createElement(Reactable.Tr,{className:'rowClass2',data:{Age:'23',Name:'Lee Salminen'}}),React.createElement(Reactable.Tr,{className:'rowClass3',data:{Age:'28',Position:'Developer'}})),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the table',function(){expect($('table#table.table')).to.exist;});it('renders the column headers in the table',function(){var headers=[];$('thead th').each(function(){headers.push($(this).text());});expect(headers).to.eql(['Name','Age','Position']);});it('renders the first row with the correct class name',function(){ReactableTestUtils.expectRowClass(0,'rowClass1');});it('renders the second row with the correct class name',function(){ReactableTestUtils.expectRowClass(1,'rowClass2');});it('renders the third row with the correct class name',function(){ReactableTestUtils.expectRowClass(2,'rowClass3');});});describe('adding
s with classNames to the ',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table'},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name',className:'name-1'},'Griffin Smith'),React.createElement(Reactable.Td,{column:'Age'},'18')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name',className:'name-2'},'Lee Salminen'),React.createElement(Reactable.Td,{column:'Age'},'23')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Position',className:'position'},'Developer'),React.createElement(Reactable.Td,{column:'Age'},'28'))),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the first column with the correct class name',function(){expect($('td.name-1')).to.have.text('Griffin Smith');});it('renders the second column with the correct class name',function(){expect($('td.name-2')).to.have.text('Lee Salminen');});it('renders the third column with the correct class name',function(){expect($('td.position')).to.have.text('Developer');});});});describe('specifying an array of columns',function(){describe('as strings',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{Name:'Griffin Smith',Age:'18',HideThis:'one'},{Age:'23',Name:'Lee Salminen',HideThis:'two'},{Age:'28',Position:'Developer'}],columns:['Name','Age']}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('omits columns not in the list',function(){var columns=$('tr.reactable-column-header th');expect(columns.length).to.equal(2);expect($(columns[0])).to.have.text('Name');expect($(columns[1])).to.have.text('Age');});it('adds class name for each column base on its label',function(){var columns=$('tr.reactable-column-header th');expect($(columns[0])).to.have['class']('reactable-th-name');expect($(columns[1])).to.have['class']('reactable-th-age');});});describe('as objects',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{name:'Griffin Smith',age:'18',HideThis:'one'},{age:'23',name:'Lee Salminen',HideThis:'two'},{age:'28',Position:'Developer'}],columns:[{key:'name',label:'Name'},{key:'age',label:'Age'}]}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('omits columns not in the list',function(){var columns=$('tr.reactable-column-header th');expect(columns.length).to.equal(2);});it('allows changing the labels of the columns',function(){var columns=$('tr.reactable-column-header th');expect($(columns[0])).to.have.text('Name');expect($(columns[1])).to.have.text('Age');});it('adds class name for each column base on its key',function(){var columns=$('tr.reactable-column-header th');expect($(columns[0])).to.have['class']('reactable-th-name');expect($(columns[1])).to.have['class']('reactable-th-age');});});});describe('specifying columns using a ',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{id:'table',data:[{Name:Reactable.unsafe('Griffin Smith'),Age:'18'},{Age:'28',Position:Reactable.unsafe('Developer')},{Age:'23',Name:Reactable.unsafe('Lee Salminen')}]},React.createElement(Reactable.Thead,null,React.createElement(Reactable.Th,{column:'Name',id:'my-name'},React.createElement('strong',null,'name')))),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders only the columns in the Thead',function(){expect($('#table tbody tr:first td')).to.exist;expect($('#table thead tr:first th')).to.exist;});it('renders the contents of the Th',function(){expect($('#table>thead>tr>th>strong')).to.exist;});it('passes through the properties of the Th',function(){expect($('#table>thead>tr>th')).to.have.id('my-name');});});describe('unsafe() strings',function(){context('in the
directly',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{Name:Reactable.unsafe('Griffin Smith'),Age:'18'},{Age:'28',Position:Reactable.unsafe('Developer')},{Age:'23',Name:Reactable.unsafe('Lee Salminen')}],sortable:['Name']}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the HTML in the table cells',function(){var griffins_name=$('span#griffins-name');expect(griffins_name.length).to.equal(1);expect(griffins_name).to.have.text('Griffin Smith');var lees_name=$('span#lees-name');expect(lees_name.length).to.equal(1);expect(lees_name).to.have.text('Lee Salminen');var who_knows_job=$('span#who-knows-job');expect(who_knows_job.length).to.equal(1);expect(who_knows_job).to.have.text('Developer');});it('still allows sorting',function(){var nameHeader=$('#table thead tr.reactable-column-header th')[0];ReactTestUtils.Simulate.click(nameHeader);ReactableTestUtils.expectRowText(0,['28','Developer','']);ReactableTestUtils.expectRowText(1,['18','','Griffin Smith']);ReactableTestUtils.expectRowText(2,['23','','Lee Salminen']);});});context('in column labels',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{Name:'Griffin Smith',Age:'18'},{Age:'23',Name:'Lee Salminen'},{Age:'28',Position:'Developer'}],columns:[{key:'Name',label:Reactable.unsafe('Name')},{key:'Age',label:Reactable.unsafe('Age')},{key:'Position',label:Reactable.unsafe('Position')}]}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the HTML in the column headers',function(){var headers=[];$('thead th').each(function(){headers.push($(this).html());});expect(headers).to.eql(['Name','Age','Position']);});});context('in the s',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table'},React.createElement(Reactable.Tr,{data:{Name:Reactable.unsafe('Griffin Smith'),Age:'18'}}),React.createElement(Reactable.Tr,{data:{Age:'23',Name:Reactable.unsafe('Lee Salminen')}}),React.createElement(Reactable.Tr,{data:{Age:'28',Position:Reactable.unsafe('Developer')}})),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the HTML in the table cells',function(){var griffins_name=$('span#griffins-name');expect(griffins_name.length).to.equal(1);expect(griffins_name).to.have.text('Griffin Smith');var lees_name=$('span#lees-name');expect(lees_name.length).to.equal(1);expect(lees_name).to.have.text('Lee Salminen');var who_knows_job=$('span#who-knows-job');expect(who_knows_job.length).to.equal(1);expect(who_knows_job).to.have.text('Developer');});});context('in the s',function(){before(function(){this.component = ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',columns:['State','Description','Tag'],noDataText:'No matching records found.'}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('shows the "no data" message',function(){var $text=$('.reactable-no-data').text();expect($text).to.eq('No matching records found.');});});context('when filtered without any matches',function(){before(function(){this.component = ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',filterable:['State','Tag'],filterPlaceholder:'Filter Results',filterBy:'xxxxx',noDataText:'No matching records found.',columns:['State','Description','Tag']},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'New York'),React.createElement(Reactable.Td,{column:'Description'},'this is some text'),React.createElement(Reactable.Td,{column:'Tag'},'new')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'New Mexico'),React.createElement(Reactable.Td,{column:'Description'},'lorem ipsum'),React.createElement(Reactable.Td,{column:'Tag'},'old')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'Colorado'),React.createElement(Reactable.Td,{column:'Description'},'new description that shouldnt match filter'),React.createElement(Reactable.Td,{column:'Tag'},'old')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'Alaska'),React.createElement(Reactable.Td,{column:'Description'},'bacon'),React.createElement(Reactable.Td,{column:'Tag'},'renewed'))),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('shows the "no data" message',function(){var text=$('.reactable-no-data').text();expect(text).to.eq('No matching records found.');});});context('when initialized with an empty array for `data` prop',function(){before(function(){this.component = ReactDOM.render(React.createElement(Reactable.Table,{data:[],className:'table',id:'table',columns:['State','Description','Tag'],noDataText:'No matching records found.'}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('shows the "no data" message',function(){var $text=$('.reactable-no-data').text();expect($text).to.eq('No matching records found.');});});});});}); diff --git a/lib/reactable/filterer.js b/lib/reactable/filterer.js index b88f7f28..0903ae6c 100644 --- a/lib/reactable/filterer.js +++ b/lib/reactable/filterer.js @@ -39,10 +39,20 @@ var FiltererInput = (function (_React$Component) { }, { key: 'render', value: function render() { + var value = ''; + if (typeof this.props.value != 'string') { + for (var key in this.props.value) { + value += key + ': ' + this.props.value[key] + ', '; + } + value = value.slice(0, -2); + } else { + value = this.props.value; + } + value = value.trim(); return _react2['default'].createElement('input', { type: 'text', className: 'reactable-filter-input', placeholder: this.props.placeholder, - value: this.props.value, + value: value, onKeyUp: this.onChange.bind(this), onChange: this.onChange.bind(this) }); } diff --git a/lib/reactable/lib/array_intersect.js b/lib/reactable/lib/array_intersect.js new file mode 100644 index 00000000..f3b7a50f --- /dev/null +++ b/lib/reactable/lib/array_intersect.js @@ -0,0 +1,47 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.array_intersect = array_intersect; + +function array_intersect() { + var i, + all, + shortest, + nShortest, + n, + len, + ret = [], + obj = {}, + nOthers; + nOthers = arguments.length - 1; + nShortest = arguments[0].length; + shortest = 0; + for (i = 0; i <= nOthers; i++) { + n = arguments[i].length; + if (n < nShortest) { + shortest = i; + nShortest = n; + } + } + + for (i = 0; i <= nOthers; i++) { + n = i === shortest ? 0 : i || shortest; //Read the shortest array first. Read the first array instead of the shortest + len = arguments[n].length; + for (var j = 0; j < len; j++) { + var elem = arguments[n][j]; + if (obj[elem] === i - 1) { + if (i === nOthers) { + ret.push(elem); + obj[elem] = 0; + } else { + obj[elem] = i; + } + } else if (i === 0) { + obj[elem] = 0; + } + } + } + return ret; +} diff --git a/lib/reactable/table.js b/lib/reactable/table.js index ccc3c079..62cfc4e7 100644 --- a/lib/reactable/table.js +++ b/lib/reactable/table.js @@ -24,6 +24,8 @@ var _libFilter_props_from = require('./lib/filter_props_from'); var _libExtract_data_from = require('./lib/extract_data_from'); +var _libArray_intersect = require('./lib/array_intersect'); + var _unsafe = require('./unsafe'); var _thead = require('./thead'); @@ -257,24 +259,90 @@ var Table = (function (_React$Component) { }, { key: 'applyFilter', value: function applyFilter(filter, children) { - // Helper function to apply filter text to a list of table rows - filter = filter.toLowerCase(); - var matchedChildren = []; + if (typeof filter === 'string') { + // Helper function to apply filter text to a list of table rows + filter = filter.toLowerCase(); + var matchedChildren = []; - for (var i = 0; i < children.length; i++) { - var data = children[i].props.data; + for (var i = 0; i < children.length; i++) { + var data = children[i].props.data; - for (var j = 0; j < this.props.filterable.length; j++) { - var filterColumn = this.props.filterable[j]; + for (var j = 0; j < this.props.filterable.length; j++) { + var filterColumn = this.props.filterable[j]; - if (typeof data[filterColumn] !== 'undefined' && (0, _libExtract_data_from.extractDataFrom)(data, filterColumn).toString().toLowerCase().indexOf(filter) > -1) { - matchedChildren.push(children[i]); - break; + if (typeof data[filterColumn] !== 'undefined' && (0, _libExtract_data_from.extractDataFrom)(data, filterColumn).toString().toLowerCase().indexOf(filter) > -1) { + matchedChildren.push(children[i]); + break; + } } } + + return matchedChildren; + } else { + var _ret = (function () { + + var filterCount = Object.keys(filter).length; + var matchedChildren = []; + + for (var filterColumn in filter) { + var val = filter[filterColumn]; + for (var i = 0; i < children.length; i++) { + var data = children[i].props.data; + if (typeof data[filterColumn] !== 'undefined' && (0, _libExtract_data_from.extractDataFrom)(data, filterColumn).toString().toLowerCase().indexOf(val) > -1) { + matchedChildren.push(children[i]); + } + } + } + + if (filterCount > 1) { + var result = []; + return { + v: matchedChildren.map(function (children) { + var occurrences = matchedChildren.filter(function (value) { + return value.key === children.key; + }).length; + if (occurrences == filterCount) { + return children; + } + }) + }; + } else { + return { + v: matchedChildren + }; + } + })(); + + if (typeof _ret === 'object') return _ret.v; } + } + }, { + key: 'onFilter', + value: function onFilter(filters) { + if (typeof filters === 'string' && filters.indexOf(':') != -1) { + (function () { + var filterObj = {}; + filters = filters.trim(); + var col = ''; + var val = ''; + filters = filters.split(','); + + filters.map(function (filter) { + filter = filter.split(':'); + if (filter[0]) { + col = filter[0].trim(); + } + if (filter[1]) { + val = filter[1].trim(); + } + filterObj[col] = val; + }); - return matchedChildren; + filters = filterObj; + })(); + } + + this.setState({ filter: filters }); } }, { key: 'sortByCurrentSort', @@ -337,7 +405,7 @@ var Table = (function (_React$Component) { this.setState({ currentSort: currentSort }); this.sortByCurrentSort(); - if (this.props.onSort) { + if (typeof this.props.onSort === 'function') { this.props.onSort(currentSort); } } @@ -463,9 +531,7 @@ var Table = (function (_React$Component) { props, columns && columns.length > 0 ? _react2['default'].createElement(_thead.Thead, { columns: columns, filtering: filtering, - onFilter: function (filter) { - _this.setState({ filter: filter }); - }, + onFilter: this.onFilter.bind(this), filterPlaceholder: this.props.filterPlaceholder, currentFilter: this.state.filter, sort: this.state.currentSort, diff --git a/src/reactable/filterer.jsx b/src/reactable/filterer.jsx index a21cdb19..c9b45b2a 100644 --- a/src/reactable/filterer.jsx +++ b/src/reactable/filterer.jsx @@ -2,16 +2,27 @@ import React from 'react'; import ReactDOM from 'react-dom'; export class FiltererInput extends React.Component { + onChange() { - this.props.onFilter(ReactDOM.findDOMNode(this).value); + this.props.onFilter(ReactDOM.findDOMNode(this).value) } render() { + let value = '' + if (typeof(this.props.value) != 'string') { + for(let key in this.props.value) { + value += key + ': ' + this.props.value[key] + ', ' + } + value = value.slice(0, -2) + } else { + value = this.props.value + } + value = value.trim() return ( ); @@ -35,4 +46,3 @@ export class Filterer extends React.Component { ); } }; - diff --git a/src/reactable/lib/array_intersect.jsx b/src/reactable/lib/array_intersect.jsx new file mode 100644 index 00000000..0179de20 --- /dev/null +++ b/src/reactable/lib/array_intersect.jsx @@ -0,0 +1,32 @@ +export function array_intersect() { + var i, all, shortest, nShortest, n, len, ret = [], obj={}, nOthers; + nOthers = arguments.length-1; + nShortest = arguments[0].length; + shortest = 0; + for (i=0; i<=nOthers; i++){ + n = arguments[i].length; + if (n -1 - ) { - matchedChildren.push(children[i]); - break; - } + if (typeof(data[filterColumn]) !== 'undefined' && extractDataFrom(data, filterColumn).toString().toLowerCase().indexOf(filter) > -1) { + matchedChildren.push(children[i]); + break; } + } } return matchedChildren; + } else { + + let filterCount = Object + .keys(filter) + .length + let matchedChildren = [] + + for (let filterColumn in filter) { + let val = filter[filterColumn] + for (let i = 0; i < children.length; i++) { + let data = children[i].props.data; + if (typeof(data[filterColumn]) !== 'undefined' && extractDataFrom(data, filterColumn).toString().toLowerCase().indexOf(val) > -1) { + matchedChildren.push(children[i]); + } + } + } + + if (filterCount > 1) { + let result = [] + return matchedChildren.map(function (children) { + let occurrences = matchedChildren.filter(function (value) { + return value.key === children.key; + }).length + if (occurrences == filterCount) {return children} + }) + } else {return matchedChildren;} + } + } + + onFilter(filters) { + if( typeof(filters) === 'string' && filters.indexOf(':') != -1) { + let filterObj = {} + filters = filters.trim() + let col = '' + let val = '' + filters = filters.split(',') + + filters.map(function(filter) { + filter = filter.split(':') + if(filter[0]) { col = filter[0].trim() } + if(filter[1]) { val = filter[1].trim() } + filterObj[col] = val + }) + + filters = filterObj + } + + this.setState({ filter: filters }); } sortByCurrentSort() { @@ -430,9 +477,7 @@ export class Table extends React.Component { {columns && columns.length > 0 ? { - this.setState({ filter: filter }); - }} + onFilter={this.onFilter.bind(this)} filterPlaceholder={this.props.filterPlaceholder} currentFilter={this.state.filter} sort={this.state.currentSort} diff --git a/tests/reactable_test.jsx b/tests/reactable_test.jsx index 7b157440..4b982298 100644 --- a/tests/reactable_test.jsx +++ b/tests/reactable_test.jsx @@ -1533,7 +1533,7 @@ describe('Reactable', function() { ReactableTestUtils.expectRowText(2, ['Third']); }); }); - + describe('sorts and calls onSort callback via props', function(){ var sortColumn = null; @@ -1553,7 +1553,7 @@ describe('Reactable', function() { // sort based on classname return a.props.className.localeCompare(b.props.className); } - }]} + }]} onSort={ callback }/>, ReactableTestUtils.testNode() ); @@ -1664,6 +1664,45 @@ describe('Reactable', function() { }) }); + context('from the filterer field with column and val', function() { + it('filters case insensitive on specified columns', function() { + var $filter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); + + $filter.val('Tag: renewed'); + React.addons.TestUtils.Simulate.keyUp($filter[0]); + + ReactableTestUtils.expectRowText(0, ['Alaska', 'bacon', 'renewed']); + }); + + it('filter placeholder is set', function(){ + var $filter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); + expect($filter.attr("placeholder")).to.equal('Filter Results'); + }) + }); + + context('from the filterer field with multiple columns and vals', function() { + it('filters case insensitive on specified columns', function() { + var $filter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); + + $filter.val('Tag: renewed, State: alaska, Description: bacon'); + React.addons.TestUtils.Simulate.keyUp($filter[0]); + ReactableTestUtils.expectRowText(0, ['Alaska', 'bacon', 'renewed']); + }); + + it('filters case insensitive on specified columns', function() { + var $filter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); + + $filter.val('Tag: renewed, State: New, Description: bacon'); + React.addons.TestUtils.Simulate.keyUp($filter[0]); + ReactableTestUtils.expectRowText(0, ''); + }); + + it('filter placeholder is set', function(){ + var $filter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); + expect($filter.attr("placeholder")).to.equal('Filter Results'); + }) + }); + context('from the function', function() { before(function() { this.component.filterBy('york'); @@ -1679,7 +1718,7 @@ describe('Reactable', function() { }); }); - context('from filterBy prop', function() { + context('from string filterBy prop', function() { before(function() { ReactableTestUtils.resetTestEnvironment(); @@ -1748,6 +1787,143 @@ describe('Reactable', function() { expect($builtInFilter).to.have.value('alaska'); }); }); + + context('from 1 column Object filterBy prop', function() { + before(function() { + ReactableTestUtils.resetTestEnvironment(); + + var ParentComponent = React.createClass({ + getInitialState: function() { + return {customFilterText:{'Tag': 'new'}} + }, + + handleChange(event) { + this.setState({customFilterText: event.target.value}); + }, + + render: function() { + return ( +
+ + + + New York + this is some text + new + + + New Mexico + lorem ipsum + old + + + Colorado + + new description that shouldnt match filter + + old + + + Alaska + bacon + renewed + + +
+ ); + } + }) + + this.component = ReactDOM.render(React.createElement(ParentComponent), ReactableTestUtils.testNode()); + }); + + it('filters case insensitive on specified columns', function() { + ReactableTestUtils.expectRowText(0, ['New York', 'this is some text', 'new']); + var $builtInFilter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); + expect($builtInFilter).to.have.value('Tag: new'); + + // Simulate changing input on parent component and re-rendering Reactable.Table with new props. + var node = this.component.refs.customFilterInput; + node.value = 'alaska'; + ReactTestUtils.Simulate.change(customFilterInput); + + ReactableTestUtils.expectRowText(0, ['Alaska', 'bacon', 'renewed']); + expect($builtInFilter).to.have.value('alaska'); + }); + }); + + context('from multiple columns object filterBy prop', function() { + before(function() { + ReactableTestUtils.resetTestEnvironment(); + + var ParentComponent = React.createClass({ + getInitialState: function() { + return {customFilterText:{'Tag': 'new', 'State': 'alaska'}} + }, + + handleChange(event) { + this.setState({customFilterText: event.target.value}); + }, + + render: function() { + return ( +
+ + + + New York + this is some text + new + + + New Mexico + lorem ipsum + old + + + Colorado + + new description that shouldnt match filter + + old + + + Alaska + bacon + renewed + + +
+ ); + } + }) + + this.component = ReactDOM.render(React.createElement(ParentComponent), ReactableTestUtils.testNode()); + }); + + it('filters case insensitive on specified columns', function() { + ReactableTestUtils.expectRowText(0, ['Alaska', 'bacon', 'renewed']); + + var $builtInFilter = $('#table thead tr.reactable-filterer input.reactable-filter-input'); + expect($builtInFilter).to.have.value('Tag: new, State: alaska'); + + // Simulate changing input on parent component and re-rendering Reactable.Table with new props. + var node = this.component.refs.customFilterInput; + node.value = 'alaska'; + ReactTestUtils.Simulate.change(customFilterInput); + + ReactableTestUtils.expectRowText(0, ['Alaska', 'bacon', 'renewed']); + expect($builtInFilter).to.have.value('alaska'); + }); + }); }); context('filtering with prop and hiding filter input', function() {
s',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table'},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name'},Reactable.unsafe('Griffin Smith')),React.createElement(Reactable.Td,{column:'Age'},'18')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name'},Reactable.unsafe('Lee Salminen')),React.createElement(Reactable.Td,{column:'Age'},'23')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Position'},Reactable.unsafe('Developer')),React.createElement(Reactable.Td,{column:'Age'},'28'))),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the HTML in the table cells',function(){var griffins_name=$('span#griffins-name');expect(griffins_name.length).to.equal(1);expect(griffins_name).to.have.text('Griffin Smith');var lees_name=$('span#lees-name');expect(lees_name.length).to.equal(1);expect(lees_name).to.have.text('Lee Salminen');var who_knows_job=$('span#who-knows-job');expect(who_knows_job.length).to.equal(1);expect(who_knows_job).to.have.text('Developer');});});});describe('pagination',function(){describe('specifying pageButtonLimit',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{'Name':'Griffin Smith','Age':'18'},{'Age':'23','Name':'Lee Salminen'},{'Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18'},{'Age':'23','Name':'Test Person'},{'Name':'Ian Zhang','Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18','Position':'Software Developer'},{'Age':'23','Name':'Lee Salminen'},{'Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18'},{'Age':'23','Name':'Lee Salminen'},{'Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18'},{'Age':'23','Name':'Test Person'},{'Name':'Ian Zhang','Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18','Position':'Software Developer'},{'Age':'23','Name':'Lee Salminen'},{'Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18'},{'Age':'23','Name':'Lee Salminen'},{'Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18'},{'Age':'23','Name':'Test Person'},{'Name':'Ian Zhang','Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18','Position':'Software Developer'},{'Age':'23','Name':'Lee Salminen'},{'Age':'28','Position':'Developer'}],itemsPerPage:2,pageButtonLimit:8}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('shows no more page buttons than the pageButtonLimit',function(){var pageButtons=$('#table tbody.reactable-pagination a.reactable-page-button');expect(pageButtons.length).to.equal(8);});});describe('specifying itemsPerPage',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{'Name':'Griffin Smith','Age':'18'},{'Age':'23','Name':'Lee Salminen'},{'Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18'},{'Age':'23','Name':'Test Person'},{'Name':'Ian Zhang','Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18','Position':'Software Developer'},{'Age':'23','Name':'Lee Salminen'},{'Age':'28','Position':'Developer'}],itemsPerPage:4}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('provides buttons for each page',function(){var pageButtons=$('#table tbody.reactable-pagination a.reactable-page-button');expect(pageButtons.length).to.equal(3);expect($(pageButtons[0])).to.have.text('1');expect($(pageButtons[1])).to.have.text('2');expect($(pageButtons[2])).to.have.text('3');});it('displays only the first n rows',function(){expect($('#table tbody.reactable-data tr').length).to.equal(4);});it('specifies a class on the currently active page',function(){var activePage=$('#table tbody.reactable-pagination a.reactable-page-button.reactable-current-page');expect(activePage.length).to.equal(1);expect(activePage).to.have.text('1');});it('does not show previous button',function(){var previousButton=$('#table tbody.reactable-pagination a.reactable-previous-page');expect(previousButton.length).to.equal(0);});it('shows next button',function(){var nextButton=$('#table tbody.reactable-pagination a.reactable-next-page');expect(nextButton.length).to.equal(1);});describe('clicking page buttons',function(){beforeEach(function(){var page2=$('#table tbody.reactable-pagination a.reactable-page-button')[1];ReactTestUtils.Simulate.click(page2);});it('loads the next n rows',function(){var rows=$('#table tbody.reactable-data tr');expect($($(rows[0]).find('td')[0])).to.have.text('Test Person');expect($($(rows[1]).find('td')[0])).to.have.text('Ian Zhang');expect($($(rows[2]).find('td')[0])).to.have.text('Griffin Smith');expect($($(rows[3]).find('td')[0])).to.have.text('Lee Salminen');});it('puts an active class on the new active page',function(){var activePage=$('#table tbody.reactable-pagination a.reactable-page-button.reactable-current-page');expect(activePage.length).to.equal(1);expect(activePage).to.have.text('2');});it('can go back to the original page',function(){var page1=$('#table tbody.reactable-pagination a.reactable-page-button')[0];ReactTestUtils.Simulate.click(page1);var rows=$('#table tbody.reactable-data tr');expect($($(rows[0]).find('td')[0])).to.have.text('Griffin Smith');expect($($(rows[1]).find('td')[0])).to.have.text('Lee Salminen');expect($($(rows[2]).find('td')[0])).to.have.text('');expect($($(rows[3]).find('td')[0])).to.have.text('Griffin Smith');});it('shows previous button',function(){var previousButton=$('#table tbody.reactable-pagination a.reactable-previous-page');expect(previousButton.length).to.equal(1);});});});describe('specifying more itemsPerPage than items',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{'Name':'Griffin Smith','Age':'18'},{'Age':'23','Name':'Lee Salminen'},{'Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18'},{'Age':'23','Name':'Test Person'},{'Name':'Ian Zhang','Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18','Position':'Software Developer'},{'Age':'23','Name':'Lee Salminen'},{'Age':'28','Position':'Developer'}],itemsPerPage:20}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders all rows',function(){expect($('#table tbody.reactable-data tr').length).to.equal(9);});it('provides buttons for 1 page',function(){var pageButtons=$('#table tbody.reactable-pagination a.reactable-page-button');expect(pageButtons.length).to.equal(1);expect($(pageButtons[0])).to.have.text('1');});it('does not show previous and next buttons',function(){var previousButton=$('#table tbody.reactable-pagination a.reactable-previous-page');var nextButton=$('#table tbody.reactable-pagination a.reactable-next-page');expect(previousButton.length + nextButton.length).to.equal(0);});});describe('not specifying itemsPerPage',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{'Name':'Griffin Smith','Age':'18'},{'Age':'23','Name':'Lee Salminen'},{'Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18'},{'Age':'23','Name':'Test Person'},{'Name':'Ian Zhang','Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18','Position':'Software Developer'},{'Age':'23','Name':'Lee Salminen'},{'Age':'28','Position':'Developer'}]}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders all rows',function(){expect($('#table tbody.reactable-data tr').length).to.equal(9);});});describe('specifying 0 itemsPerPage',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{'Name':'Griffin Smith','Age':'18'},{'Age':'23','Name':'Lee Salminen'},{'Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18'},{'Age':'23','Name':'Test Person'},{'Name':'Ian Zhang','Age':'28','Position':'Developer'},{'Name':'Griffin Smith','Age':'18','Position':'Software Developer'},{'Age':'23','Name':'Lee Salminen'},{'Age':'28','Position':'Developer'}],itemsPerPage:0}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders all rows',function(){expect($('#table tbody.reactable-data tr').length).to.equal(9);});});});describe('sorting',function(){describe('no default sort',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{Name:'Lee Salminen',Age:'23',Position:'Programmer'},{Name:'Griffin Smith',Age:'18',Position:'Engineer'},{Name:'Ian Zhang',Age:'28',Position:'Developer'}],sortable:[{column:'Name',sortFunction:function sortFunction(a,b){ // Sort by last name +var nameA=a.split(' ');var nameB=b.split(' ');return nameA[1].localeCompare(nameB[1]);}},'Age','Position']}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders all rows with no sort',function(){ReactableTestUtils.expectRowText(0,['Lee Salminen','23','Programmer']);ReactableTestUtils.expectRowText(1,['Griffin Smith','18','Engineer']);ReactableTestUtils.expectRowText(2,['Ian Zhang','28','Developer']);});it('adds reactable-header-sortable to all headers',function(){var header=$('#table thead tr.reactable-column-header th')[0];expect($(header)).to.have['class']('reactable-header-sortable');header = $('#table thead tr.reactable-column-header th')[1];expect($(header)).to.have['class']('reactable-header-sortable');header = $('#table thead tr.reactable-column-header th')[2];expect($(header)).to.have['class']('reactable-header-sortable');});it('sorts by text in ascending order',function(){var positionHeader=$('#table thead tr.reactable-column-header th')[2];ReactTestUtils.Simulate.click(positionHeader);ReactableTestUtils.expectRowText(0,['Ian Zhang','28','Developer']);ReactableTestUtils.expectRowText(1,['Griffin Smith','18','Engineer']);ReactableTestUtils.expectRowText(2,['Lee Salminen','23','Programmer']); // Make sure the headers have the right classes +expect($(positionHeader)).to.have['class']('reactable-header-sort-asc');});it('sorts by text in descending order',function(){var positionHeader=$('#table thead tr.reactable-column-header th')[2];ReactTestUtils.Simulate.click(positionHeader);ReactableTestUtils.expectRowText(0,['Lee Salminen','23','Programmer']);ReactableTestUtils.expectRowText(1,['Griffin Smith','18','Engineer']);ReactableTestUtils.expectRowText(2,['Ian Zhang','28','Developer']); // Make sure the headers have the right classes +expect($(positionHeader)).to.have['class']('reactable-header-sort-desc');});it('sorts by last name in ascending order',function(){var nameHeader=$('#table thead tr.reactable-column-header th')[0];ReactTestUtils.Simulate.click(nameHeader);ReactableTestUtils.expectRowText(0,['Lee Salminen','23','Programmer']);ReactableTestUtils.expectRowText(1,['Griffin Smith','18','Engineer']);ReactableTestUtils.expectRowText(2,['Ian Zhang','28','Developer']); // Make sure the headers have the right classes +expect($(nameHeader)).to.have['class']('reactable-header-sort-asc');});it('sorts by last name in descending order',function(){var nameHeader=$('#table thead tr.reactable-column-header th')[0];ReactTestUtils.Simulate.click(nameHeader);ReactableTestUtils.expectRowText(0,['Ian Zhang','28','Developer']);ReactableTestUtils.expectRowText(1,['Griffin Smith','18','Engineer']);ReactableTestUtils.expectRowText(2,['Lee Salminen','23','Programmer']); // Make sure the headers have the right classes +expect($(nameHeader)).to.have['class']('reactable-header-sort-desc');});});describe('passing `true` to sortable',function(){var component;before(function(){this.render = function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{Name:'Lee Salminen',Age:'23',Position:'Programmer'},{Name:'Griffin Smith',Age:'18',Position:'Engineer'},{Name:'Ian Zhang',Age:'28',Position:'Developer'}],sortable:true}),ReactableTestUtils.testNode());};this.render();});after(ReactableTestUtils.resetTestEnvironment);it('sorts by the first column in ascending order',function(){var nameHeader=$('#table thead tr.reactable-column-header th')[0];ReactTestUtils.Simulate.click(nameHeader);ReactableTestUtils.expectRowText(0,['Griffin Smith','18','Engineer']);ReactableTestUtils.expectRowText(1,['Ian Zhang','28','Developer']);ReactableTestUtils.expectRowText(2,['Lee Salminen','23','Programmer']); // Make sure the headers have the right classes +expect($(nameHeader)).to.have['class']('reactable-header-sort-asc');});it('sorts by the first column in descending order',function(){var nameHeader=$('#table thead tr.reactable-column-header th')[0];ReactTestUtils.Simulate.click(nameHeader);ReactableTestUtils.expectRowText(0,['Lee Salminen','23','Programmer']);ReactableTestUtils.expectRowText(1,['Ian Zhang','28','Developer']);ReactableTestUtils.expectRowText(2,['Griffin Smith','18','Engineer']); // Make sure the headers have the right classes +expect($(nameHeader)).to.have['class']('reactable-header-sort-desc');});it('sorts by the second column in ascending order',function(){var nameHeader=$('#table thead tr.reactable-column-header th')[1];ReactTestUtils.Simulate.click(nameHeader);ReactableTestUtils.expectRowText(0,['Griffin Smith','18','Engineer']);ReactableTestUtils.expectRowText(1,['Lee Salminen','23','Programmer']);ReactableTestUtils.expectRowText(2,['Ian Zhang','28','Developer']); // Make sure the headers have the right classes +expect($(nameHeader)).to.have['class']('reactable-header-sort-asc');});it('sorts by the second column in descending order',function(){var nameHeader=$('#table thead tr.reactable-column-header th')[1];ReactTestUtils.Simulate.click(nameHeader);ReactableTestUtils.expectRowText(0,['Ian Zhang','28','Developer']);ReactableTestUtils.expectRowText(1,['Lee Salminen','23','Programmer']);ReactableTestUtils.expectRowText(2,['Griffin Smith','18','Engineer']); // Make sure the headers have the right classes +expect($(nameHeader)).to.have['class']('reactable-header-sort-desc');});it('sorts by the third column in ascending order',function(){var positionHeader=$('#table thead tr.reactable-column-header th')[2];ReactTestUtils.Simulate.click(positionHeader);ReactableTestUtils.expectRowText(0,['Ian Zhang','28','Developer']);ReactableTestUtils.expectRowText(1,['Griffin Smith','18','Engineer']);ReactableTestUtils.expectRowText(2,['Lee Salminen','23','Programmer']); // Make sure the headers have the right classes +expect($(positionHeader)).to.have['class']('reactable-header-sort-asc');});it('sorts by the third column in descending order',function(){var positionHeader=$('#table thead tr.reactable-column-header th')[2];ReactTestUtils.Simulate.click(positionHeader);ReactableTestUtils.expectRowText(0,['Lee Salminen','23','Programmer']);ReactableTestUtils.expectRowText(1,['Griffin Smith','18','Engineer']);ReactableTestUtils.expectRowText(2,['Ian Zhang','28','Developer']); // Make sure the headers have the right classes +expect($(positionHeader)).to.have['class']('reactable-header-sort-desc');});it('Keeps the same sort after rerendering',function(){expect(this.render).to.not['throw'](Error);ReactableTestUtils.expectRowText(0,['Lee Salminen','23','Programmer']);ReactableTestUtils.expectRowText(1,['Griffin Smith','18','Engineer']);ReactableTestUtils.expectRowText(2,['Ian Zhang','28','Developer']);});});describe('default sort',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{Name:'Lee Salminen',Age:'23',Position:'Programmer'},{Name:'Griffin Smith',Age:'18',Position:'Engineer'},{Name:'Ian Zhang',Age:'28',Position:'Developer'}],sortable:[{column:'Name',sortFunction:function sortFunction(a,b){ // Sort by last name +var nameA=a.split(' ');var nameB=b.split(' ');return nameA[1].localeCompare(nameB[1]);}},'Age','Position'],defaultSort:{column:'Age',direction:'desc'}}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders all rows sorted by default column age descending',function(){ReactableTestUtils.expectRowText(0,['Ian Zhang','28','Developer']);ReactableTestUtils.expectRowText(1,['Lee Salminen','23','Programmer']);ReactableTestUtils.expectRowText(2,['Griffin Smith','18','Engineer']);});});describe('default sort no direction specified',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{Name:'Lee Salminen',Age:'23',Position:'Programmer'},{Name:'Griffin Smith',Age:'18',Position:'Engineer'},{Name:'Ian Zhang',Age:'28',Position:'Developer'}],sortable:[{column:'Name',sortFunction:function sortFunction(a,b){ // Sort by last name +var nameA=a.split(' ');var nameB=b.split(' ');return nameA[1].localeCompare(nameB[1]);}},'Age','Position'],defaultSort:'Age'}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders all rows sorted by default column age ascending',function(){ReactableTestUtils.expectRowText(0,['Griffin Smith','18','Engineer']);ReactableTestUtils.expectRowText(1,['Lee Salminen','23','Programmer']);ReactableTestUtils.expectRowText(2,['Ian Zhang','28','Developer']);});});describe('unsortable column',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{Name:'Lee Salminen',Age:'23',Position:'Programmer'},{Name:'Griffin Smith',Age:'18',Position:'Engineer'},{Name:'Ian Zhang',Age:'28',Position:'Developer'}],sortable:['Age','Position']}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('leaves columns unsorted',function(){var nameHeader=$('#table thead tr.reactable-column-header th')[0];ReactTestUtils.Simulate.click(nameHeader);ReactableTestUtils.expectRowText(0,['Lee Salminen','23','Programmer']);ReactableTestUtils.expectRowText(1,['Griffin Smith','18','Engineer']);ReactableTestUtils.expectRowText(2,['Ian Zhang','28','Developer']);});});[Reactable.Sort.Numeric,Reactable.Sort.NumericInteger].forEach(function(method){describe('numeric sort',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{Count:'23'},{Count:'18'},{Count:'28'},{Count:'1.23'},{Count:'a'},{Count:'z'},{Count:'123'}],columns:[{key:'Count',sortable:method}]}),ReactableTestUtils.testNode());});after(function(){ReactableTestUtils.resetTestEnvironment();});it('sorts columns numerically',function(){var sortHeader=$('#table thead tr.reactable-column-header th')[0];ReactTestUtils.Simulate.click(sortHeader);ReactableTestUtils.expectRowText(0,['1.23']);ReactableTestUtils.expectRowText(1,['18']);ReactableTestUtils.expectRowText(2,['23']);ReactableTestUtils.expectRowText(3,['28']);ReactableTestUtils.expectRowText(4,['123']);ReactableTestUtils.expectRowText(5,['a']);ReactableTestUtils.expectRowText(6,['z']);});});});describe('numeric sort with Tr and Td specified',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',columns:[{key:'Count',sortable:Reactable.Sort.Numeric}]},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Count'},'23')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Count'},'18')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Count'},'28')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Count'},'1.23')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Count'},'a')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Count'},'z')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Count'},'123'))),ReactableTestUtils.testNode());});after(function(){ReactableTestUtils.resetTestEnvironment();});it('sorts columns numerically',function(){var sortHeader=$('#table thead tr.reactable-column-header th')[0];ReactTestUtils.Simulate.click(sortHeader);ReactableTestUtils.expectRowText(0,['1.23']);ReactableTestUtils.expectRowText(1,['18']);ReactableTestUtils.expectRowText(2,['23']);ReactableTestUtils.expectRowText(3,['28']);ReactableTestUtils.expectRowText(4,['123']);ReactableTestUtils.expectRowText(5,['a']);ReactableTestUtils.expectRowText(6,['z']);});});describe('numeric sort with Tr and Td specified and custom value',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',columns:[{key:'Count',sortable:Reactable.Sort.Numeric}]},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Count',value:23},'twenty-three')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Count',value:18},'eighteen')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Count',value:28},'twenty-eight')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Count',value:1.23},'one point two three')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Count',value:'a'},'a')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Count',value:'z'},'z')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Count',value:123},'one hundred twenty-three'))),ReactableTestUtils.testNode());});after(function(){ReactableTestUtils.resetTestEnvironment();});it('sorts columns numerically',function(){var sortHeader=$('#table thead tr.reactable-column-header th')[0];ReactTestUtils.Simulate.click(sortHeader);ReactableTestUtils.expectRowText(0,['one point two three']);ReactableTestUtils.expectRowText(1,['eighteen']);ReactableTestUtils.expectRowText(2,['twenty-three']);ReactableTestUtils.expectRowText(3,['twenty-eight']);ReactableTestUtils.expectRowText(4,['one hundred twenty-three']);ReactableTestUtils.expectRowText(5,['a']);ReactableTestUtils.expectRowText(6,['z']);});});describe('currency sort',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{Price:'1.25'},{Price:'$1.01'},{Price:'1'},{Price:'$10,000'},{Price:'$10,500'},{Price:'$10'},{Price:'a'},{Price:'z'},{Price:'$2'},{Price:'$.5'},{Price:'$0.60'},{Price:'.1'}],columns:[{key:'Price',sortable:Reactable.Sort.Currency}]}),ReactableTestUtils.testNode());});after(function(){ReactableTestUtils.resetTestEnvironment();});it('sorts columns numerically. parsing out currency symbols',function(){var sortHeader=$('#table thead tr.reactable-column-header th')[0];ReactTestUtils.Simulate.click(sortHeader);ReactableTestUtils.expectRowText(0,['.1']);ReactableTestUtils.expectRowText(1,['$.5']);ReactableTestUtils.expectRowText(2,['$0.60']);ReactableTestUtils.expectRowText(3,['1']);ReactableTestUtils.expectRowText(4,['$1.01']);ReactableTestUtils.expectRowText(5,['1.25']);ReactableTestUtils.expectRowText(6,['$2']);ReactableTestUtils.expectRowText(7,['$10']);ReactableTestUtils.expectRowText(8,['$10,000']);ReactableTestUtils.expectRowText(9,['$10,500']);ReactableTestUtils.expectRowText(10,['a']);ReactableTestUtils.expectRowText(11,['z']);});});describe('date sort',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{'Date':'1/1/2014 11:00 AM'},{'Date':'1/1/2013 11:00 AM'},{'Date':'1/1/2014 4:30 PM'},{'Date':'4/3/2013'},{'Date':'a'},{'Date':'z'}],columns:[{key:'Date',sortable:Reactable.Sort.Date}]}),ReactableTestUtils.testNode());});after(function(){ReactableTestUtils.resetTestEnvironment();});it('sorts columns by date',function(){var sortHeader=$('#table thead tr.reactable-column-header th')[0];ReactTestUtils.Simulate.click(sortHeader);ReactableTestUtils.expectRowText(0,['1/1/2013 11:00 AM']);ReactableTestUtils.expectRowText(1,['4/3/2013']);ReactableTestUtils.expectRowText(2,['1/1/2014 11:00 AM']);ReactableTestUtils.expectRowText(3,['1/1/2014 4:30 PM']);ReactableTestUtils.expectRowText(4,['a']);ReactableTestUtils.expectRowText(5,['z']);});});describe('case insensitive sorting',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{'Name':'Lee Salminen'},{'Name':'Griffin Smith'},{'Name':'Ian Zhang'},{'Name':'lee Salminen'},{'Name':'griffin smith'},{'Name':'Ian zhang'}],columns:[{key:'Name',sortable:Reactable.Sort.CaseInsensitive}]}),ReactableTestUtils.testNode());});after(function(){ReactableTestUtils.resetTestEnvironment();});it('sorts columns by value - case insensitive',function(){var sortHeader=$('#table thead tr.reactable-column-header th')[0];ReactTestUtils.Simulate.click(sortHeader);ReactableTestUtils.expectRowText(0,['Griffin Smith']);ReactableTestUtils.expectRowText(1,['griffin smith']);ReactableTestUtils.expectRowText(2,['Ian Zhang']);ReactableTestUtils.expectRowText(3,['Ian zhang']);ReactableTestUtils.expectRowText(4,['Lee Salminen']);ReactableTestUtils.expectRowText(5,['lee Salminen']);});});describe('custom sort with React Components',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{'Rank':React.createElement('span',{className:'3'},'Third')},{'Rank':React.createElement('span',{className:'1'},'First')},{'Rank':React.createElement('span',{className:'2'},'Second')}],columns:[{key:'Rank',sortable:function sortable(a,b){ // sort based on classname +return a.props.className.localeCompare(b.props.className);}}]}),ReactableTestUtils.testNode());});after(function(){ReactableTestUtils.resetTestEnvironment();});it('sorts columns by value',function(){var sortHeader=$('#table thead tr.reactable-column-header th')[0];ReactTestUtils.Simulate.click(sortHeader);ReactableTestUtils.expectRowText(0,['First']);ReactableTestUtils.expectRowText(1,['Second']);ReactableTestUtils.expectRowText(2,['Third']);});});describe('sorts and calls onSort callback via props',function(){var sortColumn=null;var callback=function callback(sortObject){sortColumn = sortObject.column;};before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{'Rank':React.createElement('span',{className:'3'},'Third')},{'Rank':React.createElement('span',{className:'1'},'First')},{'Rank':React.createElement('span',{className:'2'},'Second')}],columns:[{key:'Rank',sortable:function sortable(a,b){ // sort based on classname +return a.props.className.localeCompare(b.props.className);}}],onSort:callback}),ReactableTestUtils.testNode());});after(function(){ReactableTestUtils.resetTestEnvironment();});it('returns currentSort object to callback for utilization',function(){var sortHeader=$('#table thead tr.reactable-column-header th')[0];ReactTestUtils.Simulate.click(sortHeader);expect(sortColumn).to.equal('Rank');});});});describe('filtering',function(){describe('filtering with javascript objects for data',function(){var data=[{name:"Lee SomeoneElse",age:18},{name:"Lee Salminen",age:23},{name:"No Age",age:null}];before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',filterable:['Name','Age']},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name',data:data[0].name}),React.createElement(Reactable.Td,{column:'Age',data:data[0].age})),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name',data:data[1].name}),React.createElement(Reactable.Td,{column:'Age',data:data[1].age})),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name',data:data[2].name}),React.createElement(Reactable.Td,{column:'Age',data:data[2].age}))),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('filters case insensitive on specified columns',function(){var $filter=$('#table thead tr.reactable-filterer input.reactable-filter-input');$filter.val('lee');React.addons.TestUtils.Simulate.keyUp($filter[0]);ReactableTestUtils.expectRowText(0,['Lee SomeoneElse','18']);ReactableTestUtils.expectRowText(1,['Lee Salminen','23']);});});describe('basic case-insensitive filtering',function(){before(function(){this.component = ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',filterable:['State','Tag'],filterPlaceholder:'Filter Results',columns:['State','Description','Tag']},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'New York'),React.createElement(Reactable.Td,{column:'Description'},'this is some text'),React.createElement(Reactable.Td,{column:'Tag'},'new')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'New Mexico'),React.createElement(Reactable.Td,{column:'Description'},'lorem ipsum'),React.createElement(Reactable.Td,{column:'Tag'},'old')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'Colorado'),React.createElement(Reactable.Td,{column:'Description'},'new description that shouldnt match filter'),React.createElement(Reactable.Td,{column:'Tag'},'old')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'Alaska'),React.createElement(Reactable.Td,{column:'Description'},'bacon'),React.createElement(Reactable.Td,{column:'Tag'},'renewed'))),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);context('from the filterer field',function(){it('filters case insensitive on specified columns',function(){var $filter=$('#table thead tr.reactable-filterer input.reactable-filter-input');$filter.val('new');React.addons.TestUtils.Simulate.keyUp($filter[0]);ReactableTestUtils.expectRowText(0,['New York','this is some text','new']);ReactableTestUtils.expectRowText(1,['New Mexico','lorem ipsum','old']);ReactableTestUtils.expectRowText(2,['Alaska','bacon','renewed']);});it('filter placeholder is set',function(){var $filter=$('#table thead tr.reactable-filterer input.reactable-filter-input');expect($filter.attr("placeholder")).to.equal('Filter Results');});});context('from the filterer field with column and val',function(){it('filters case insensitive on specified columns',function(){var $filter=$('#table thead tr.reactable-filterer input.reactable-filter-input');$filter.val('Tag: renewed');React.addons.TestUtils.Simulate.keyUp($filter[0]);ReactableTestUtils.expectRowText(0,['Alaska','bacon','renewed']);});it('filter placeholder is set',function(){var $filter=$('#table thead tr.reactable-filterer input.reactable-filter-input');expect($filter.attr("placeholder")).to.equal('Filter Results');});});context('from the filterer field with multiple columns and vals',function(){it('filters case insensitive on specified columns',function(){var $filter=$('#table thead tr.reactable-filterer input.reactable-filter-input');$filter.val('Tag: renewed, State: alaska, Description: bacon');React.addons.TestUtils.Simulate.keyUp($filter[0]);ReactableTestUtils.expectRowText(0,['Alaska','bacon','renewed']);});it('filters case insensitive on specified columns',function(){var $filter=$('#table thead tr.reactable-filterer input.reactable-filter-input');$filter.val('Tag: renewed, State: New, Description: bacon');React.addons.TestUtils.Simulate.keyUp($filter[0]);ReactableTestUtils.expectRowText(0,'');});it('filter placeholder is set',function(){var $filter=$('#table thead tr.reactable-filterer input.reactable-filter-input');expect($filter.attr("placeholder")).to.equal('Filter Results');});});context('from the function',function(){before(function(){this.component.filterBy('york');});it('applies the filtering',function(){ReactableTestUtils.expectRowText(0,['New York','this is some text','new']);});it('updates the value of the filterer',function(){var $filter=$('#table thead tr.reactable-filterer input.reactable-filter-input');expect($filter).to.have.value('york');});});context('from string filterBy prop',function(){before(function(){ReactableTestUtils.resetTestEnvironment();var ParentComponent=React.createClass({displayName:'ParentComponent',getInitialState:function getInitialState(){return {customFilterText:'new'};},handleChange:function handleChange(event){this.setState({customFilterText:event.target.value});},render:function render(){return React.createElement('div',null,React.createElement('input',{type:'text',ref:'customFilterInput',id:'customFilterInput',value:this.state.customFilterText,onChange:this.handleChange}),React.createElement(Reactable.Table,{className:'table',id:'table',filterable:['State','Tag'],filterPlaceholder:'Filter Results',filterBy:this.state.customFilterText,columns:['State','Description','Tag']},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'New York'),React.createElement(Reactable.Td,{column:'Description'},'this is some text'),React.createElement(Reactable.Td,{column:'Tag'},'new')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'New Mexico'),React.createElement(Reactable.Td,{column:'Description'},'lorem ipsum'),React.createElement(Reactable.Td,{column:'Tag'},'old')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'Colorado'),React.createElement(Reactable.Td,{column:'Description'},'new description that shouldnt match filter'),React.createElement(Reactable.Td,{column:'Tag'},'old')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'Alaska'),React.createElement(Reactable.Td,{column:'Description'},'bacon'),React.createElement(Reactable.Td,{column:'Tag'},'renewed'))));}});this.component = ReactDOM.render(React.createElement(ParentComponent),ReactableTestUtils.testNode());});it('filters case insensitive on specified columns',function(){ReactableTestUtils.expectRowText(0,['New York','this is some text','new']);ReactableTestUtils.expectRowText(1,['New Mexico','lorem ipsum','old']);ReactableTestUtils.expectRowText(2,['Alaska','bacon','renewed']);var $builtInFilter=$('#table thead tr.reactable-filterer input.reactable-filter-input');expect($builtInFilter).to.have.value('new'); // Simulate changing input on parent component and re-rendering Reactable.Table with new props. +var node=this.component.refs.customFilterInput;node.value = 'alaska';ReactTestUtils.Simulate.change(customFilterInput);ReactableTestUtils.expectRowText(0,['Alaska','bacon','renewed']);expect($builtInFilter).to.have.value('alaska');});});context('from 1 column Object filterBy prop',function(){before(function(){ReactableTestUtils.resetTestEnvironment();var ParentComponent=React.createClass({displayName:'ParentComponent',getInitialState:function getInitialState(){return {customFilterText:{'Tag':'new'}};},handleChange:function handleChange(event){this.setState({customFilterText:event.target.value});},render:function render(){return React.createElement('div',null,React.createElement('input',{type:'text',ref:'customFilterInput',id:'customFilterInput',value:this.state.customFilterText,onChange:this.handleChange}),React.createElement(Reactable.Table,{className:'table',id:'table',filterable:['State','Tag'],filterPlaceholder:'Filter Results',filterBy:this.state.customFilterText,columns:['State','Description','Tag']},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'New York'),React.createElement(Reactable.Td,{column:'Description'},'this is some text'),React.createElement(Reactable.Td,{column:'Tag'},'new')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'New Mexico'),React.createElement(Reactable.Td,{column:'Description'},'lorem ipsum'),React.createElement(Reactable.Td,{column:'Tag'},'old')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'Colorado'),React.createElement(Reactable.Td,{column:'Description'},'new description that shouldnt match filter'),React.createElement(Reactable.Td,{column:'Tag'},'old')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'Alaska'),React.createElement(Reactable.Td,{column:'Description'},'bacon'),React.createElement(Reactable.Td,{column:'Tag'},'renewed'))));}});this.component = ReactDOM.render(React.createElement(ParentComponent),ReactableTestUtils.testNode());});it('filters case insensitive on specified columns',function(){ReactableTestUtils.expectRowText(0,['New York','this is some text','new']);var $builtInFilter=$('#table thead tr.reactable-filterer input.reactable-filter-input');expect($builtInFilter).to.have.value('Tag: new'); // Simulate changing input on parent component and re-rendering Reactable.Table with new props. +var node=this.component.refs.customFilterInput;node.value = 'alaska';ReactTestUtils.Simulate.change(customFilterInput);ReactableTestUtils.expectRowText(0,['Alaska','bacon','renewed']);expect($builtInFilter).to.have.value('alaska');});});context('from multiple columns object filterBy prop',function(){before(function(){ReactableTestUtils.resetTestEnvironment();var ParentComponent=React.createClass({displayName:'ParentComponent',getInitialState:function getInitialState(){return {customFilterText:{'Tag':'new','State':'alaska'}};},handleChange:function handleChange(event){this.setState({customFilterText:event.target.value});},render:function render(){return React.createElement('div',null,React.createElement('input',{type:'text',ref:'customFilterInput',id:'customFilterInput',value:this.state.customFilterText,onChange:this.handleChange}),React.createElement(Reactable.Table,{className:'table',id:'table',filterable:['State','Tag'],filterPlaceholder:'Filter Results',filterBy:this.state.customFilterText,columns:['State','Description','Tag']},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'New York'),React.createElement(Reactable.Td,{column:'Description'},'this is some text'),React.createElement(Reactable.Td,{column:'Tag'},'new')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'New Mexico'),React.createElement(Reactable.Td,{column:'Description'},'lorem ipsum'),React.createElement(Reactable.Td,{column:'Tag'},'old')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'Colorado'),React.createElement(Reactable.Td,{column:'Description'},'new description that shouldnt match filter'),React.createElement(Reactable.Td,{column:'Tag'},'old')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'Alaska'),React.createElement(Reactable.Td,{column:'Description'},'bacon'),React.createElement(Reactable.Td,{column:'Tag'},'renewed'))));}});this.component = ReactDOM.render(React.createElement(ParentComponent),ReactableTestUtils.testNode());});it('filters case insensitive on specified columns',function(){ReactableTestUtils.expectRowText(0,['Alaska','bacon','renewed']);var $builtInFilter=$('#table thead tr.reactable-filterer input.reactable-filter-input');expect($builtInFilter).to.have.value('Tag: new, State: alaska'); // Simulate changing input on parent component and re-rendering Reactable.Table with new props. +var node=this.component.refs.customFilterInput;node.value = 'alaska';ReactTestUtils.Simulate.change(customFilterInput);ReactableTestUtils.expectRowText(0,['Alaska','bacon','renewed']);expect($builtInFilter).to.have.value('alaska');});});});context('filtering with prop and hiding filter input',function(){before(function(){this.component = ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',filterable:['State','Tag'],filterPlaceholder:'Filter Results',filterBy:'new',hideFilterInput:true,columns:['State','Description','Tag']},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'New York'),React.createElement(Reactable.Td,{column:'Description'},'this is some text'),React.createElement(Reactable.Td,{column:'Tag'},'new')),React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'State'},'New Mexico'),React.createElement(Reactable.Td,{column:'Description'},'lorem ipsum'),React.createElement(Reactable.Td,{column:'Tag'},'old'))),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('does not render the filter input box',function(){expect($('#table thead tr.reactable-filterer input.reactable-filter-input').length).to.equal(0);});});context('filtering and pagination together',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{'State':'New York','Description':'this is some text','Tag':'new'},{'State':'New Mexico','Description':'lorem ipsum','Tag':'old'},{'State':'Colorado','Description':'new description that shouldn\'t match filter','Tag':'old'},{'State':'Alaska','Description':'bacon','Tag':'renewed'}],filterable:['State','Tag'],columns:['State','Description','Tag'],itemsPerPage:2}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);afterEach(function(){var $filter=$('#table thead tr.reactable-filterer input.reactable-filter-input');$filter.val('');React.addons.TestUtils.Simulate.keyUp($filter[0]);});it('updates the pagination links',function(){var $filter=$('#table thead tr.reactable-filterer input.reactable-filter-input');$filter.val('colorado');React.addons.TestUtils.Simulate.keyUp($filter[0]);var pageButtons=$('#table tbody.reactable-pagination a.reactable-page-button');expect(pageButtons.length).to.equal(1);expect($(pageButtons[0])).to.have.text('1');});it('updates the current page if necessary',function(){var $filter=$('#table thead tr.reactable-filterer input.reactable-filter-input');var $pageButtons=$('#table tbody.reactable-pagination a.reactable-page-button'); // Go to the last page +React.addons.TestUtils.Simulate.click($pageButtons[1]); // Then filter so that that page doesn't exist anymore +$filter.val('colorado');React.addons.TestUtils.Simulate.keyUp($filter[0]);ReactableTestUtils.expectRowText(0,['Colorado',"new description that shouldn't match filter",'old']);var activePage=$('#table tbody.reactable-pagination ' + 'a.reactable-page-button.reactable-current-page');expect(activePage.length).to.equal(1);expect(activePage).to.have.text('1');});});});describe('directly passing a data array with non-string data',function(){before(function(){ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table',data:[{Name:'Griffin Smith',Age:18},{Age:23,Name:{toString:function toString(){return 'Lee Salminen';}}},{Age:28.45,Position:'Developer'}]}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('renders the table',function(){expect($('table#table.table')).to.exist;});it('renders the column headers in the table',function(){var headers=[];$('thead th').each(function(){headers.push($(this).text());});expect(headers).to.eql(['Name','Age','Position']);});it('renders the first row with the correct data',function(){ReactableTestUtils.expectRowText(0,['Griffin Smith','18','']);});it('renders the second row with the correct data',function(){ReactableTestUtils.expectRowText(1,['Lee Salminen','23','']);});it('renders the third row with the correct data',function(){ReactableTestUtils.expectRowText(2,['','28.45','Developer']);});});describe('multiple tables on a page',function(){before(function(){this.parentTestNode = ReactableTestUtils.testNode();this.testNode1 = $('
').attr('id','test-node-1');this.testNode2 = $('
').attr('id','test-node-2');ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table1',data:[{Name:'Griffin Smith',Age:'18'},{Age:'23',Name:'Lee Salminen'},{Age:'28',Position:'Developer'}]}),this.testNode1[0]);ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table2',data:[{Moniker:'Griffin Smith',Elderliness:'18'},{Elderliness:'23',Moniker:'Lee Salminen'},{Elderliness:'28',Title:'Developer'}]}),this.testNode2[0]);});after(function(){$(this.parentTestNode).empty().remove();});it('renders the column headers in the first table',function(){var headers=[];this.testNode1.find('thead th').each(function(){headers.push($(this).text());});expect(headers).to.eql(['Name','Age','Position']);});it('renders the column headers in the second table',function(){var headers=[];this.testNode2.find('thead th').each(function(){headers.push($(this).text());});expect(headers).to.eql(['Moniker','Elderliness','Title']);});});describe('handleClick callbacks',function(){before(function(){this.clicked = false;ReactDOM.render(React.createElement(Reactable.Table,{className:'table',id:'table'},React.createElement(Reactable.Tr,null,React.createElement(Reactable.Td,{column:'Name',handleClick:(function(){this.clicked = true;}).bind(this)},React.createElement('b',null,'Griffin Smith')))),ReactableTestUtils.testNode());ReactTestUtils.Simulate.click($('td')[0]);});after(ReactableTestUtils.resetTestEnvironment);it('calls the callbacks on click',function(){expect(this.clicked).to.eq(true);});});describe('table with no data',function(){context('when noDataText prop is null',function(){before(function(){this.component = ReactDOM.render(React.createElement(Reactable.Table,{data:[],columns:['State','Description','Tag']}),ReactableTestUtils.testNode());});after(ReactableTestUtils.resetTestEnvironment);it('does not render the reactable-no-data element',function(){expect($('.reactable-no-data').length).to.eq(0);});});context('when initialized without