1
0
Fork 0
mirror of https://github.com/koalyptus/TableFilter.git synced 2024-06-15 20:25:07 +02:00

Compare commits

...

781 commits

Author SHA1 Message Date
koalyptus 7afe45f1e6
Merge pull request #787 from koalyptus/dependabot/npm_and_yarn/codecov-3.7.1
Bump codecov from 3.7.0 to 3.7.1
2020-07-22 19:51:17 +10:00
koalyptus 6e01e45dfb prepare dist 2020-07-22 19:45:07 +10:00
dependabot[bot] 12c30629af
Bump codecov from 3.7.0 to 3.7.1
Bumps [codecov](https://github.com/codecov/codecov-node) from 3.7.0 to 3.7.1.
- [Release notes](https://github.com/codecov/codecov-node/releases)
- [Commits](https://github.com/codecov/codecov-node/compare/v3.7.0...v3.7.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-21 12:35:35 +00:00
koalyptus 3e763efac9
Merge pull request #784 from koalyptus/769-refine-empty-cell-logic
769 refine empty nonempty operators logic
2020-06-16 13:03:27 +10:00
koalyptus 825b915ae8 769 refine empty nonempty operators logic 2020-06-16 12:28:12 +10:00
koalyptus 8e48bf2943
Merge pull request #783 from koalyptus/greenkeeper/monorepo.babel7-20200526215451
Update babel7 to the latest version 🚀
2020-06-15 15:20:26 +10:00
koalyptus be7a5e585f prepare dist for 0.7.1 2020-06-15 15:19:11 +10:00
greenkeeper[bot] c44bef22a2
chore(package): update lockfile package-lock.json 2020-05-26 23:57:32 +00:00
greenkeeper[bot] 6dcebbf67e
chore(package): update @babel/preset-env to version 7.10.0 2020-05-26 23:57:28 +00:00
greenkeeper[bot] 44cb6f9124
chore(package): update @babel/core to version 7.10.0 2020-05-26 23:57:25 +00:00
koalyptus 571c31e8da
Merge pull request #780 from koalyptus/772-fix
Fix for #772: help instructions pop-up position with responsive behaviour
2020-05-14 12:58:23 +10:00
koalyptus 8633891fdb add unit tests - prepare dist 2020-05-14 12:40:44 +10:00
koalyptus 8eddc6f35c introduce adjust_container_left_position option in help_instructions configuration 2020-05-13 20:46:23 +10:00
koalyptus 577fb0b90a
Merge pull request #768 from koalyptus/greenkeeper/monorepo.babel7-20200228094136
Update babel7 to the latest version 🚀
2020-05-07 20:56:13 +10:00
Max Guglielmi 88a5bfe425 bump dep - prepare dist 2020-05-07 20:23:53 +10:00
Max Guglielmi cac2900444 prepare dist 2020-05-07 20:21:35 +10:00
greenkeeper[bot] 5dad4dae8e
chore(package): update lockfile package-lock.json 2020-02-28 11:43:33 +00:00
greenkeeper[bot] 134851525c
chore(package): update @babel/preset-env to version 7.8.6 2020-02-28 11:43:28 +00:00
greenkeeper[bot] 9a66748bb8
chore(package): update @babel/core to version 7.8.6 2020-02-28 11:43:25 +00:00
koalyptus c52004421f
Merge pull request #762 from koalyptus/greenkeeper/codecov-3.6.3
Update codecov to the latest version 🚀
2020-02-04 14:16:41 +11:00
koalyptus f53b392c59 prepare dist 2020-02-04 14:03:29 +11:00
koalyptus c496b0916d Merge branch 'master' into greenkeeper/codecov-3.6.3 2020-02-04 13:50:04 +11:00
koalyptus 25b89b19e7
Merge pull request #760 from koalyptus/greenkeeper/monorepo.babel7-20200112133918
Update babel7 to the latest version 🚀
2020-02-03 14:11:32 +11:00
koalyptus 8b4a05be02 prepare dist 2020-02-03 13:50:29 +11:00
koalyptus 1c4961a25b Merge branch 'master' into greenkeeper/monorepo.babel7-20200112133918 2020-02-03 13:35:30 +11:00
greenkeeper[bot] 40daf54768
chore(package): update lockfile package-lock.json 2020-01-31 14:09:11 +00:00
greenkeeper[bot] c43debc7ac
chore(package): update codecov to version 3.6.3 2020-01-31 14:09:07 +00:00
koalyptus 3ac2603e47
Merge pull request #759 from koalyptus/dependabot/npm_and_yarn/handlebars-4.5.3
Bump handlebars from 4.1.2 to 4.5.3
2020-01-14 14:53:40 +11:00
koalyptus 185c119342 prepare dist 2020-01-14 13:44:44 +11:00
koalyptus 80c9b3d734 Merge branch 'master' into dependabot/npm_and_yarn/handlebars-4.5.3 2020-01-14 13:26:01 +11:00
greenkeeper[bot] e8605e5e19
chore(package): update lockfile package-lock.json 2020-01-12 15:47:37 +00:00
greenkeeper[bot] bd95afb3eb
chore(package): update @babel/preset-env to version 7.8.0 2020-01-12 15:47:33 +00:00
greenkeeper[bot] c16f885951
chore(package): update @babel/core to version 7.8.0 2020-01-12 15:47:30 +00:00
koalyptus 6be9ad491f
Merge pull request #758 from koalyptus/greenkeeper/monorepo.babel7-20191219010209
Update babel7 to the latest version 🚀
2020-01-09 09:56:14 +11:00
koalyptus 447a3119aa Prepare dist 2020-01-09 09:44:26 +11:00
dependabot[bot] 2025aa4010
Bump handlebars from 4.1.2 to 4.5.3
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.1.2 to 4.5.3.
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/wycats/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2...v4.5.3)

Signed-off-by: dependabot[bot] <support@github.com>
2019-12-27 00:16:57 +00:00
greenkeeper[bot] bdc03755e8
chore(package): update lockfile package-lock.json 2019-12-19 02:28:44 +00:00
greenkeeper[bot] 2dceed888e
chore(package): update @babel/preset-env to version 7.7.7 2019-12-19 02:28:40 +00:00
greenkeeper[bot] 982769a020
chore(package): update @babel/core to version 7.7.7 2019-12-19 02:28:37 +00:00
koalyptus 4318826ead
Merge pull request #754 from koalyptus/greenkeeper/monorepo.babel7-20191106233658
Update babel7 to the latest version 🚀
2019-12-09 14:53:11 +11:00
koalyptus 66b8fa9d94 prepare dist: include missing file 2019-12-09 14:46:14 +11:00
koalyptus 79cea3e27f prepare dist + miscellaneous fixes 2019-12-09 14:44:37 +11:00
greenkeeper[bot] 7af493da27
chore(package): update lockfile package-lock.json 2019-11-07 01:41:18 +00:00
greenkeeper[bot] 90c3b7f937
chore(package): update @babel/preset-env to version 7.7.1 2019-11-07 01:41:14 +00:00
greenkeeper[bot] 85dce5847a
chore(package): update @babel/core to version 7.7.2 2019-11-07 01:41:11 +00:00
koalyptus 65863b635a
Merge pull request #753 from koalyptus/greenkeeper/monorepo.babel7-20191105110141
Update babel7 to the latest version 🚀
2019-11-06 14:08:51 +11:00
koalyptus 3c001f52e2 prepare dist 2019-11-06 13:56:55 +11:00
greenkeeper[bot] e3957977b6
chore(package): update lockfile package-lock.json 2019-11-05 14:06:38 +00:00
greenkeeper[bot] 8923c4db94
chore(package): update @babel/preset-env to version 7.7.0 2019-11-05 14:06:34 +00:00
greenkeeper[bot] c7d1a25467
chore(package): update @babel/core to version 7.7.0 2019-11-05 14:06:31 +00:00
koalyptus ebdd817199
Merge pull request #746 from koalyptus/greenkeeper/eslint-6.5.0
Update eslint to the latest version 🚀
2019-10-21 14:28:13 +11:00
koalyptus 27365e25d4 prepare dist 2019-10-21 14:20:42 +11:00
koalyptus 2e960867ab Merge branch 'master' into greenkeeper/eslint-6.5.0 2019-10-21 13:25:34 +11:00
koalyptus 3d35d53005
Merge pull request #745 from koalyptus/greenkeeper/monorepo.babel7-20190923213305
Update babel7 to the latest version 🚀
2019-10-20 17:59:00 +11:00
koalyptus 02bc5e3ae1 fix conflict - prepare dist 2019-10-20 17:32:55 +11:00
koalyptus 09c1f8ff52
Merge pull request #744 from koalyptus/greenkeeper/codecov-3.6.1
Update codecov to the latest version 🚀
2019-10-10 13:50:18 +11:00
koalyptus 6b339f7bd7 merge master in, resolve conflix 2019-10-10 13:38:17 +11:00
koalyptus a1efe26a85 prepare dist 2019-10-10 13:36:03 +11:00
koalyptus 64e6c6597f
Merge pull request #737 from koalyptus/greenkeeper/babel-eslint-10.0.3
Update babel-eslint to the latest version 🚀
2019-09-30 07:58:23 +10:00
koalyptus 9363a7a661 prepare dist 2019-09-30 07:09:32 +10:00
greenkeeper[bot] 41e220efa9
chore(package): update lockfile package-lock.json 2019-09-29 06:24:29 +00:00
greenkeeper[bot] 64d3808a2b
chore(package): update eslint to version 6.5.0 2019-09-29 06:24:25 +00:00
greenkeeper[bot] eb15788965
chore(package): update lockfile package-lock.json 2019-09-23 23:07:35 +00:00
greenkeeper[bot] fede2f6e86
chore(package): update @babel/preset-env to version 7.6.2 2019-09-23 23:07:26 +00:00
greenkeeper[bot] 9738c8ed91
chore(package): update @babel/core to version 7.6.2 2019-09-23 23:07:21 +00:00
greenkeeper[bot] b285d01b54
chore(package): update lockfile package-lock.json 2019-09-20 12:24:13 +00:00
greenkeeper[bot] 37eed72f2c
chore(package): update codecov to version 3.6.1 2019-09-20 12:24:01 +00:00
koalyptus 71103cd04b
Merge pull request #743 from koalyptus/greenkeeper/codecov-3.6.0
Update codecov to the latest version 🚀
2019-09-20 20:01:13 +10:00
koalyptus 42a347550b prepare dist 2019-09-20 19:54:27 +10:00
koalyptus bed04b5b9b Merge remote-tracking branch 'origin/greenkeeper/monorepo.babel7-20190906190906' into greenkeeper/codecov-3.6.0 2019-09-20 19:46:05 +10:00
koalyptus 43fc68df31 Merge remote-tracking branch 'origin/greenkeeper/eslint-6.4.0' into greenkeeper/codecov-3.6.0 2019-09-20 19:45:52 +10:00
greenkeeper[bot] d116525f73
chore(package): update lockfile package-lock.json 2019-09-20 02:31:28 +00:00
greenkeeper[bot] d7ff36514d
chore(package): update codecov to version 3.6.0 2019-09-20 02:31:18 +00:00
greenkeeper[bot] 0d0abf3206
chore(package): update lockfile package-lock.json 2019-09-14 02:14:37 +00:00
greenkeeper[bot] 4cd004e423
chore(package): update eslint to version 6.4.0 2019-09-14 02:14:29 +00:00
greenkeeper[bot] 459829a214
chore(package): update lockfile package-lock.json 2019-09-06 22:27:01 +00:00
greenkeeper[bot] b8c0c1bc3f
chore(package): update @babel/preset-env to version 7.6.0 2019-09-06 22:26:54 +00:00
greenkeeper[bot] 5686e8a470
chore(package): update @babel/core to version 7.6.0 2019-09-06 22:26:48 +00:00
koalyptus b04d4f55ed
Merge pull request #735 from koalyptus/greenkeeper/eslint-6.2.0
Update eslint to the latest version 🚀
2019-09-06 14:26:50 +10:00
koalyptus 3004963058 prepare dist 2019-09-06 14:15:54 +10:00
greenkeeper[bot] 3454187be6
chore(package): update lockfile package-lock.json 2019-08-25 21:33:46 +00:00
greenkeeper[bot] 1dac7736b1
chore(package): update babel-eslint to version 10.0.3 2019-08-25 21:33:28 +00:00
greenkeeper[bot] 2c7ad88346
chore(package): update lockfile package-lock.json 2019-08-18 22:53:24 +00:00
greenkeeper[bot] 6e41c4a8c6
chore(package): update eslint to version 6.2.0 2019-08-18 22:53:09 +00:00
koalyptus 859f6b1eeb
Merge pull request #734 from koalyptus/greenkeeper/uglifyjs-webpack-plugin-2.2.0
Update uglifyjs-webpack-plugin to the latest version 🚀
2019-08-09 14:21:29 +10:00
koalyptus 7204c4b546 prepare dist 2019-08-09 12:24:02 +10:00
greenkeeper[bot] f29b59fdbd chore(package): update lockfile package-lock.json 2019-07-31 12:27:29 +00:00
greenkeeper[bot] 6cc887e806 chore(package): update uglifyjs-webpack-plugin to version 2.2.0 2019-07-31 12:27:24 +00:00
koalyptus f7ad9741ca
Merge pull request #733 from koalyptus/731-upgrade-webpack
731 prepare dist
2019-07-30 13:07:16 +10:00
koalyptus 323a80d1d7 731 prepare dist 2019-07-30 12:59:37 +10:00
koalyptus fc46f0b4ae
Merge pull request #728 from koalyptus/greenkeeper/monorepo.babel7-20190704132520
Update babel7 to the latest version 🚀
2019-07-21 18:44:00 +10:00
koalyptus 0471570985 prepare dist 2019-07-21 18:12:46 +10:00
koalyptus 20243b641f Merge remote-tracking branch 'origin/greenkeeper/eslint-8.0.0' into greenkeeper/monorepo.babel7-20190704132520 2019-07-21 17:21:03 +10:00
koalyptus 99722cbdb0 resolve merge conflicts 2019-07-21 17:20:30 +10:00
koalyptus 64cc6825c5 bump tablefilter version 2019-07-21 17:17:47 +10:00
greenkeeper[bot] bcb541fcad chore(package): update lockfile package-lock.json 2019-07-04 18:45:43 +00:00
greenkeeper[bot] 1c3c1bbb0a chore(package): update @babel/preset-env to version 7.5.0 2019-07-04 18:45:38 +00:00
greenkeeper[bot] bba009c505 chore(package): update @babel/core to version 7.5.0 2019-07-04 18:45:35 +00:00
greenkeeper[bot] 48659ec1d5 chore(package): update lockfile package-lock.json 2019-06-22 04:01:53 +00:00
greenkeeper[bot] 1d32dcea7d chore(package): update eslint to version 6.0.0 2019-06-22 04:01:44 +00:00
greenkeeper[bot] 0e1c617b06 chore(package): update lockfile package-lock.json 2019-06-17 14:21:21 +00:00
greenkeeper[bot] 5c705fe591 chore(package): update babel-eslint to version 10.0.2 2019-06-17 14:21:13 +00:00
koalyptus 3c501e3aef
Merge pull request #722 from koalyptus/716-fix-sort-date-desc
Enhance filter options sorting based on column data type
2019-06-07 21:43:09 +10:00
koalyptus 78ae09c861 Enhance filter options sorting based on column data type 2019-06-07 18:26:33 +10:00
koalyptus 2e1af5efb3
Merge pull request #715 from koalyptus/greenkeeper/uglifyjs-webpack-plugin-2.1.3
Update uglifyjs-webpack-plugin to the latest version 🚀
2019-06-06 11:28:09 +10:00
koalyptus da270df5d6 fix CleanWebpackPlugin webpack plugin upgrade 2019-06-06 11:22:03 +10:00
koalyptus 8a8419bf02 Merge remote-tracking branch 'origin/greenkeeper/clean-webpack-plugin-3.0.0' into greenkeeper/uglifyjs-webpack-plugin-2.1.3 2019-06-06 10:35:09 +10:00
koalyptus a6c24c7885 fix uglifyjs webpack plugin upgrade 2019-06-06 10:33:43 +10:00
koalyptus ed2fef999a Merge branch 'master' into greenkeeper/uglifyjs-webpack-plugin-2.1.3 2019-06-06 10:19:35 +10:00
greenkeeper[bot] 47c66d71bb chore(package): update lockfile package-lock.json 2019-05-30 13:44:30 +00:00
greenkeeper[bot] f99f850c4d chore(package): update clean-webpack-plugin to version 3.0.0 2019-05-30 13:44:24 +00:00
koalyptus 10c06b5100
Merge pull request #720 from koalyptus/714-fix-clear-filter-text
address #714: clear_filter_text
2019-05-24 19:53:01 +10:00
koalyptus 1cc810c341 remove tmp file 2019-05-24 17:08:26 +10:00
koalyptus c707978e19 address #714: clear_filter_text 2019-05-24 17:03:09 +10:00
koalyptus 32b541239e
Merge pull request #719 from koalyptus/greenkeeper/monorepo.babel7-20190521175803
Update babel7 to the latest version 🚀
2019-05-22 16:41:55 +10:00
koalyptus 2963962250 prep dist 2019-05-22 16:30:51 +10:00
koalyptus bbec44cc15 Merge remote-tracking branch 'origin/greenkeeper/grunt-qunit-istanbul-1.1.0' into greenkeeper/monorepo.babel7-20190521175803 2019-05-22 16:25:16 +10:00
koalyptus 352a700fb2 Merge remote-tracking branch 'origin/greenkeeper/codecov-3.4.0' into greenkeeper/monorepo.babel7-20190521175803 2019-05-22 16:24:25 +10:00
koalyptus fae4ec9e07 bump TableFilter version 2019-05-22 16:24:18 +10:00
greenkeeper[bot] 226f18a6f6 chore(package): update lockfile package-lock.json 2019-05-21 21:28:45 +00:00
greenkeeper[bot] 1d58191127 chore(package): update @babel/preset-env to version 7.4.5 2019-05-21 21:28:41 +00:00
greenkeeper[bot] 1559c74fd9 chore(package): update @babel/core to version 7.4.5 2019-05-21 21:28:37 +00:00
greenkeeper[bot] 2cd30b1bfb chore(package): update lockfile package-lock.json 2019-05-15 11:23:47 +00:00
greenkeeper[bot] cd5e5589a4 chore(package): update uglifyjs-webpack-plugin to version 2.1.3 2019-05-15 11:23:43 +00:00
greenkeeper[bot] 5499093810 chore(package): update lockfile package-lock.json 2019-05-09 04:49:09 +00:00
greenkeeper[bot] df54ddda33 chore(package): update codecov to version 3.4.0 2019-05-09 04:49:04 +00:00
greenkeeper[bot] 80ebc0aa8c chore(package): update lockfile package-lock.json 2019-05-07 14:38:14 +00:00
greenkeeper[bot] a5fa336a08 chore(package): update grunt-qunit-istanbul to version 1.1.0 2019-05-07 14:38:06 +00:00
koalyptus 36d4f85f6c
Merge pull request #708 from koalyptus/greenkeeper/monorepo.babel7-20190426211543
Update babel7 to the latest version 🚀
2019-04-28 11:49:01 +10:00
koalyptus e886a6f1a8 prepare dist 2019-04-28 11:32:55 +10:00
koalyptus 7204746e5f Merge branch 'master' into greenkeeper/monorepo.babel6-20190426211543 2019-04-28 11:25:36 +10:00
koalyptus ecd33d0631 Add support template 2019-04-28 11:21:18 +10:00
greenkeeper[bot] f97394fc32 chore(package): update lockfile package-lock.json 2019-04-26 22:51:31 +00:00
greenkeeper[bot] eef0ab3bbd chore(package): update @babel/preset-env to version 7.4.4 2019-04-26 22:51:26 +00:00
greenkeeper[bot] c48b48f924 chore(package): update @babel/core to version 7.4.4 2019-04-26 22:51:23 +00:00
koalyptus d699d02914 Update feature request template 2019-04-26 22:53:03 +10:00
koalyptus 09b3f7875d
Merge pull request #706 from koalyptus/koalyptus-patch-1
Update issue templates
2019-04-26 22:34:54 +10:00
koalyptus 9c54974338 Update issue templates 2019-04-26 22:28:22 +10:00
koalyptus b89a52fb77
Merge pull request #698 from koalyptus/greenkeeper/codecov-3.3.0
Update codecov to the latest version 🚀
2019-04-20 22:47:26 +10:00
koalyptus ef46fd4295 bump tf version 2019-04-20 22:39:59 +10:00
koalyptus 8d8c8ae74c Merge branch 'master' into greenkeeper/codecov-4.3.0 2019-04-20 22:33:56 +10:00
koalyptus fafa983dac
Merge pull request #697 from koalyptus/greenkeeper/monorepo.babel7-20190402222217
Update babel7 to the latest version 🚀
2019-04-15 22:25:21 +10:00
koalyptus a19c5a106f prepare dist 2019-04-15 22:10:43 +10:00
koalyptus 1e391233dc Merge branch 'master' into greenkeeper/monorepo.babel-20190402222217 2019-04-15 21:12:35 +10:00
koalyptus aade342976
Merge pull request #696 from koalyptus/greenkeeper/eslint-5.16.0
Update eslint to the latest version 🚀
2019-04-08 16:22:18 +10:00
koalyptus 0443442916
Update package-lock.json 2019-04-05 09:41:27 +11:00
greenkeeper[bot] ed4979331c chore(package): update lockfile package-lock.json 2019-04-03 12:03:37 +00:00
greenkeeper[bot] 0e1a1ff3d1 chore(package): update codecov to version 3.3.0 2019-04-03 12:03:32 +00:00
greenkeeper[bot] e71b3a5c93 chore(package): update lockfile package-lock.json 2019-04-02 22:27:02 +00:00
greenkeeper[bot] a22b009c57 chore(package): update @babel/preset-env to version 7.4.3 2019-04-02 22:26:58 +00:00
greenkeeper[bot] f6a9a058c9 chore(package): update @babel/core to version 7.4.3 2019-04-02 22:26:54 +00:00
koalyptus f7c231b99f
Update package.json 2019-04-02 20:53:29 +11:00
greenkeeper[bot] 6f4e5a91ab chore(package): update eslint to version 5.16.0 2019-03-30 18:26:17 +00:00
koalyptus f405a45d79
Merge pull request #694 from koalyptus/greenkeeper/clean-webpack-plugin-2.0.1
Greenkeeper/clean webpack plugin 2.0.1
2019-03-27 13:59:39 +11:00
koalyptus fbe43b1db4 Fix clean-webpack-plugin usage as not backwards compatible 2019-03-27 13:49:35 +11:00
koalyptus e13201733d Merge branch 'master' into greenkeeper/clean-webpack-plugin-2.0.1 2019-03-27 13:12:25 +11:00
koalyptus 002c46297e
Merge pull request #693 from koalyptus/greenkeeper/monorepo.babel7-20190319230952
Update babel7 to the latest version 🚀
2019-03-27 11:45:50 +11:00
koalyptus 017337b2e2
Update package-lock.json 2019-03-26 22:17:50 +11:00
koalyptus 51679ad61b
Update package-lock.json 2019-03-26 22:17:07 +11:00
koalyptus bc34e8b187
Update package.json 2019-03-26 22:16:18 +11:00
greenkeeper[bot] 58e90cb766 chore(package): update lockfile package-lock.json 2019-03-19 23:14:46 +00:00
greenkeeper[bot] 3243fad4da chore(package): update @babel/preset-env to version 7.4.0 2019-03-19 23:14:42 +00:00
greenkeeper[bot] ea2a8be8b6 chore(package): update @babel/core to version 7.4.0 2019-03-19 23:14:39 +00:00
koalyptus 5e1fe901b7
Merge pull request #692 from koalyptus/greenkeeper/eslint-5.15.2
Update eslint to the latest version 🚀
2019-03-20 07:13:32 +11:00
koalyptus c001e90617 bump TableFilter version 2019-03-19 22:07:00 +11:00
greenkeeper[bot] a446c0afc0 chore(package): update lockfile package-lock.json 2019-03-16 00:10:05 +00:00
greenkeeper[bot] ff88f6c7d7 chore(package): update eslint to version 5.15.2 2019-03-16 00:10:00 +00:00
greenkeeper[bot] d46265eb57 chore(package): update lockfile package-lock.json 2019-03-14 18:54:50 +00:00
greenkeeper[bot] 3057b1949c chore(package): update clean-webpack-plugin to version 2.0.1
Closes #690
2019-03-14 18:54:47 +00:00
koalyptus bca2cee175
Merge pull request #689 from koalyptus/greenkeeper/eslint-5.15.0
Update eslint to the latest version 🚀
2019-03-06 14:01:58 +11:00
koalyptus 077eb3fe87
Update package.json 2019-03-06 13:56:56 +11:00
koalyptus 90e4367951
Update package-lock.json 2019-03-06 13:56:41 +11:00
greenkeeper[bot] 589b356bc6 chore(package): update lockfile package-lock.json 2019-03-02 06:35:38 +00:00
greenkeeper[bot] 7664e054e5 chore(package): update eslint to version 5.15.0 2019-03-02 06:35:34 +00:00
koalyptus 2dcad20d0c
Merge pull request #688 from koalyptus/greenkeeper/monorepo.babel7-20190225223535
Update babel7 to the latest version 🚀
2019-02-28 13:57:08 +11:00
koalyptus 86369ff116
Merge branch 'master' into greenkeeper/monorepo.babel7-20190225223535 2019-02-28 13:23:19 +11:00
koalyptus f1bdd8997f
Update package.json 2019-02-28 13:22:29 +11:00
koalyptus eefbf3fe41
Update package-lock.json 2019-02-28 13:22:17 +11:00
koalyptus 0b455e2ec4
Merge pull request #687 from koalyptus/greenkeeper/uglifyjs-webpack-plugin-2.1.2
Update uglifyjs-webpack-plugin to the latest version 🚀
2019-02-27 13:26:28 +11:00
koalyptus de6745821f
Update package.json 2019-02-26 21:18:40 +11:00
koalyptus f79234ea7e
Update package-lock.json 2019-02-26 21:18:07 +11:00
greenkeeper[bot] 8bcf731d3c chore(package): update lockfile package-lock.json 2019-02-25 22:37:50 +00:00
greenkeeper[bot] 5247493035 chore(package): update @babel/preset-env to version 7.3.4 2019-02-25 22:37:45 +00:00
greenkeeper[bot] 69a1fd3ee9 chore(package): update @babel/core to version 7.3.4 2019-02-25 22:37:41 +00:00
greenkeeper[bot] 9c80252935 chore(package): update lockfile package-lock.json 2019-02-25 13:34:31 +00:00
greenkeeper[bot] c22f9981e6 chore(package): update uglifyjs-webpack-plugin to version 2.1.2 2019-02-25 13:34:27 +00:00
koalyptus 04012e5a97
Merge pull request #686 from koalyptus/greenkeeper/eslint-5.14.1
Update eslint to the latest version 🚀
2019-02-19 22:20:33 +11:00
koalyptus 02997076d4
Merge branch 'master' into greenkeeper/eslint-5.14.1 2019-02-19 21:26:47 +11:00
koalyptus 9117097750
Update package.json 2019-02-19 21:26:06 +11:00
koalyptus e3f9851848
Update package-lock.json 2019-02-19 21:25:42 +11:00
koalyptus f1febe1688
Merge pull request #685 from koalyptus/679-uuid-generator-fix
fix TableFilter table id generation with more robust uuid generator
2019-02-19 21:14:50 +11:00
greenkeeper[bot] cf9a566e92 chore(package): update lockfile package-lock.json 2019-02-18 18:51:39 +00:00
greenkeeper[bot] 34e8b4099b chore(package): update eslint to version 5.14.1 2019-02-18 18:51:36 +00:00
koalyptus 495b64ecf0 fix TableFilter table id generation with more robust uuid generator 2019-02-18 22:50:04 +11:00
koalyptus 0a69a99dc5
Merge pull request #682 from koalyptus/feature-registering
Feature registering
2019-02-16 22:02:55 +11:00
koalyptus 2d9671e10d upgrade various packages 2019-02-16 21:52:06 +11:00
koalyptus 0f380c03da Merge remote-tracking branch 'origin/greenkeeper/monorepo.babel7-20190216020312' into feature-registering 2019-02-16 21:38:42 +11:00
koalyptus df85babf34 Merge remote-tracking branch 'origin/greenkeeper/codecov-3.2.0' into feature-registering 2019-02-16 21:32:51 +11:00
koalyptus 131280c1a3 merge eslint 2019-02-16 20:23:52 +11:00
greenkeeper[bot] 372473227c chore(package): update lockfile package-lock.json 2019-02-16 02:04:34 +00:00
greenkeeper[bot] cb7fc0d4fa chore(package): update @babel/core to version 7.3.3 2019-02-16 02:04:29 +00:00
greenkeeper[bot] c3b5ef529c chore(package): update lockfile package-lock.json 2019-02-15 22:06:24 +00:00
greenkeeper[bot] 89b1814c2d chore(package): update eslint to version 5.14.0 2019-02-15 22:06:18 +00:00
koalyptus 9a1202c0b5 merge master in, fix conflict 2019-02-15 21:41:56 +11:00
koalyptus 95475b022d prepare dist 2019-02-15 21:37:30 +11:00
koalyptus 8b1d3a6e23 fix extesion registering 2019-02-15 14:16:35 +11:00
greenkeeper[bot] 6b2fbd1eef chore(package): update lockfile package-lock.json 2019-02-13 02:15:43 +00:00
greenkeeper[bot] 8d1dc88f6a chore(package): update codecov to version 3.2.0 2019-02-13 02:15:38 +00:00
koalyptus 34c56e5765 Fix class name registering 2019-02-10 23:14:46 +11:00
koalyptus 87ee312fc5 undo Register class 2019-02-10 00:38:11 +11:00
koalyptus df0221d5e7 refactor feature istantiation helpers 2019-02-10 00:27:55 +11:00
koalyptus 528d587a80 continue messing around 2019-02-07 07:27:52 +11:00
koalyptus b8bdff83aa
Merge pull request #676 from koalyptus/greenkeeper/monorepo.babel7-20190205012427
Update babel7 to the latest version 🚀
2019-02-06 13:15:33 +11:00
koalyptus d40244b7e5
Update package.json 2019-02-06 12:59:41 +11:00
koalyptus ec7799b57b
Update package-lock.json 2019-02-06 12:59:29 +11:00
greenkeeper[bot] fa28abbee8 chore(package): update lockfile package-lock.json 2019-02-05 01:26:33 +00:00
greenkeeper[bot] e06dfbdc35 chore(package): update @babel/preset-env to version 7.3.1 2019-02-05 01:26:29 +00:00
koalyptus 64f56c22a4 include files in git 2019-01-22 22:23:36 +11:00
koalyptus ecfa6c64ad wip continue 2019-01-22 22:23:00 +11:00
koalyptus 37f6db7025 wip 2019-01-15 23:29:13 +11:00
koalyptus bfa440b265
Merge pull request #674 from koalyptus/webpack-dev-server-secutity-update
Webpack dev server secutity update
2019-01-06 20:51:20 +11:00
koalyptus bf9cbd0a69 prepare dist package 2019-01-06 20:43:34 +11:00
koalyptus 967ae801b4
Update package-lock.json 2019-01-06 20:30:22 +11:00
koalyptus 066c5fee56
Update package.json 2019-01-06 20:28:07 +11:00
koalyptus 807c191a01
Update package.json 2019-01-06 20:27:50 +11:00
koalyptus 9382a07c7b
Merge pull request #673 from koalyptus/greenkeeper/sugar-date-2.0.6
Greenkeeper/sugar date 2.0.6
2018-12-31 14:00:02 +11:00
koalyptus 8b09b6feab fix unit tests 2018-12-31 13:52:15 +11:00
koalyptus d733766621
Merge pull request #672 from koalyptus/greenkeeper/uglifyjs-webpack-plugin-2.1.1
Update uglifyjs-webpack-plugin to the latest version 🚀
2018-12-31 13:18:24 +11:00
koalyptus ceba24d727
Merge branch 'master' into greenkeeper/uglifyjs-webpack-plugin-2.1.1 2018-12-31 13:13:52 +11:00
koalyptus c25cae1679
Update package.json 2018-12-31 13:12:15 +11:00
koalyptus 04342ac316
Update package-lock.json 2018-12-31 13:12:02 +11:00
koalyptus 0ad57767f8
Merge pull request #671 from koalyptus/greenkeeper/grunt-shell-3.0.0
Update grunt-shell to the latest version 🚀
2018-12-28 13:52:55 +11:00
koalyptus fd56dabea8
Merge branch 'master' into greenkeeper/grunt-shell-3.0.0 2018-12-28 13:48:12 +11:00
koalyptus 0b11de4f90
Update package.json 2018-12-28 13:47:30 +11:00
koalyptus bbd0ce06ce
Update package-lock.json 2018-12-28 13:47:15 +11:00
greenkeeper[bot] 500344c64a chore(package): update lockfile package-lock.json 2018-12-27 12:49:53 +00:00
greenkeeper[bot] 5845f8c52d chore(package): update uglifyjs-webpack-plugin to version 2.1.1 2018-12-27 12:49:49 +00:00
koalyptus d232f64fa5
Merge pull request #670 from koalyptus/greenkeeper/uglifyjs-webpack-plugin-2.1.0
Update uglifyjs-webpack-plugin to the latest version 🚀
2018-12-27 21:16:04 +11:00
koalyptus 53a77d1b97
Merge branch 'master' into greenkeeper/uglifyjs-webpack-plugin-2.1.0 2018-12-27 21:12:10 +11:00
koalyptus 44ce01be4b
Update package.json 2018-12-27 21:10:15 +11:00
koalyptus 1f17364a00
Update package-lock.json 2018-12-27 21:09:48 +11:00
koalyptus a437dad841
Merge pull request #669 from koalyptus/greenkeeper/monorepo.babel7-20181220134640
Update babel7 to the latest version 🚀
2018-12-27 15:14:36 +11:00
koalyptus 99b34c07b4
Update package-lock.json 2018-12-27 14:38:21 +11:00
koalyptus ff977281c7
Update package.json 2018-12-27 14:38:05 +11:00
greenkeeper[bot] bf667cdd6f chore(package): update lockfile package-lock.json 2018-12-22 22:11:45 +00:00
greenkeeper[bot] 94d6d59593 chore(package): update grunt-shell to version 3.0.0 2018-12-22 22:11:42 +00:00
greenkeeper[bot] 1fc5fa5f8a chore(package): update lockfile package-lock.json 2018-12-22 16:31:56 +00:00
greenkeeper[bot] 34d35a3495 chore(package): update uglifyjs-webpack-plugin to version 2.1.0 2018-12-22 16:31:52 +00:00
greenkeeper[bot] 9750b07e06 chore(package): update lockfile package-lock.json 2018-12-20 13:52:14 +00:00
greenkeeper[bot] bfe6b6dc2c chore(package): update @babel/preset-env to version 7.2.3 2018-12-20 13:52:10 +00:00
koalyptus 67b1d4b65e
Merge pull request #668 from koalyptus/greenkeeper/monorepo.babel7-20181215114759
Update babel7 to the latest version 🚀
2018-12-17 13:17:18 +11:00
koalyptus c7482bec2d
Update package.json 2018-12-16 20:24:25 +11:00
koalyptus b38bc836ee
Update package-lock.json 2018-12-16 20:24:01 +11:00
greenkeeper[bot] 79d06ff09e chore(package): update lockfile package-lock.json 2018-12-15 11:52:27 +00:00
greenkeeper[bot] bd6afe484c chore(package): update @babel/preset-env to version 7.2.0 2018-12-15 11:52:23 +00:00
greenkeeper[bot] 6560392771 chore(package): update @babel/core to version 7.2.2 2018-12-15 11:52:20 +00:00
greenkeeper[bot] 599717ae14 chore(package): update lockfile package-lock.json 2018-12-05 14:32:04 +00:00
greenkeeper[bot] e96273e95f chore(package): update sugar-date to version 2.0.6
Closes #666
2018-12-05 14:32:00 +00:00
koalyptus dcc0a43258
Merge pull request #662 from koalyptus/greenkeeper/monorepo.babel7-7.1.6
Update babel7 to the latest version 🚀
2018-11-15 21:19:52 +11:00
koalyptus 31ece0ff81
Update package-lock.json 2018-11-15 20:27:35 +11:00
koalyptus db0c95e197
Update package.json 2018-11-15 20:27:07 +11:00
greenkeeper[bot] 2945c27ae9 chore(package): update lockfile package-lock.json 2018-11-14 16:43:54 +00:00
greenkeeper[bot] 786bb519b0 chore(package): update @babel/preset-env to version 7.1.6 2018-11-14 16:43:51 +00:00
greenkeeper[bot] db1ecaec42 chore(package): update @babel/core to version 7.1.6 2018-11-14 16:43:48 +00:00
koalyptus 3f74756d58
Merge pull request #661 from koalyptus/greenkeeper/clean-webpack-plugin-1.0.0
Update clean-webpack-plugin to the latest version 🚀
2018-11-14 14:01:05 +11:00
koalyptus dca79c8391
Update package-lock.json 2018-11-14 13:42:56 +11:00
koalyptus dd6de7f219
Update package.json 2018-11-14 13:42:39 +11:00
greenkeeper[bot] 4e222fd98c chore(package): update lockfile package-lock.json 2018-11-12 00:10:56 +00:00
greenkeeper[bot] e45c7ce863 chore(package): update clean-webpack-plugin to version 1.0.0 2018-11-12 00:10:52 +00:00
koalyptus b45815cfc7
Merge pull request #660 from koalyptus/greenkeeper/monorepo.babel7-7.1.5
Greenkeeper/monorepo.babel7 7.1.5
2018-11-07 13:40:58 +11:00
koalyptus 481c7c3970
Update package-lock.json 2018-11-07 13:32:52 +11:00
koalyptus 6b47928c92
Update package.json 2018-11-07 13:32:28 +11:00
greenkeeper[bot] 259a88d0c5 chore(package): update lockfile package-lock.json 2018-11-07 00:41:08 +00:00
greenkeeper[bot] 91ec79d226 chore(package): update @babel/preset-env to version 7.1.5
Closes #652
2018-11-07 00:41:04 +00:00
greenkeeper[bot] 6630a87263 chore(package): update @babel/core to version 7.1.5
Closes #652
2018-11-07 00:41:02 +00:00
koalyptus 4d4d1f4212
Merge pull request #659 from koalyptus/greenkeeper/grunt-cli-1.3.2
Update grunt-cli to the latest version 🚀
2018-11-05 17:23:26 +11:00
koalyptus 7631b51f3d
Update package-lock.json 2018-11-05 11:00:17 +11:00
koalyptus 5bde707a0c
Update package.json 2018-11-05 10:59:41 +11:00
greenkeeper[bot] 2cea817247 chore(package): update lockfile package-lock.json 2018-11-04 19:31:28 +00:00
greenkeeper[bot] 68acd1fcb7 chore(package): update grunt-cli to version 1.3.2 2018-11-04 19:31:24 +00:00
koalyptus 4d424d1d7e
Merge pull request #657 from koalyptus/656-fix-loader
fix events loader subscribes to
2018-10-27 22:12:21 +11:00
koalyptus 50fda2a900 fix events loader subscribes to 2018-10-27 21:46:27 +11:00
koalyptus 335f97a9de
Merge pull request #655 from koalyptus/greenkeeper/babel-eslint-10.0.0
Update babel-eslint to the latest version 🚀
2018-10-05 14:03:41 +10:00
koalyptus a7e0f235a3
Update package.json 2018-10-05 10:00:17 +10:00
greenkeeper[bot] d6a79e14fc chore(package): update lockfile package-lock.json 2018-09-25 22:33:52 +00:00
greenkeeper[bot] 7e780f3463 chore(package): update babel-eslint to version 10.0.0 2018-09-25 22:28:44 +00:00
koalyptus 439f183d95
Merge pull request #653 from koalyptus/greenkeeper/uglifyjs-webpack-plugin-2.0.1
Update uglifyjs-webpack-plugin to the latest version 🚀
2018-09-24 09:16:58 +02:00
koalyptus 10b80612fe
Update package.json 2018-09-24 17:02:15 +10:00
greenkeeper[bot] 72327b84cc chore(package): update lockfile package-lock.json 2018-09-18 16:43:39 +00:00
greenkeeper[bot] ba5323ab3b chore(package): update uglifyjs-webpack-plugin to version 2.0.1 2018-09-18 16:42:32 +00:00
koalyptus a9c0fd9c2f
Merge pull request #651 from koalyptus/591-linked-filters-enhancement
linked filters refactor
2018-09-17 12:02:52 +02:00
koalyptus e6049975ee remove commented out code leftovers 2018-09-17 19:34:50 +10:00
koalyptus 62a55c8d95 linked filters refactor 2018-09-17 19:32:16 +10:00
koalyptus 5d4def11fc
Merge pull request #650 from koalyptus/greenkeeper/uglifyjs-webpack-plugin-2.0.0
Update uglifyjs-webpack-plugin to the latest version 🚀
2018-09-17 10:04:36 +02:00
koalyptus 13eb677b8e
Update package.json 2018-09-17 17:53:09 +10:00
greenkeeper[bot] d48bbeaab5 chore(package): update lockfile package-lock.json 2018-09-14 16:26:57 +00:00
greenkeeper[bot] 6fec4947c4 chore(package): update uglifyjs-webpack-plugin to version 2.0.0 2018-09-14 16:24:23 +00:00
koalyptus d3634bce5f
Merge pull request #648 from koalyptus/628-highlight-auto-filter
fix unhighlight all
2018-09-12 17:58:23 +02:00
koalyptus 6813debb6e fix unit tests 2018-09-13 01:52:51 +10:00
koalyptus b14667a345 more unit tests 2018-09-13 01:44:23 +10:00
koalyptus 2f825a25b4 fix unhighlight all 2018-09-13 01:23:20 +10:00
koalyptus cca223c4d4
Merge pull request #647 from koalyptus/greenkeeper/monorepo.babel7-7.0.1
Update babel7 to the latest version 🚀
2018-09-12 16:13:42 +02:00
koalyptus 09243a9bdb include grunt contrib pkg bumps 2018-09-13 00:10:07 +10:00
greenkeeper[bot] 24e0f3d184 chore(package): update lockfile 2018-09-12 03:40:22 +00:00
greenkeeper[bot] d70cf23624 chore(package): update @babel/core to version 7.0.1 2018-09-12 03:38:51 +00:00
koalyptus 2d963e782f
Merge pull request #641 from koalyptus/greenkeeper/babel-loader-8.0.2
chore(package): update babel-loader to version 8.0.2
2018-09-10 10:11:18 +02:00
koalyptus c100f0f63f
Merge branch 'master' into greenkeeper/babel-loader-8.0.2 2018-09-10 10:05:32 +02:00
koalyptus 875fdc2603 Fix babel-loader 8.x deps, keep old babel deps for test config... 2018-09-10 18:06:40 +10:00
koalyptus 4bdf873ec8
Merge pull request #643 from koalyptus/greenkeeper/codecov-3.1.0
Update codecov to the latest version 🚀
2018-09-08 15:59:08 +02:00
koalyptus d1875f19f2
Update package.json 2018-09-06 14:10:30 +10:00
greenkeeper[bot] 5254983778 chore(package): update codecov to version 3.1.0 2018-09-04 23:33:04 +00:00
koalyptus 7e13d59d0f
Update package.json 2018-09-03 10:40:41 +10:00
greenkeeper[bot] a66402e139 chore(package): update babel-loader to version 8.0.2
Closes #640
2018-09-03 00:32:39 +00:00
koalyptus 8cb8f74fa3
Merge pull request #639 from koalyptus/greenkeeper/babel-eslint-9.0.0
Update babel-eslint to the latest version 🚀
2018-08-29 09:21:17 +10:00
koalyptus c5775ae8aa
Update package.json 2018-08-29 09:14:39 +10:00
greenkeeper[bot] a10d3a2830 chore(package): update babel-eslint to version 9.0.0 2018-08-28 02:30:08 +00:00
koalyptus 2e089a1823
Merge pull request #638 from koalyptus/fixed-headers
sticky headers enhancement
2018-08-26 11:48:13 +10:00
koalyptus 3231da9760 sticky headers enhancement 2018-08-26 11:56:51 +10:00
koalyptus 7533499c40
Merge pull request #637 from koalyptus/greenkeeper/grunt-cli-1.3.1
Update grunt-cli to the latest version 🚀
2018-08-20 17:07:37 +10:00
koalyptus 80cf351eab
Update package.json 2018-08-20 16:46:35 +10:00
greenkeeper[bot] d790156373 chore(package): update grunt-cli to version 1.3.1 2018-08-19 03:59:49 +00:00
koalyptus 70d791f41c
Merge pull request #636 from koalyptus/greenkeeper/grunt-cli-1.3.0
Update grunt-cli to the latest version 🚀
2018-08-17 11:22:48 +10:00
koalyptus f1f28b51cb
Update package.json 2018-08-17 09:40:50 +10:00
greenkeeper[bot] 8a94f2ffd2 chore(package): update grunt-cli to version 1.3.0 2018-08-16 00:10:38 +00:00
koalyptus a0f9f28397
Merge pull request #634 from koalyptus/greenkeeper/uglifyjs-webpack-plugin-1.3.0
Update uglifyjs-webpack-plugin to the latest version 🚀
2018-08-15 13:56:12 +10:00
koalyptus 71292db999
Update package.json 2018-08-15 13:50:38 +10:00
greenkeeper[bot] 42a40a295b chore(package): update uglifyjs-webpack-plugin to version 1.3.0 2018-08-14 15:46:54 +00:00
koalyptus 7a90cb5b13
Merge pull request #633 from koalyptus/donate
please npm
2018-08-09 10:08:02 +10:00
koalyptus 7eecd95122 please npm 2018-08-08 22:25:55 +10:00
koalyptus a45217bc9f add donate badge 2018-08-08 21:15:10 +10:00
koalyptus d14a0a359a
Merge pull request #632 from koalyptus/donate
add donate badge
2018-08-08 21:13:20 +10:00
koalyptus e09bab000b
Merge pull request #626 from koalyptus/625-fix-empty-filter-operator
refine empty-nonempty operator checks
2018-07-29 11:12:02 +10:00
koalyptus efffa40248 refine empty-nonempty operator checks 2018-07-29 11:18:16 +10:00
koalyptus 50afb94340
Merge pull request #622 from koalyptus/greenkeeper/babel-eslint-8.2.6
Update babel-eslint to the latest version 🚀
2018-07-16 09:52:29 +10:00
koalyptus d35ea7cb26
Update package.json 2018-07-13 16:31:21 +10:00
greenkeeper[bot] 52705e56f7 chore(package): update babel-eslint to version 8.2.6 2018-07-12 14:10:28 +00:00
koalyptus b34e5696f3
Merge pull request #621 from koalyptus/greenkeeper/codecov-3.0.4
Update codecov to the latest version 🚀
2018-07-09 13:11:21 +10:00
koalyptus 606cc00393
Update package.json 2018-07-09 10:41:08 +10:00
greenkeeper[bot] c728209c92 chore(package): update codecov to version 3.0.4 2018-07-09 00:17:55 +00:00
koalyptus 2e3bdda8bc
Merge pull request #620 from koalyptus/greenkeeper/codecov-3.0.3
Update codecov to the latest version 🚀
2018-07-06 20:18:09 +10:00
greenkeeper[bot] 7bc7b16cfc chore(package): update codecov to version 3.0.3 2018-07-06 04:41:52 +00:00
koalyptus c5bc7cbb33
Merge pull request #618 from koalyptus/greenkeeper/eslint-5.0.1
Update eslint to the latest version 🚀
2018-07-02 19:26:57 +10:00
koalyptus ec6d0779a1
Update package.json 2018-06-29 14:20:16 +10:00
greenkeeper[bot] bcbfe5251f chore(package): update eslint to version 5.0.1 2018-06-26 05:39:20 +00:00
koalyptus 453ff1c59c
Merge pull request #617 from koalyptus/greenkeeper/uglifyjs-webpack-plugin-1.2.7
Update uglifyjs-webpack-plugin to the latest version 🚀
2018-06-26 14:23:31 +10:00
koalyptus 948055da09
Merge branch 'master' into greenkeeper/uglifyjs-webpack-plugin-1.2.7 2018-06-26 13:54:36 +10:00
koalyptus f534a8b23f
Update package.json 2018-06-26 13:54:09 +10:00
koalyptus 6c23ae883f
Merge pull request #616 from koalyptus/greenkeeper/babel-eslint-8.2.5
Update babel-eslint to the latest version 🚀
2018-06-26 13:52:34 +10:00
koalyptus 55e4d6b511
Merge branch 'master' into greenkeeper/babel-eslint-8.2.5 2018-06-26 13:34:16 +10:00
koalyptus 2d5f7401f9
Update package.json 2018-06-26 13:33:34 +10:00
koalyptus 00143a686b
Merge pull request #615 from koalyptus/greenkeeper/eslint-5.0.0
Update eslint to the latest version 🚀
2018-06-26 13:32:26 +10:00
koalyptus 46f7028580
Update package.json 2018-06-26 13:14:45 +10:00
greenkeeper[bot] 313336ab5f chore(package): update uglifyjs-webpack-plugin to version 1.2.7 2018-06-25 18:29:06 +00:00
greenkeeper[bot] 89851eae3b chore(package): update babel-eslint to version 8.2.5 2018-06-23 16:19:05 +00:00
greenkeeper[bot] e49538c442 chore(package): update eslint to version 5.0.0 2018-06-23 05:36:13 +00:00
koalyptus cb0aa73a6d
bump version - babel-eslint upgrade 2018-06-23 11:15:43 +10:00
koalyptus 9b89b78f38
Merge pull request #614 from koalyptus/greenkeeper/babel-eslint-8.2.4
Update babel-eslint to the latest version 🚀
2018-06-23 11:06:25 +10:00
greenkeeper[bot] 1a32ef216b chore(package): update babel-eslint to version 8.2.4 2018-06-22 20:32:47 +00:00
koalyptus bcf7189bbc
Merge pull request #612 from koalyptus/greenkeeper/uglifyjs-webpack-plugin-1.2.6
Update uglifyjs-webpack-plugin to the latest version 🚀
2018-06-21 15:25:46 +10:00
greenkeeper[bot] 9a55c86e5f chore(package): update uglifyjs-webpack-plugin to version 1.2.6 2018-06-20 14:49:58 +00:00
koalyptus c710fa3585
Merge pull request #611 from koalyptus/580-sticky-head
580 sticky head
2018-06-17 21:29:01 +10:00
koalyptus a5164f4ba5 remove 1px gap on sticky headers 2018-06-17 21:21:41 +10:00
koalyptus 0babe0249e test case 2018-06-17 20:39:04 +10:00
koalyptus ca4f0f2afa remove sticky css class on destroy 2018-06-17 20:23:41 +10:00
koalyptus 00150bc9e1 implement sticky headers 2018-06-16 00:21:26 +10:00
koalyptus 46b21b4a20 fix webpack-cli upgrade (remaining es2015 preset ref) 2018-06-15 21:30:00 +10:00
koalyptus 89b0cf843a try name property in travis releases provider 2018-06-15 21:06:57 +10:00
koalyptus 946f600260 re-instate source maps 2018-06-15 20:47:30 +10:00
koalyptus 0cd8fb2aa3
Merge pull request #609 from koalyptus/607-sort-support-cell-parser
missing file
2018-06-09 22:44:34 +10:00
koalyptus ad8c86c599 missing file 2018-06-09 22:50:45 +10:00
koalyptus bf1bdc5a0e
Merge pull request #608 from koalyptus/607-sort-support-cell-parser
support cellparser in sort adapter, fix function name with uglifyjs option
2018-06-09 22:14:30 +10:00
koalyptus ed01c6e201 support cellparser in sort adapter, fix function name with uglifyjs option 2018-06-09 22:09:37 +10:00
koalyptus b4905f7703
Merge pull request #604 from koalyptus/603-alternate-rows-fix
alternate rows background inconsistency fix
2018-06-02 13:51:13 +10:00
koalyptus 2cc28e8072 alternate rows background inconsistency fix 2018-06-02 13:48:07 +10:00
koalyptus 521d02c374
Merge pull request #602 from koalyptus/598-pagination-toggle-fix
introduce bound helper function
2018-05-20 21:46:03 +10:00
koalyptus fe51fdecb8 introduce bound helper function 2018-05-20 21:43:20 +10:00
koalyptus bfa23c3b6e
Merge pull request #601 from koalyptus/599-colvis-gridlayout-fix
fix colvis bug with grid-layout on
2018-05-18 16:20:56 +10:00
koalyptus 2abd81906b url typo in package.json 2018-05-18 16:05:55 +10:00
koalyptus f1e046e331 fix colvis bug with grid-layout on 2018-05-18 15:50:34 +10:00
koalyptus ea8ca2a125 remove deployment to gh-pages, correct website url, bump version 2018-05-06 11:29:37 +10:00
koalyptus 6bc6c8a8eb remove deployment to gh-pages, correct website url 2018-05-06 11:24:38 +10:00
koalyptus c0520dd4bb deploy dist and docs to s3, separate travis providers 2018-05-06 10:46:56 +10:00
koalyptus 3d7945b09c deploy dist and docs to s3, keep deployment to gh-pages 2018-05-06 10:34:49 +10:00
koalyptus 84c964bf13 bump version 2018-05-05 19:31:45 +10:00
koalyptus c7d6de72f7 revert gh-pages in travis 2018-05-05 18:13:54 +10:00
koalyptus 81f31a3106 fix git tag cmd in travis (5) 2018-05-05 17:41:30 +10:00
koalyptus 3995dee394 fix git tag cmd in travis (4) 2018-05-05 17:26:27 +10:00
koalyptus 7540169fcd fix git tag cmd in travis (3) 2018-05-05 17:23:24 +10:00
koalyptus 4bff89b70c fix git tag cmd in travis (2) 2018-05-05 16:57:11 +10:00
koalyptus c8df8992b3 fix git tag cmd in travis (1) 2018-05-05 16:47:10 +10:00
koalyptus 4889b29cda fix git tag cmd in travis 2018-05-05 16:38:25 +10:00
koalyptus b3101a8871
Merge pull request #597 from koalyptus/gh-pages-travis
gh-pages provider in travis
2018-05-05 16:19:26 +10:00
koalyptus bf2f2bd747 gh-pages provider in travis 2018-05-05 16:14:20 +10:00
koalyptus b08b517fa7
Merge pull request #593 from koalyptus/greenkeeper/esdoc-1.1.0
Update esdoc to the latest version 🚀
2018-05-01 08:11:50 +10:00
koalyptus f2c5edbfb8
Update package.json 2018-04-30 13:11:41 +10:00
greenkeeper[bot] ca6ced712a chore(package): update esdoc to version 1.1.0 2018-04-29 10:36:49 +00:00
koalyptus 0d95699fa6 bump version for codecov update + fix build error 2018-04-29 18:01:36 +10:00
koalyptus 4378141d7d Conditional git tag command in travis 2018-04-29 17:42:31 +10:00
koalyptus 0631fd2ef7
Merge pull request #592 from koalyptus/greenkeeper/codecov-3.0.1
Update codecov to the latest version 🚀
2018-04-29 06:54:59 +10:00
greenkeeper[bot] 7cbb38d9ba chore(package): update codecov to version 3.0.1 2018-04-27 00:19:37 +00:00
koalyptus edd2494899
Merge pull request #590 from koalyptus/test-pr-travis-deploy
Test pr travis deploy
2018-04-22 22:11:36 +10:00
koalyptus 49eb4b7bd6 bump package version 2018-04-22 22:17:02 +10:00
koalyptus 5d4627277a Merge branch 'master' into test-pr-travis-deploy 2018-04-22 22:16:10 +10:00
koalyptus 907ccd5e4a
Merge pull request #589 from koalyptus/test-pr-travis-deploy
Define master branch in deploy section travis.yaml
2018-04-22 21:59:22 +10:00
koalyptus c26e6d3c4b Define master branch in deploy section travis.yaml 2018-04-22 21:58:50 +10:00
koalyptus e1106f23a8 travis: git tags automation (10) 2018-04-22 21:35:09 +10:00
koalyptus 7909cde78b travis: git tags automation (9) 2018-04-22 21:28:20 +10:00
koalyptus bc416e0e39 travis: git tags automation (8) 2018-04-22 21:14:47 +10:00
koalyptus 934ba4add0 travis: git tags automation (7) 2018-04-22 20:42:53 +10:00
koalyptus 73fc78e9e3 travis: git tags automation (6) 2018-04-22 15:39:55 +10:00
koalyptus c1000b7684 travis: git tags automation (5) 2018-04-22 15:25:41 +10:00
koalyptus a34009f1e9 travis: git tags automation (4) 2018-04-22 15:08:41 +10:00
koalyptus 51e27c4a2f travis: git tags automation (3) 2018-04-22 14:24:10 +10:00
koalyptus 2fee4d95f2 travis: git tags automation (2) 2018-04-22 14:12:22 +10:00
koalyptus 5b6919ba39 travis: git tags automation (1) 2018-04-22 13:37:49 +10:00
koalyptus 974bb3cc77 travis: git tags automation (0) 2018-04-22 13:06:51 +10:00
koalyptus 1a1560d636 Add missing starter.html file 2018-04-18 10:27:41 +10:00
koalyptus 2d3f67d504 $npm_package_version 2018-04-15 22:48:19 +10:00
koalyptus 81c593382a Merge branch 'toolbar-min-width-1' 2018-04-15 22:33:24 +10:00
koalyptus 62cab3ac2c Add git config to before_script in travis yaml 2018-04-15 22:32:59 +10:00
koalyptus 4ac92a3e73 Merge branch 'toolbar-min-width-0' 2018-04-15 22:10:28 +10:00
koalyptus da8977433d wip 2018-04-15 22:06:47 +10:00
koalyptus cde2e8a326
Merge pull request #588 from koalyptus/toolbar-min-width
amend release command (0)
2018-04-15 21:25:15 +10:00
koalyptus 7b03e23f3c amend release command (0) 2018-04-15 17:52:13 +10:00
koalyptus dc3d40b12c
Merge pull request #587 from koalyptus/toolbar-min-width
Toolbar min-width + add npm release command
2018-04-15 17:25:15 +10:00
koalyptus 48674c3b31 Toolbar min-width + add npm release command 2018-04-15 17:18:14 +10:00
koalyptus a92acfa615
Merge pull request #586 from koalyptus/greenkeeper/babel-eslint-8.2.3
Update babel-eslint to the latest version 🚀
2018-04-14 15:19:56 +10:00
greenkeeper[bot] be1bdf72cd chore(package): update babel-eslint to version 8.2.3 2018-04-13 15:37:24 +00:00
koalyptus b6d9bddc6f
Merge pull request #583 from koalyptus/auto-min-width
introduce default column width
2018-04-07 10:49:15 +10:00
koalyptus 025717f61c introduce default column width 2018-04-07 10:45:33 +10:00
koalyptus e09d30c2cd
Merge pull request #581 from koalyptus/auto-min-width
ensure table layout is fixed when cols widths are defined
2018-04-02 20:35:17 +10:00
koalyptus 39bbe6a19a ensure table layout is fixed when cols widths are defined 2018-04-02 18:01:28 +10:00
koalyptus 2f7b650f5b
Merge pull request #578 from koalyptus/greenkeeper/eslint-4.19.1
Update eslint to the latest version 🚀
2018-03-22 13:09:20 +11:00
greenkeeper[bot] 85092bbd1c chore(package): update eslint to version 4.19.1 2018-03-22 00:59:23 +00:00
koalyptus 3bed943a42
Merge pull request #577 from koalyptus/decommission-grunt-contrib-stylus
Decommission grunt contrib stylus
2018-03-18 13:35:44 +11:00
koalyptus 2452a0bd9e convert var to const in webpack configs 2018-03-18 13:31:54 +11:00
koalyptus 98aca44cb9 remove unused packages from package.json 2018-03-18 13:29:47 +11:00
koalyptus 33ed3cc194 prepare for PR 2018-03-18 13:20:44 +11:00
koalyptus 2da8a56659 wip 2018-03-18 12:59:33 +11:00
koalyptus 71d5cd7a49
Merge pull request #576 from koalyptus/greenkeeper/eslint-4.19.0
Update eslint to the latest version 🚀
2018-03-17 08:44:58 +11:00
greenkeeper[bot] 05c2d6b666 chore(package): update eslint to version 4.19.0 2018-03-16 21:32:05 +00:00
koalyptus 50f4a0014b wip 2018-03-16 16:21:41 +11:00
koalyptus 07eebbd528
Merge pull request #574 from koalyptus/kill-grunt-webpack
Kill grunt webpack
2018-03-03 10:59:30 +11:00
koalyptus 9ccc4dbfd4 update pr template 2018-03-03 10:51:29 +11:00
koalyptus 9d184df49a update readme 2018-03-03 10:49:32 +11:00
koalyptus d664ebb780 Merge branch 'master' into kill-grunt-webpack 2018-03-03 10:32:07 +11:00
koalyptus 0226300af8
Merge pull request #575 from koalyptus/greenkeeper/eslint-4.18.2
Update eslint to the latest version 🚀
2018-03-03 09:53:24 +11:00
greenkeeper[bot] 1e8e4a6467 chore(package): update eslint to version 4.18.2 2018-03-02 20:54:28 +00:00
koalyptus 0ec96ed520 remove accidental npm dep 2018-03-02 23:26:31 +11:00
koalyptus 11d01b1661 remove grunt-babel 2018-03-02 23:24:16 +11:00
koalyptus 2d0219b54d wip 2018-03-02 17:12:15 +11:00
koalyptus 317d795974
Merge pull request #573 from koalyptus/greenkeeper/webpack-4.0.1
Greenkeeper/webpack 4.0.1
2018-02-28 22:13:07 +11:00
koalyptus f2f853c517 Adopt webpack 4 2018-02-28 21:53:57 +11:00
greenkeeper[bot] 9468602f3d chore(package): update webpack to version 4.0.1
Closes #571
2018-02-26 20:36:41 +00:00
koalyptus cc0932f5f7
Merge pull request #572 from koalyptus/greenkeeper/webpack-dev-server-3.0.0
Update webpack-dev-server to the latest version 🚀
2018-02-26 09:03:16 +11:00
greenkeeper[bot] f97ff3a52d chore(package): update webpack-dev-server to version 3.0.0 2018-02-25 11:21:01 +00:00
koalyptus 8575d0ea68
Merge pull request #570 from koalyptus/greenkeeper/eslint-4.18.1
Update eslint to the latest version 🚀
2018-02-21 21:51:30 +11:00
koalyptus d274876976
Merge pull request #569 from koalyptus/greenkeeper/babel-eslint-8.2.2
Update babel-eslint to the latest version 🚀
2018-02-21 08:58:52 +11:00
greenkeeper[bot] a9737da2f6 chore(package): update eslint to version 4.18.1 2018-02-20 21:40:23 +00:00
greenkeeper[bot] 62964c2478 chore(package): update babel-eslint to version 8.2.2 2018-02-20 11:17:00 +00:00
koalyptus 71e7012ba0
Merge pull request #568 from koalyptus/greenkeeper/eslint-4.18.0
Update eslint to the latest version 🚀
2018-02-17 11:38:50 +11:00
greenkeeper[bot] 4a3fbbb736 chore(package): update eslint to version 4.18.0 2018-02-16 23:09:39 +00:00
koalyptus ee128f9d80
Merge pull request #567 from koalyptus/565-562-fixes
565 562 fixes
2018-02-13 22:11:23 +11:00
koalyptus 9b29d1632e dist package 2018-02-13 21:44:21 +11:00
koalyptus 1946d75125 Fix TableFilter start-up when 1 header row only 2018-02-13 14:15:35 +11:00
koalyptus 83ff0aab79
Merge pull request #566 from koalyptus/565-562-fixes
565 562 fixes
2018-02-11 17:06:31 +11:00
koalyptus 8dbc307a39 PR feedback (0) 2018-02-11 17:04:30 +11:00
koalyptus c7eefc8ddc show no results banner at start-up if no working rows #562 2018-02-10 22:12:16 +11:00
koalyptus 0e2d17714d fix unit tests 2018-02-10 21:29:36 +11:00
koalyptus 650959237b refactor setCheckListValues in CheckList class 2018-02-10 21:11:33 +11:00
koalyptus 4a10876a96 wip 2018-02-09 22:45:14 +11:00
koalyptus d5ef7afa1e
Merge pull request #563 from koalyptus/refactor-auto-filter-config
Refactor auto filter config
2018-02-04 22:13:33 +11:00
koalyptus 4cf9a4081d Merge branch 'master' into refactor-auto-filter-config 2018-02-04 22:02:58 +11:00
koalyptus c1e26349ef fix build (0) 2018-02-04 21:36:53 +11:00
koalyptus 16b2997a71
Merge pull request #564 from koalyptus/greenkeeper/eslint-4.17.0
Update eslint to the latest version 🚀
2018-02-03 19:01:13 +11:00
greenkeeper[bot] ab273644e5 chore(package): update eslint to version 4.17.0 2018-02-03 02:31:02 +00:00
koalyptus 731909a267 Remove provate members from auto-generated documentation 2018-02-02 22:34:17 +11:00
koalyptus 7f75e23b1b introduce isKeyPressed in event module 2018-02-02 22:26:28 +11:00
koalyptus 55eadd72eb wip 2018-01-29 23:20:52 +11:00
koalyptus 4855c9064b
Merge pull request #560 from koalyptus/558-filter-cells-with-html-elements
558 filter cells with html elements
2018-01-23 14:36:48 +11:00
koalyptus 032bdd53b0 remove commented out code 2018-01-23 14:18:18 +11:00
koalyptus f73aa02733 fix tests 2018-01-23 14:14:41 +11:00
koalyptus 029f2c35e8 wip 2018-01-21 22:38:22 +11:00
koalyptus 52a514088b
Merge pull request #559 from koalyptus/greenkeeper/eslint-4.16.0
Update eslint to the latest version 🚀
2018-01-21 14:03:46 +11:00
greenkeeper[bot] c7756d8d58 chore(package): update eslint to version 4.16.0 2018-01-20 04:30:35 +00:00
koalyptus 054423f10d
Merge pull request #557 from koalyptus/deprecate-grunt-esdoc
Remove grunt-esdoc, add grunt-shell pointing to esdoc npm command
2018-01-16 22:22:52 +11:00
koalyptus cccc4b71cf Remove grunt-esdoc, add grunt-shell pointing to esdoc npm command 2018-01-16 22:13:31 +11:00
koalyptus db2bb7de18
Merge pull request #555 from koalyptus/deprecate-grunt-eslint
Deprecate grunt eslint
2018-01-12 23:07:10 +11:00
koalyptus 740cce0551 bump babel-eslint version 2018-01-12 22:40:57 +11:00
koalyptus f6a93f7f00 remove grunt-eslint 2018-01-12 22:39:49 +11:00
koalyptus b6db436bca
Merge pull request #554 from koalyptus/greenkeeper/babel-eslint-8.2.0
Update babel-eslint to the latest version 🚀
2018-01-12 21:24:26 +11:00
greenkeeper[bot] 158c8835f9 chore(package): update babel-eslint to version 8.2.0 2018-01-08 23:20:26 +00:00
koalyptus 7a2bc50a56
Merge pull request #553 from koalyptus/545-state-persistence-type-precedence
545 state persistence type precedence
2018-01-08 21:50:56 +11:00
koalyptus 74cea36219 PR feedback 2018-01-08 21:38:55 +11:00
koalyptus 2deeb5d57a Fix multiple state type persistence at start-up 2018-01-07 22:48:35 +11:00
koalyptus 619c272469 Merge branch 'master' into 545-state-persistence-type-precedence 2018-01-07 20:36:48 +11:00
koalyptus 7862bc68d0
Merge pull request #552 from koalyptus/travis-s3-cloudfront
undo s3/cloudfront deployment travis config
2018-01-05 22:16:28 +11:00
koalyptus e2e8331a08 undo s3/cloudfront deployment travis config 2018-01-05 22:08:16 +11:00
koalyptus 3134ee804b
Merge pull request #551 from koalyptus/travis-s3-cloudfront
s3/cloudfront deployment travis config (1)
2018-01-05 16:56:33 +11:00
koalyptus 1c930a0184 s3/cloudfront deployment travis config (1) 2018-01-05 16:50:38 +11:00
koalyptus 51f188e63f
Merge pull request #550 from koalyptus/travis-s3-cloudfront
s3/cloudfront deployment travis config
2018-01-05 16:18:58 +11:00
koalyptus 2ca11374a0 s3/cloudfront deployment travis config 2018-01-05 16:06:08 +11:00
koalyptus 79367df924 build 2018-01-03 13:07:15 +11:00
koalyptus fe384896d5 wip 2017-12-27 23:13:44 +11:00
koalyptus f8c5d081d4
Merge pull request #549 from koalyptus/single-filter-columns
Single filter columns
2017-12-26 21:58:22 +11:00
koalyptus 3ff774d78f Move single filter css class definition in single_filter literal object 2017-12-26 21:25:28 +11:00
koalyptus 33ae62cab7 Merge branch 'master' into single-filter-columns 2017-12-26 20:46:08 +11:00
koalyptus 8be5990a02
Merge pull request #548 from koalyptus/greenkeeper/babel-eslint-8.1.2
Update babel-eslint to the latest version 🚀
2017-12-26 15:11:22 +11:00
greenkeeper[bot] 88d31090b4 chore(package): update babel-eslint to version 8.1.2 2017-12-26 02:17:18 +00:00
koalyptus fbfa2fdf96
Merge pull request #546 from koalyptus/greenkeeper/babel-eslint-8.1.0
Update babel-eslint to the latest version 🚀
2017-12-25 22:27:59 +11:00
koalyptus f447199905
Update package.json 2017-12-25 22:15:17 +11:00
koalyptus be67034e02
Update .eslintrc 2017-12-25 22:00:58 +11:00
greenkeeper[bot] a01c914f0a chore(package): update babel-eslint to version 8.1.0 2017-12-24 07:17:53 +00:00
koalyptus c288fe44ce
Update PULL_REQUEST_TEMPLATE.md 2017-12-17 22:50:01 +11:00
koalyptus dc05239d57
Merge pull request #544 from koalyptus/single-filter-columns
exclude columns from Single filter filtering
2017-12-17 22:21:45 +11:00
koalyptus 42fb561866 exclude columns from Single filter filtering 2017-12-17 22:02:56 +11:00
koalyptus 95c8206eb7
Create PULL_REQUEST_TEMPLATE.md 2017-12-16 13:41:38 +11:00
koalyptus 26beced5c7
Merge pull request #543 from koalyptus/539-persist-regex-url-hash
fix selectOptions on CheckList to use checkbox value instead of text
2017-12-10 21:56:17 +11:00
koalyptus cf7a53354d fix selectOptions on CheckList to use checkbox value instead of text 2017-12-10 21:31:41 +11:00
koalyptus 653b1ce006
Merge pull request #542 from koalyptus/refactor-reset-button-options
Refactor reset button options
2017-12-08 22:10:43 +11:00
koalyptus d69f60aced more unit tests 2017-12-08 21:38:28 +11:00
koalyptus 949f21f446 bumped version to 0.6.8 2017-12-07 22:51:21 +11:00
koalyptus 722c420dc6 prepare dist 2017-12-07 22:48:00 +11:00
koalyptus 590dd8316c resolve conflicts 2017-12-07 22:38:24 +11:00
koalyptus 376102c801 refactor reset button options under a structured literal object 2017-12-07 22:32:21 +11:00
koalyptus a243c96dd3
Merge pull request #541 from maciex/fix_hidden_rows_in_tests
Fix hidden rows in tests
2017-12-07 22:29:12 +11:00
Maciej Sitarz 631f6bdb5c Commit missing files from ./dist 2017-12-07 12:14:18 +01:00
Maciej Sitarz fc089f1b73 Clear filters so the page after tests shows all rows 2017-12-07 10:16:21 +01:00
Maciej Sitarz dfa93b378b Bump version to v.0.6.7 2017-12-07 10:01:28 +01:00
Maciej Sitarz 0affe2c187 Rebuild and update ./dist 2017-12-06 22:08:58 +01:00
Maciej Sitarz 8231252f34 Merge branch 'fix_regex_with_stars' 2017-12-06 22:05:51 +01:00
Maciej Sitarz 75faca6e8d First search for rgx: then for other operators 2017-12-06 21:51:36 +01:00
Maciej Sitarz 4a6ae393a5 Add tests for regex with start(*) and plus(+) 2017-12-06 21:50:50 +01:00
koalyptus 0e669bcc45
Merge pull request #538 from koalyptus/filter-font-size
enforce styling for label element in checklist filter
2017-12-05 13:56:20 +11:00
koalyptus 08fb37b982 enforce styling for label element in checklist filter 2017-12-05 12:55:45 +11:00
koalyptus bde954e570
Merge pull request #536 from koalyptus/filter-font-size
harmonise font-size across filter types
2017-12-04 22:30:47 +11:00
koalyptus 78f6df704b harmonise font-size across filter types 2017-12-04 22:15:09 +11:00
koalyptus 7cf9be1342
Merge pull request #535 from koalyptus/rows-iterator
Rows iterator
2017-12-03 22:07:15 +11:00
koalyptus 86a650ff6d tidy-up code (2) 2017-12-03 21:57:07 +11:00
koalyptus 13adb6fb3a Merge branch 'master' into rows-iterator 2017-12-03 21:48:35 +11:00
koalyptus f2d54839c3 tidy-up code 2017-12-03 21:48:00 +11:00
koalyptus 9abc9802bd
Merge pull request #534 from koalyptus/greenkeeper/babel-eslint-8.0.3
Update babel-eslint to the latest version 🚀
2017-12-02 20:30:09 +11:00
greenkeeper[bot] 82a03d428c chore(package): update babel-eslint to version 8.0.3 2017-12-01 18:20:55 +00:00
koalyptus 0b5160b45d fix merge conflicts 2017-12-01 21:49:08 +11:00
koalyptus fca1fcf23c
Merge pull request #533 from koalyptus/531-popup-filters-1-row
531 popup filters 1 row
2017-11-30 14:43:22 +11:00
koalyptus e311aa36f1 Add missing files to git 2017-11-30 14:36:03 +11:00
koalyptus 9b54c10bc6 tidy-up code 2017-11-30 14:00:10 +11:00
koalyptus eb62703e50 remove commented out code 2017-11-30 13:57:11 +11:00
koalyptus 81062452e2 wip 2017-11-27 19:34:24 +11:00
koalyptus 6e72912c90 add missing files to git 2017-11-26 17:56:24 +11:00
koalyptus 52999f000e loops refactor (1) 2017-11-26 17:51:13 +11:00
koalyptus 6999b0c7f9 Continue loops refactor 2017-11-11 21:42:49 +11:00
koalyptus e205a6b15a wip 2017-11-10 22:29:37 +11:00
koalyptus fbeb52bda2
Merge pull request #528 from koalyptus/greenkeeper/babel-eslint-8.0.2
Update babel-eslint to the latest version 🚀
2017-11-07 09:27:33 +11:00
greenkeeper[bot] 465b216e01 chore(package): update babel-eslint to version 8.0.2 2017-11-06 20:32:00 +00:00
koalyptus ff622ea585
Merge pull request #525 from koalyptus/highlight-active-column
Highlight active column
2017-11-01 22:44:08 +11:00
koalyptus 6a0179681b unit tests 2017-11-01 22:11:24 +11:00
koalyptus 68adc86cbc highlight each cell of an active column 2017-10-29 21:36:15 +11:00
koalyptus e661005ff8 Add eachCol iterator 2017-10-28 22:33:12 +11:00
koalyptus a861cff760
Merge pull request #523 from koalyptus/519-tbody-working-rows
519 tbody working rows
2017-10-28 16:18:59 +11:00
koalyptus 12e4052a9f more unit tests 2017-10-28 16:06:36 +11:00
koalyptus e9441fe1d5 Add empty content css mixin for empty containers in toolbar 2017-10-27 23:00:10 +11:00
koalyptus 175a23934f Merge pull request #522 from koalyptus/519-tbody-working-rows
519 tbody working rows
2017-10-26 14:08:20 +11:00
koalyptus a757bd02fa more unit tests 2017-10-26 13:35:55 +11:00
koalyptus b03ec21a28 unit tests 2017-10-25 22:23:43 +11:00
koalyptus 5f66df7e6a Use tbody for working rows 2017-10-25 17:05:39 +11:00
koalyptus 5a10841f84 Merge branch 'master' into 519-tbody-working-rows 2017-10-24 21:30:56 +11:00
koalyptus 2ef37ed58d Merge pull request #521 from koalyptus/greenkeeper/codecov-3.0.0
Update codecov to the latest version 🚀
2017-10-23 21:49:35 +11:00
greenkeeper[bot] 828a42f938 chore(package): update codecov to version 3.0.0 2017-10-23 06:37:41 +00:00
koalyptus 4428f7b48b Renamed always_visible_rows option exlucde_rows 2017-10-22 20:57:01 +11:00
koalyptus e855fc5bbd Rename visibleRows excludeRows 2017-10-20 23:33:18 +11:00
koalyptus a7f0f442d8 Merge pull request #518 from koalyptus/greenkeeper/codecov-2.3.1
Update codecov to the latest version 🚀
2017-10-15 07:51:22 +11:00
greenkeeper[bot] 2a424e7f6f chore(package): update codecov to version 2.3.1 2017-10-14 14:05:27 +00:00
koalyptus 50f537fbfc Merge pull request #516 from koalyptus/toolbar-refactor
Toolbar refactor
2017-10-10 13:10:55 +11:00
koalyptus 7ba78c94ae Reach doc threshold 2017-10-09 22:15:08 +11:00
koalyptus 763fbcc86e unit tests 2017-10-09 21:56:58 +11:00
koalyptus 3abca0ef22 wip (3) 2017-10-08 21:56:12 +11:00
koalyptus 7888a8ee24 wip (3) 2017-10-08 21:14:25 +11:00
koalyptus abec798b27 wip (2) 2017-10-06 14:07:55 +11:00
koalyptus eb9ac51b5a wip 2017-10-02 22:15:35 +11:00
koalyptus d86601e1a1 Merge branch '507-fix-col-widths-col-visibility-ext' into toolbar-refactor 2017-10-02 21:16:10 +11:00
koalyptus fd48f8c3ec Merge pull request #514 from koalyptus/greenkeeper/babel-eslint-8.0.1
Update babel-eslint to the latest version 🚀
2017-09-27 19:58:34 +10:00
greenkeeper[bot] fa28d6ce17 chore(package): update babel-eslint to version 8.0.1 2017-09-26 21:11:23 +00:00
koalyptus 4250fda098 Merge pull request #513 from koalyptus/507-fix-col-widths-col-visibility-ext
Fix + unit tests
2017-09-23 21:47:35 +10:00
koalyptus 4f9e3dee01 Fix + unit tests 2017-09-23 21:34:09 +10:00
koalyptus e05f0b2c73 Merge pull request #510 from koalyptus/greenkeeper/babel-eslint-8.0.0
Update babel-eslint to the latest version 🚀
2017-09-13 09:45:00 +10:00
greenkeeper[bot] 7c7a5fc1b7 chore(package): update babel-eslint to version 8.0.0 2017-09-12 14:18:29 +00:00
koalyptus a54abc6ea1 Merge pull request #508 from koalyptus/506-linked-filters-paging-fix
Fix link filters with paging on
2017-09-08 18:09:08 +10:00
koalyptus e4ed4d5567 Unit tests 2017-09-08 18:00:03 +10:00
koalyptus 29c4c107bc refactor linked filters logic to filter out values for drop-down and checklist filter 2017-09-07 14:21:40 +10:00
koalyptus 0b242aadc7 Fix link filters with paging on 2017-09-05 22:34:06 +10:00
koalyptus 44a39e7e1f Merge pull request #505 from koalyptus/greenkeeper/grunt-eslint-20.1.0
Update grunt-eslint to the latest version 🚀
2017-09-01 23:39:53 +10:00
greenkeeper[bot] e82640c7da chore(package): update grunt-eslint to version 20.1.0 2017-08-31 04:08:18 +00:00
koalyptus f89bf8859b Merge pull request #504 from koalyptus/style-issue-columns-list
Made ColsVisibility container inherit font-size, expand linked filters unit tests
2017-08-27 11:16:03 +10:00
koalyptus 6b5c432ce7 Made ColsVisibility container inherit font-size, expand linked filters unit tests 2017-08-27 10:54:05 +10:00
koalyptus 409a3bc6eb Merge pull request #501 from koalyptus/style-issue-columns-list
Style issue columns list
2017-08-12 22:46:28 +10:00
koalyptus d406a09a9e more css tweaks for edge 2017-08-12 22:30:41 +10:00
koalyptus 36b045c6d2 other css definition tweak for edge 2017-08-10 15:57:51 +10:00
koalyptus 59902adcf5 Merge pull request #500 from koalyptus/style-issue-columns-list
list-style-type instead of list-style
2017-08-10 14:04:02 +10:00
koalyptus 41842eede4 list-style-type instead of list-style 2017-08-10 13:48:59 +10:00
koalyptus 62c7cb1918 Merge pull request #499 from koalyptus/increase-coverage
refactor _buildSubmitButton in TableFilter
2017-08-09 14:43:55 +10:00
koalyptus d23f6f4cc8 refactor _buildSubmitButton in TableFilter 2017-08-09 14:18:52 +10:00
koalyptus 80f1fc3371 Merge pull request #498 from koalyptus/greenkeeper/grunt-babel-7.0.0
Update grunt-babel to the latest version 🚀
2017-08-09 13:36:19 +10:00
greenkeeper[bot] ea87137a82 chore(package): update grunt-babel to version 7.0.0 2017-08-08 23:35:45 +00:00
koalyptus aa8df36e28 Merge pull request #497 from koalyptus/greenkeeper/codecov-2.3.0
Update codecov to the latest version 🚀
2017-08-04 10:43:31 +10:00
greenkeeper[bot] 0947a87d6c chore(package): update codecov to version 2.3.0 2017-08-03 13:46:49 +00:00
koalyptus 72c47a9b0d Merge pull request #495 from koalyptus/494-formatted-number-no-decimal
Refine cell value coercion to number in filtering logic
2017-08-02 14:36:26 +10:00
koalyptus f0c9a800a5 Refine cell value coercion to number in filtering logic 2017-08-02 13:58:44 +10:00
koalyptus ad5405e699 Merge pull request #493 from koalyptus/358-increase-coverage
358 increase coverage
2017-07-30 21:49:21 +10:00
koalyptus cc5c8b9ed5 Increased TableFilter coverage 2017-07-30 21:39:23 +10:00
koalyptus 04d8fd3d14 Merge branch 'master' into 358-increase-coverage 2017-07-30 11:03:29 +10:00
koalyptus fb0a6a0a01 Merge pull request #492 from koalyptus/490-grid-layout-no-results
Keep scrollbar when grid-layout on and no-results-message
2017-07-29 11:17:10 +10:00
koalyptus 78059d1bf8 Keep scrollbar when grid-layout on and no-results-message 2017-07-29 11:08:13 +10:00
koalyptus 3352765fed Merge pull request #489 from koalyptus/487-fix-state-empty-table
Fix setFilterValue with inexistent filter element
2017-07-26 11:41:21 +10:00
koalyptus f96166be48 Fix setFilterValue with inexistent filter element 2017-07-26 11:30:36 +10:00
koalyptus 3a878c9e90 Merge pull request #488 from koalyptus/485-popup_filter-filters_row_index
Override filters row index setting when popup filters on
2017-07-25 22:51:57 +10:00
koalyptus 7b8c3c7412 Removed unnecessary setting for popup filter tests 2017-07-25 22:24:46 +10:00
koalyptus 9f6751533e Override filters row index setting when popup filters on 2017-07-25 22:22:32 +10:00
koalyptus 82e9b27598 Fix esdoc badge 2017-07-20 16:24:03 +10:00
koalyptus 237fff1351 Merge pull request #483 from koalyptus/481-getcolvalues-optimisation
Revert gh-pages publish-lib unfortunate change
2017-07-20 16:05:33 +10:00
koalyptus e00c560c80 Revert gh-pages publish-lib unfortunate change 2017-07-20 16:04:09 +10:00
koalyptus 407e772fdb Merge pull request #482 from koalyptus/481-getcolvalues-optimisation
getColValues optimisation from @rimace
2017-07-20 15:24:19 +10:00
koalyptus 645437b5e3 getColValues optimisation from @rimace 2017-07-20 13:39:43 +10:00
koalyptus 7f6221cd8e Merge pull request #480 from koalyptus/remove-external_flt_grid-option
Remove external flt grid option
2017-07-16 12:02:53 +10:00
koalyptus d9c770855a Fixed popup filter extra row issue 2017-07-16 11:55:54 +10:00
koalyptus 70a7d6540c Fixing popup filters extra row visibility 2017-07-16 11:27:23 +10:00
koalyptus acf6678619 Merge pull request #479 from koalyptus/remove-external_flt_grid-option
Removed external_flt_grid_option setting, make paths properties functions
2017-07-16 11:07:48 +10:00
koalyptus f2242c4e57 Removed external_flt_grid_option setting, make paths properties functions 2017-07-16 10:52:40 +10:00
koalyptus 8fb7c76e2d Merge pull request #477 from koalyptus/config-settings-helpers
Config settings helpers
2017-07-09 16:02:39 +10:00
koalyptus 72e78fd4bc Introduced settings helpers 2017-07-09 15:11:51 +10:00
koalyptus 2f1e065571 Remove hasExtensions and hasColWidths properties on TableFilter 2017-07-08 10:53:19 +10:00
koalyptus 761c3730ed Merge pull request #475 from koalyptus/refactor-features-instanciation
Refactor features instanciation
2017-07-03 13:28:31 +10:00
koalyptus cdf7b926ba Allowing features instantiation without configuration 2017-07-02 21:53:40 +10:00
koalyptus d3addb09c4 Placed features instantiation inside init method 2017-07-01 21:41:49 +10:00
koalyptus 471203b0a6 Merge branch 'master' into refactor-features-instanciation 2017-07-01 20:37:14 +10:00
koalyptus 7cac5b105e Merge pull request #474 from koalyptus/460-unit-test
Unit tests for popup-filters with grouped headers
2017-06-30 22:22:12 +10:00
koalyptus e8c3f27d93 Commented out test failing on build... 2017-06-30 22:12:31 +10:00
koalyptus 97d2ed0d64 Fixed linting 2017-06-30 22:00:40 +10:00
koalyptus 7278aab649 Unit tests for popup-filters with grouped headers 2017-06-30 21:54:50 +10:00
koalyptus e33e634d0d Merge pull request #473 from koalyptus/greenkeeper/format-number-3.0.0
Update format-number to the latest version 🚀
2017-06-30 13:30:04 +10:00
greenkeeper[bot] 92af5d8842 chore(package): update format-number to version 3.0.0 2017-06-29 11:40:10 +00:00
koalyptus 140f949190 Merge pull request #472 from koalyptus/greenkeeper/initial
Update dependencies to enable Greenkeeper 🌴
2017-06-28 21:04:09 +10:00
koalyptus c5d043f85b Fixed linting errors due to version bump of grunt-eslint 2017-06-28 20:47:32 +10:00
greenkeeper[bot] 06cea02484 docs(readme): add Greenkeeper badge 2017-06-27 12:01:05 +00:00
greenkeeper[bot] 287b7413e3 chore(travis): whitelist greenkeeper branches 2017-06-27 12:01:02 +00:00
greenkeeper[bot] 3c330ac4f0 chore(package): update dependencies 2017-06-27 12:00:59 +00:00
koalyptus 51bc126c8d Merge pull request #471 from koalyptus/465-cols-visibility-callbacks-grid-layout
More defensive with tableLayout
2017-06-27 15:39:26 +10:00
koalyptus edcd166cd8 More defensive with tableLayout 2017-06-27 15:28:16 +10:00
koalyptus aaead0e5ca Merge pull request #470 from koalyptus/465-cols-visibility-callbacks-grid-layout
465 cols visibility callbacks grid layout
2017-06-27 13:59:56 +10:00
koalyptus 990ef45e45 Removed commented out code 2017-06-27 13:42:02 +10:00
koalyptus 9ae607d802 Re-instating colsVisibility callbacks when grid-layout on + deleting code 2017-06-27 13:38:53 +10:00
Max Guglielmi 3c07d8dcc4 Started fixing col widths undex firefox 2017-06-25 21:51:15 +10:00
koalyptus bb8b8a9d50 Merge pull request #469 from koalyptus/466-grid-layout-misalignment
Removed headers table container width when is grid-layout on
2017-06-24 21:10:45 +10:00
Max Guglielmi 08303e93ca Removed headers table container width when is grid-layout on 2017-06-24 20:54:49 +10:00
koalyptus 01bdad6368 Merge pull request #468 from koalyptus/466-grid-layout-misalignment
Modified grd_headTblCont css definitions to account scrollbar width
2017-06-23 17:11:36 +10:00
Max Guglielmi 8145ef116f Modified grd_headTblCont css definitions to account scrollbar width 2017-06-23 17:01:13 +10:00
koalyptus ab9ff96684 Merge pull request #464 from koalyptus/refactor-paging-options
Refactor paging options
2017-06-15 13:43:50 +10:00
Max Guglielmi 9858ac84c1 Fixed unit tests 2017-06-14 22:12:44 +10:00
Max Guglielmi c6b876d7f9 Initial commit 2017-06-14 13:59:04 +10:00
koalyptus 05f1c62ad0 Merge pull request #463 from koalyptus/refactor-grid-layout-options
Refactor grid layout options
2017-06-04 20:34:04 +10:00
Max Guglielmi bf631efd24 Modified an option name (2) 2017-06-04 18:22:20 +10:00
Max Guglielmi f86e73b374 Modified an option name 2017-06-03 19:57:24 +10:00
Max Guglielmi 7cd85bbd34 Fixed unit tests 2017-06-03 19:45:20 +10:00
Max Guglielmi 38424bfdca Started refactoring configuration options 2017-06-02 14:01:10 +10:00
koalyptus 9dde61e7a0 Merge pull request #462 from koalyptus/refactor-popup-filters-options
Refactor popup filters options
2017-05-31 20:55:06 +10:00
Max Guglielmi 5fc1c78d1b Expanded unit tests 2017-05-31 13:46:23 +10:00
Max Guglielmi 2cbfc0b1ec Bumped webapack version 2017-05-29 13:34:47 +10:00
Max Guglielmi 5043378c2c Refactor popup-filters options 2017-05-29 13:31:45 +10:00
Max Guglielmi 92e743a67e Merge branch 'master' into refactor-popup-filters-options 2017-05-27 22:42:03 +10:00
koalyptus 9262e7fd13 Merge pull request #461 from koalyptus/460-fix-popup-filters
Fixed tf reference in closeAll and destroy
2017-05-27 22:22:53 +10:00
Max Guglielmi 5adfa8a1be Fixed tf reference in closeAll and destroy 2017-05-27 22:15:06 +10:00
Max Guglielmi 0d64d5aa00 Bumped version 2017-05-27 21:39:25 +10:00
Max Guglielmi 11e15f0482 Enforcing eslint rule 2017-05-25 13:51:44 +10:00
koalyptus 07355d7442 Merge pull request #459 from koalyptus/refactor-help-instructions
Refactor help-instructions configuration option
2017-05-24 13:03:35 +10:00
Max Guglielmi e8392b8fa5 Refactor help-instructions configuration option 2017-05-23 13:49:21 +10:00
koalyptus bfcf221a91 Merge pull request #458 from koalyptus/refactor-loader-options
Refactor loader configuration options
2017-05-18 20:14:11 +10:00
Max Guglielmi c29cbda581 Refactor loader configuration options 2017-05-18 13:49:11 +10:00
koalyptus 5294a31e30 Merge pull request #457 from koalyptus/refactor-status-bar-options
Refactor status-bar config
2017-05-17 13:30:03 +10:00
Max Guglielmi ed7ead95d5 Removed commented out code from pagination demo 2017-05-17 13:16:57 +10:00
Max Guglielmi aee6063410 Refactor status-bar config 2017-05-16 13:55:48 +10:00
koalyptus 45e78777e9 Merge pull request #456 from koalyptus/refactor-features-instanciation
Refactor features instanciation
2017-05-13 21:12:19 +10:00
Max Guglielmi 1de6a6288c updated unit tests 2017-05-13 20:51:10 +10:00
Max Guglielmi 4b7af32eb1 Updated README 2017-05-13 11:09:21 +10:00
Max Guglielmi 955c49a2c1 Merge branch 'master' into refactor-features-instanciation 2017-05-13 10:22:00 +10:00
koalyptus eeb5afe97b Merge pull request #453 from koalyptus/greenkeeper-codecov-2.2.0
Update codecov to version 2.2.0 🚀
2017-05-10 16:10:34 +10:00
greenkeeperio-bot f5d818c91a chore(package): update codecov to version 2.2.0
https://greenkeeper.io/
2017-05-10 11:23:48 +10:00
koalyptus 0a38e422b8 Merge pull request #450 from koalyptus/greenkeeper-grunt-webpack-3.0.0
Update grunt-webpack to version 3.0.0 🚀
2017-05-09 21:03:53 +10:00
Max Guglielmi f059faecbc Added missing starter.html 2017-05-09 20:53:25 +10:00
Max Guglielmi 195918f088 Dist build 2017-05-09 20:47:05 +10:00
Max Guglielmi 022e52e31c Exploring babel settings issues 2017-05-09 14:31:29 +10:00
Max Guglielmi b249399b1d Merge branch 'master' into greenkeeper-grunt-webpack-3.0.0 2017-05-09 13:08:56 +10:00
koalyptus 132d46fed5 Merge pull request #452 from koalyptus/greenkeeper-webpack-2.5.1
chore(package): update webpack to version 2.5.1
2017-05-07 19:43:34 +10:00
koalyptus 49e16a3631 Merge pull request #451 from koalyptus/284-sort-filter-options
284 sort filter options
2017-05-07 16:47:58 +10:00
Max Guglielmi 06c3b3f025 Added base class for drop-down filter types 2017-05-07 16:05:36 +10:00
greenkeeperio-bot 39e4340dee chore(package): update webpack to version 2.5.1
https://greenkeeper.io/
2017-05-07 06:12:58 +10:00
Max Guglielmi cb3a633807 Fixed tests 2017-05-07 00:35:24 +10:00
Max Guglielmi b0bc11007f Refactor logic for sorting drop-down filter options 2017-05-06 21:32:01 +10:00
greenkeeperio-bot 7781bcfe4b chore(package): update grunt-webpack to version 3.0.0
https://greenkeeper.io/
2017-05-05 23:57:18 +10:00
koalyptus 308ea2ce25 Merge pull request #449 from koalyptus/greenkeeper-webpack-2.5.0
chore(package): update webpack to version 2.5.0
2017-05-04 20:42:30 +10:00
greenkeeperio-bot d66c7906c0 chore(package): update webpack to version 2.5.0
https://greenkeeper.io/
2017-05-04 20:22:41 +10:00
koalyptus a0bf340378 Merge pull request #448 from koalyptus/rows-counter-options-refactor
Rows counter options refactor
2017-05-03 21:48:54 +10:00
Max Guglielmi 1b8bb8a9ea Added registerExtension method 2017-05-03 21:27:44 +10:00
Max Guglielmi 25101b278a Refactored options and updated unit tests 2017-05-02 22:31:02 +10:00
koalyptus 5c4c8c0fe9 Merge pull request #446 from koalyptus/refactor-features-instanciation
Refactor features instanciation
2017-05-01 22:13:16 +10:00
Max Guglielmi 7a861eabee Added missing starter file in dist folder 2017-05-01 22:10:57 +10:00
Max Guglielmi b8f549a432 Added missing doco 2017-05-01 22:04:01 +10:00
koalyptus 5a82498d60 Merge pull request #445 from koalyptus/refactor-features-instanciation
Refactor features instanciation
2017-05-01 21:59:57 +10:00
Max Guglielmi 890d004c3c Regrouped FEATURES destructuring 2017-05-01 21:45:17 +10:00
Max Guglielmi c7c20cdacf Removed commented out code 2017-05-01 21:41:24 +10:00
Max Guglielmi 3f2bc41176 Moved features definitions in const file 2017-05-01 21:36:51 +10:00
Max Guglielmi 70779f192c Started refactoring features instn 2017-05-01 09:36:47 +10:00
koalyptus 6fc121a314 Merge pull request #442 from koalyptus/440-popup-filters-horizontal-scroll
Made popup filters element anchored to container
2017-04-26 07:44:49 +10:00
Max Guglielmi 29960cada8 Made popup filters element anchored to container 2017-04-26 07:29:08 +10:00
koalyptus 6dc1c9e53b Merge pull request #441 from koalyptus/greenkeeper-webpack-dev-server-2.4.4
chore(package): update webpack-dev-server to version 2.4.4
2017-04-25 19:47:52 +10:00
greenkeeperio-bot 5b7b1527d5 chore(package): update webpack-dev-server to version 2.4.4
https://greenkeeper.io/
2017-04-23 21:38:27 +10:00
Max Guglielmi 6bfccca291 Added missing doc comment for MarkActiveColumns class 2017-04-23 18:50:35 +10:00
koalyptus 39c8933a3f Merge pull request #439 from koalyptus/modulerise-mark-active-columns
Modulerise mark active columns
2017-04-23 18:30:33 +10:00
Max Guglielmi 5411843f9f Expanded unit tests 2017-04-23 18:22:34 +10:00
Max Guglielmi 88b0dc5215 Added final new line 2017-04-23 05:43:06 +10:00
Max Guglielmi 2a8571d940 Production build 2017-04-23 05:34:54 +10:00
Max Guglielmi 9882a99417 Merge branch 'master' into modulerise-mark-active-columns 2017-04-23 05:18:18 +10:00
Max Guglielmi 2f8fb874d8 Unit tests for mark active columns feature 2017-04-23 05:17:42 +10:00
koalyptus 5f229311f0 Merge pull request #438 from koalyptus/greenkeeper-babel-eslint-7.2.3
Update babel-eslint to version 7.2.3 🚀
2017-04-22 17:15:04 +10:00
greenkeeperio-bot 4a88f6cc56 chore(package): update babel-eslint to version 7.2.3
https://greenkeeper.io/
2017-04-22 17:02:39 +10:00
koalyptus 151ec256fa Merge pull request #437 from koalyptus/greenkeeper-babel-loader-7.0.0
Update babel-loader to version 7.0.0 🚀
2017-04-22 17:02:23 +10:00
Max Guglielmi 37c90ed12b Started modulerising mark active columns feature 2017-04-22 06:22:50 +10:00
greenkeeperio-bot c21863c71a chore(package): update babel-loader to version 7.0.0
https://greenkeeper.io/
2017-04-22 06:18:20 +10:00
Max Guglielmi 508fc8fd1c Merge branch 'master' of https://github.com/koalyptus/TableFilter 2017-04-18 03:01:16 +10:00
Max Guglielmi 9f6b3160fc Added missing extensions bundle in dist folder 2017-04-18 03:00:10 +10:00
koalyptus 650de1d7e3 add links to cotributing in readme 2017-04-16 19:38:10 +10:00
koalyptus 68ebfcd537 Merge pull request #436 from koalyptus/greenkeeper-webpack-2.4.1
chore(package): update webpack to version 2.4.1
2017-04-15 17:01:31 +10:00
koalyptus 4cc870b1bb Merge pull request #435 from koalyptus/greenkeeper-grunt-contrib-clean-1.1.0
chore(package): update grunt-contrib-clean to version 1.1.0
2017-04-15 16:55:01 +10:00
greenkeeperio-bot a15fb5719e chore(package): update webpack to version 2.4.1
https://greenkeeper.io/
2017-04-14 23:53:13 +10:00
koalyptus 6926ef3b9a Merge pull request #434 from koalyptus/dom-method
Added dom method, made tbl property private
2017-04-14 19:52:43 +10:00
Max Guglielmi 76a61d5a01 Added dom method, made tbl property private 2017-04-14 19:30:58 +10:00
greenkeeperio-bot f24c5da431 chore(package): update grunt-contrib-clean to version 1.1.0
https://greenkeeper.io/
2017-04-13 10:42:17 +10:00
koalyptus b9ab9582a8 Merge pull request #433 from koalyptus/greenkeeper-babel-eslint-7.2.2
Update babel-eslint to version 7.2.2 🚀
2017-04-13 05:40:26 +10:00
greenkeeperio-bot f9426c9ed0 chore(package): update babel-eslint to version 7.2.2
https://greenkeeper.io/
2017-04-13 02:12:02 +10:00
koalyptus 067cce1d7b Merge pull request #431 from koalyptus/358-increase-coverage
358 increase coverage
2017-04-11 02:39:12 +10:00
Max Guglielmi b03445ea46 Expanded StatusBar tests 2017-04-11 02:33:27 +10:00
Max Guglielmi 9d7f49dda9 Bumped packages versions 2017-04-11 00:56:40 +10:00
Max Guglielmi dfd78be5b3 Merge branch 'master' into 358-increase-coverage 2017-04-11 00:53:14 +10:00
koalyptus f0e2ec6a8a Merge pull request #429 from koalyptus/simplify-get-data-apis
Simplify get data apis
2017-04-02 10:49:03 +10:00
Max Guglielmi 06ed30de3b Added getColumnData and getColumnValues 2017-04-02 00:54:19 +11:00
Max Guglielmi 5cfc6c573b Uncommented code 2017-03-31 15:01:13 +11:00
Max Guglielmi ec940d428a Updated unit tests 2017-03-31 14:56:51 +11:00
Max Guglielmi 4f593cb2d3 Started fixing unit tests 2017-03-30 23:14:27 +11:00
Max Guglielmi 611fc1ba24 Continued simplyfing data retrieval APIs 2017-03-29 21:42:31 +11:00
Max Guglielmi 4f7249bfa4 Started simplying data retrieval APIs 2017-03-26 20:42:51 +11:00
koalyptus 8f8e468278 Merge pull request #425 from koalyptus/424-page-length-persistence-issue
Fixed set page length when no valid rows + added unit tests
2017-03-25 15:31:44 +11:00
Max Guglielmi 23916b753a Reverted changes to grouped headers demo 2017-03-25 15:21:32 +11:00
Max Guglielmi e8ba629217 Fixed set page length when no valid rows + added unit tests 2017-03-25 15:19:12 +11:00
koalyptus ef2c2917db Merge pull request #423 from koalyptus/greenkeeper-babel-eslint-7.2.1
Update babel-eslint to version 7.2.1 🚀
2017-03-24 07:40:32 +11:00
greenkeeperio-bot 6daed0f4a8 chore(package): update babel-eslint to version 7.2.1
https://greenkeeper.io/
2017-03-24 05:11:14 +11:00
koalyptus 8624920e2c Merge pull request #422 from koalyptus/greenkeeper-babel-eslint-7.2.0
Update babel-eslint to version 7.2.0 🚀
2017-03-21 10:06:24 +11:00
greenkeeperio-bot e303cccd2a chore(package): update babel-eslint to version 7.2.0
https://greenkeeper.io/
2017-03-21 09:07:42 +11:00
koalyptus 88c4f2d8d0 Merge pull request #421 from koalyptus/greenkeeper-codecov-2.1.0
Update codecov to version 2.1.0 🚀
2017-03-19 12:02:59 +11:00
greenkeeperio-bot 41feee7a22 chore(package): update codecov to version 2.1.0
https://greenkeeper.io/
2017-03-18 22:54:09 +11:00
koalyptus c0101f45b5 Merge pull request #420 from koalyptus/413-col-ops-result-formatting
Added results formatting to ColOps
2017-03-18 12:54:50 +11:00
Max Guglielmi c49eb2e50f Added results formatting to ColOps 2017-03-18 10:20:51 +11:00
koalyptus 238af84a97 Merge pull request #419 from koalyptus/greenkeeper-codecov-2.0.2
Update codecov to version 2.0.2 🚀
2017-03-17 09:34:35 +11:00
greenkeeperio-bot 87d166c4a4 chore(package): update codecov to version 2.0.2
https://greenkeeper.io/
2017-03-16 19:48:07 +11:00
koalyptus d05a3c4dc0 Merge pull request #418 from koalyptus/358-increase-coverage
358 increase coverage
2017-03-16 15:21:36 +11:00
Max Guglielmi a2ccc2668a Added test case for disabled enter key 2017-03-16 15:05:56 +11:00
Max Guglielmi e93df29cc0 Merge branch 'master' into 358-increase-coverage 2017-03-16 13:32:07 +11:00
koalyptus aafe5da783 Merge pull request #417 from koalyptus/greenkeeper-codecov-2.0.1
Update codecov to version 2.0.1 🚀
2017-03-15 13:29:48 +11:00
greenkeeperio-bot 35174fb849 chore(package): update codecov to version 2.0.1
https://greenkeeper.io/
2017-03-15 09:57:32 +11:00
koalyptus 1905d89a75 Merge pull request #416 from koalyptus/greenkeeper-babel-core-6.24.0
chore(package): update babel-core to version 6.24.0
2017-03-14 13:46:31 +11:00
greenkeeperio-bot d566d6a315 chore(package): update babel-core to version 6.24.0
https://greenkeeper.io/
2017-03-13 14:14:10 +11:00
koalyptus 08529d0d59 Correct pull requests section 2017-03-10 19:15:12 +11:00
koalyptus ce946b9aed Merge pull request #411 from koalyptus/358-increase-coverage
358 increase coverage
2017-03-01 22:18:32 +11:00
Max Guglielmi f7aa5cd65c Expanded statusBar tests 2017-03-01 22:09:20 +11:00
Max Guglielmi d9c0fd6d0b Merge branch 'master' into 358-increase-coverage 2017-03-01 21:12:31 +11:00
koalyptus 41db8d67df Merge pull request #409 from koalyptus/cell-parser
Cell parser
2017-02-27 13:57:20 +11:00
Max Guglielmi 7a5985ba8f Added test case 2017-02-27 13:38:19 +11:00
Max Guglielmi 574e2c3761 Removed commented out code 2017-02-26 21:45:41 +11:00
Max Guglielmi 90b5e3cdca Renamed custom_cell_data option cell_parser 2017-02-26 21:43:36 +11:00
koalyptus b062d44b87 Merge pull request #406 from koalyptus/refresh-deps-versions
Bumped various packages versions
2017-02-21 22:18:52 +11:00
Max Guglielmi ca1c801d64 Bumped various packages versions 2017-02-21 21:25:08 +11:00
koalyptus c3a6c61739 Merge pull request #405 from koalyptus/404-fix-destroy-extensions
Fixed destroyExtensions
2017-02-13 15:11:31 +11:00
Max Guglielmi 5a496f228a Fixed destroyExtensions 2017-02-13 14:52:47 +11:00
167 changed files with 20774 additions and 3757 deletions

14
.esdoc.json Normal file
View file

@ -0,0 +1,14 @@
{
"source": "src",
"destination": "docs/docs",
"plugins": [{
"name": "esdoc-standard-plugin",
"option": {
"lint": {"enable": false},
"accessor": {
"access": ["public", "protected"],
"autoPrivate": true
}
}
}]
}

View file

@ -1,18 +1,20 @@
{
"parser": "babel-eslint",
"parserOptions": {
"sourceType": "module"
"sourceType": "module",
"ecmaFeatures": { "modules": true }
},
"rules": {
"max-len": [2, 80, 2, {"ignoreUrls": true}],
"indent": [2, 4, {"SwitchCase": 1}],
"semi": ["error", "always"],
"no-trailing-spaces": 2,
"no-multi-spaces": 2,
"array-bracket-spacing": 2,
"keyword-spacing": ["error", { "after": true, "before": true }],
"max-depth": [2, 7],
"max-statements": [2, 144],
"complexity": [2, 78],
"max-statements": [2, 133],
"complexity": [2, 45],
"no-unused-vars": 2,
"no-eval": 2,
"no-underscore-dangle": 0,
@ -24,9 +26,6 @@
"new-cap": 2,
"radix": [2, "always"]
},
"ecmaFeatures": {
"modules": true
},
"env": {
"es6": true,
"browser": true,

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**Reproduction steps:**
Steps to reproduce the behavior:
1. [First Step]
2. [Second Step]
3. [Other Steps...]
**Expected behavior**
A clear and concise description of what you expected to happen.
**Observed behavior:**
A clear and concise description of observed behavior.
**Screenshots**
If applicable, add screenshots to help explain your problem.
![Screenshots and GIFs which follow reproduction steps to demonstrate the problem](url)
**TableFilter version:** [Enter TableFilter version here]
**Browser and version:** [Enter Browser name and version here]
**OS and version:** [Enter OS name and version here]
**Device:** [e.g. iPhone6]
**Additional information/context:**
Add any other context about the problem here.
* Problem started happening recently, didn't happen in an older version of TableFilter: [Yes/No] if yes [version here]
* Problem can be reliably reproduced, doesn't happen randomly: [Yes/No]

View file

@ -0,0 +1,36 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Enhancement/feature description**
[A clear and concise description of what the problem is. Ex. I'm always frustrated when ...]
**Steps which explain the enhancement/feature**
1. [First Step]
2. [Second Step]
3. [Other Steps...]
**Current and suggested behavior**
[Describe current and suggested behavior here]
**Why would the enhancement be useful to most users**
[Explain why the enhancement would be useful to most users]
**Screenshots and GIFs**
![Screenshots and GIFs which demonstrate the steps or part of TableFilter the enhancement suggestion is related to](url)
**Additional context**
[Add any other context or screenshots about the feature request here.]
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**TableFilter Version:** [Enter TableFilter version here]
**Browser and version:** [Enter Browser name and version here]
**OS and version:** [Enter OS name and version here]
**Device:** [e.g. iPhone6]

17
.github/ISSUE_TEMPLATE/support.md vendored Normal file
View file

@ -0,0 +1,17 @@
---
name: Support
about: I need support with TableFilter
title: ''
labels: ''
assignees: ''
---
For usage and support questions, please check out resources below, you might find an answer:
- https://www.tablefilter.com/
- https://www.tablefilter.com/docs/
- https://www.tablefilter.com/examples.html
- https://github.com/koalyptus/TableFilter/wiki/
- https://github.com/koalyptus/TableFilter/issues?q=is%3Aissue+is%3Aclosed
- https://codepen.io/koalyptus/pens/public/

View file

@ -1,16 +1,53 @@
language: node_js
node_js:
- '6.3.0'
- '8.9.4'
before_script:
- npm install grunt-cli -g
- npm install codecov -g
- npm install grunt-cli -g
- npm install codecov -g
script:
- npm test
- npm run codecov
- npm run deploy
- npm test
- npm run codecov
- npm run build:all
branches:
only:
- master
- /^greenkeeper/.*$/
before_deploy:
- git config --global user.email "maxgug@hotmail.com"
- git config --global user.name "koalyptus"
- export GIT_TAG=$(git describe --tags --abbrev=0)
- echo -n $GIT_TAG
- export NEW_GIT_TAG=$(node -p -e "require('./package.json').version")
- echo -n $NEW_GIT_TAG
- |
if [ $GIT_TAG != $NEW_GIT_TAG ]; then
git tag $NEW_GIT_TAG -am "Generated tag from TravisCI build $TRAVIS_BUILD_NUMBER"
fi
deploy:
- provider: releases
on:
branch: master
api_key: $GITHUB_OAUTH_ACCESS_TOKEN
skip_cleanup: true
name: $NEW_GIT_TAG
- provider: s3
on:
branch: master
access_key_id: $AWS_ACCESS_KEY_ID
secret_access_key: $AWS_SECRET_ACCESS_KEY
region: $AWS_DEFAULT_REGION
bucket: www.tablefilter.com
skip_cleanup: true
local_dir: dist
- provider: s3
on:
branch: master
access_key_id: $AWS_ACCESS_KEY_ID
secret_access_key: $AWS_SECRET_ACCESS_KEY
region: $AWS_DEFAULT_REGION
bucket: www.tablefilter.com
skip_cleanup: true
local_dir: docs
env:
global:
- secure: A1G8GvJkV0rjy7XCTVdOpTHy3xaoSZZAbMWhI+ikrqBqd8mRz+sB71FhRusouTcYdsT5VfF9Io2doS8LKAeP0TNC34Pp0uvjtsvarzn8a/oNEOuqR3Ub0ws2bmbZIZc+wOpgErKOj1H1QSJAUpd6ZjIuEAbOVXlhGBJz3zUCmcpRDh32CpFKC62oFWeGlvttxPciLLzBfKgkVKEGhPtdGP/xCHL1MCQptYVHZiXwWsaIQ5wHFO6KCVlRrPgdfOL+Yce3mT02iXH6ZjW6U6zA6vYQVQZVD873AkU5RmirYblW+jW1wdvu4UXI71lSH6Z3uXRVnrw1b0TsLVTjP9ZUbCtkTHtLbxYzeDjEukxKoCjpAppIhOtaNIxrdA8oKJAabQYp5X+QK6lkosy0zdT5u2B1+g8unZhsf0y//7lgLUe04iQ7sc1Q6AHiiEGtByaXg4BHNW53bUfKgNnbV4+IbXf8rz5wWOxL2/yWAU/GoiszjqRQfajAXCpSf6SyMjXjhhvQdeFn+Cz6FwdtaxH+tOIY0Hq9Gqy1xrLIkv/httd3O+AbhLrU1c/M0MwlFQue7GeJb7ZyF3KsK7bXvoz2dEqvzHd98NZXiQEqFXCIs77uVh4eZMoYrbEyrkOAgkUZNQYhHh9fuvfynJ/zgUvyA0v3GUvBebq3ybYKD/vqX7s=

View file

@ -116,15 +116,13 @@ In general, we follow the "fork-and-pull" Git workflow.
3. **Commit** changes to your own branch
- 3.1. **Add** unit tests covering your change in the `test` folder
- 3.2. **Run** the tests with the `npm run eslint test` command
- 3.3. **Ensure** build is working with `npm run build-all` command
- 3.3. **Ensure** build is working with `npm run dist` command
4. **Push** your work back up to your fork
5. Submit a **Pull request** so that we can review your changes
NOTE: Be sure to merge the latest from "upstream" before making a pull request!
## Donations
To support this project simply locate the `Donate` button in the [project's
website](http://koalyptus.github.io/TableFilter/)
which points to PayPal.
Thanks to all those who supported this project in the past and to those who will
Support this project by donating [here](http://www.tablefilter.com/donate.html).
Thanks to all those who supported this project in the past and those who will
in the future!

View file

@ -1,38 +1,19 @@
module.exports = function (grunt) {
var webpackConfig = require('./webpack.config.js');
var webpackDevConfig = require('./webpack.dev.config.js');
var webpackTestConfig = require('./webpack.test.config.js');
var fs = require('fs');
var path = require('path');
var testDir = 'test';
var testHost = 'http://localhost:8000/';
var pkg = grunt.file.readJSON('package.json');
var repo = 'github.com/koalyptus/TableFilter';
var styleDirDist = 'dist/tablefilter/style/';
grunt.initConfig({
eslint: {
options: {
configFile: '.eslintrc'
},
target: [
'Gruntfile.js',
'webpack.config.js',
'webpack.dev.config.js',
'webpack.test.config.js',
'src/**/*.js',
'test/*.js'
]
},
qunit: {
options: {
'--web-security': 'no',
coverage: {
disposeCollector: true,
src: ['dist/tablefilter/*.js'],
instrumentedFiles: 'temp/',
instrumentedFiles: 'report/temp/',
htmlReport: 'report/coverage',
coberturaReport: 'report/',
lcovReport: 'report/',
@ -126,24 +107,6 @@ module.exports = function (grunt) {
clean: ['demos/starter.html'],
'webpack-dev-server': {
options: {
webpack: webpackDevConfig,
publicPath: '/dist/'
},
start: {
webpack: {
devtool: 'eval'
}
}
},
webpack: {
build: webpackConfig,
dev: webpackDevConfig,
test: webpackTestConfig
},
watch: {
app: {
files: ['src/**/*', 'static/style/**/*'],
@ -161,168 +124,49 @@ module.exports = function (grunt) {
}
},
babel: {
options: {
sourceMap: true,
modules: 'amd',
compact: false,
presets: ['es2015']
// temporary shell commands while decommissioning grunt
shell: {
eslint: {
command: 'npm run lint'
},
dist: {
files: [{
expand: true,
cwd: 'src',
src: ['**/*.js'],
dest: 'dist/tablefilter'
}]
}
},
esdoc: {
dist: {
options: {
source: 'src',
destination: 'docs/docs',
title: pkg.name + ' v' + pkg.version
}
}
},
stylus: {
compile: {
options: {
banner: '/** \n' +
' *\t ' + pkg.name + ' v' + pkg.version +
' by ' + pkg.author.name + ' \n' +
' *\t build date: ' + new Date().toISOString() + ' \n' +
' *\t MIT License \n' +
' */ \n'
},
files: [
{
src: ['static/style/*.styl'],
dest: styleDirDist + 'tablefilter.css'
}, {
src: ['static/style/extensions/colsVisibility.styl'],
dest: styleDirDist + 'colsVisibility.css'
}, {
src: ['static/style/extensions/filtersVisibility.styl'],
dest: styleDirDist + 'filtersVisibility.css'
}, {
src: ['static/style/themes/default/*.styl'],
dest: styleDirDist + 'themes/default/default.css'
}, {
src: ['static/style/themes/mytheme/*.styl'],
dest: styleDirDist + 'themes/mytheme/mytheme.css'
}, {
src: ['static/style/themes/skyblue/*.styl'],
dest: styleDirDist + 'themes/skyblue/skyblue.css'
}, {
src: ['static/style/themes/transparent/*.styl'],
dest:
styleDirDist + 'themes/transparent/transparent.css'
}
]
}
},
'gh-pages': {
options: {
branch: 'gh-pages',
add: true
esdoc: {
command: 'npm run esdoc'
},
'publish-lib': {
options: {
base: 'dist',
repo: 'https://' + repo,
message: 'publish TableFilter lib to gh-pages (cli)'
},
src: ['**/*']
build: {
command: 'npm run build'
},
'publish-readme': {
options: {
base: './',
repo: 'https://' + repo,
message: 'publish README and LICENSE to gh-pages (cli)'
},
src: ['README.md', 'LICENSE']
dev: {
command: 'npm run dev'
},
'publish-docs': {
options: {
base: 'docs',
repo: 'https://' + repo,
message: 'publish Docs to gh-pages (cli)'
},
src: ['**/*']
test: {
command: 'npm run build:test'
},
'deploy-lib': {
options: {
user: {
name: 'koalyptus'
},
base: 'dist',
repo: 'https://' + process.env.GH_TOKEN + '@' + repo,
message: 'publish TableFilter to gh-pages (auto)' +
getDeployMessage(),
silent: true
},
src: ['**/*']
},
'deploy-readme': {
options: {
user: {
name: 'koalyptus'
},
base: './',
repo: 'https://' + process.env.GH_TOKEN + '@' + repo,
message: 'publish README to gh-pages (auto)' +
getDeployMessage(),
silent: true
},
src: ['README.md', 'LICENSE']
},
'deploy-docs': {
options: {
user: {
name: 'koalyptus'
},
base: 'docs',
repo: 'https://' + process.env.GH_TOKEN + '@' + repo,
message: 'publish Docs to gh-pages (auto)' +
getDeployMessage(),
silent: true
},
src: ['**/*']
'build-css': {
command: 'npm run build:css'
}
}
});
grunt.loadNpmTasks('grunt-eslint');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-string-replace');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-webpack');
grunt.loadNpmTasks('grunt-babel');
grunt.loadNpmTasks('grunt-esdoc');
grunt.loadNpmTasks('grunt-shell');
grunt.loadNpmTasks('grunt-qunit-istanbul');
grunt.loadNpmTasks('grunt-contrib-stylus');
grunt.loadNpmTasks('grunt-gh-pages');
grunt.registerTask('eslint', ['shell:eslint']);
grunt.registerTask('esdoc', ['shell:esdoc']);
grunt.registerTask('default', ['test', 'build', 'build-demos']);
// Development server
grunt.registerTask('server', ['webpack-dev-server:start']);
// Dev dev/build/watch cycle
grunt.registerTask('dev',
['eslint', 'webpack:dev', 'copy:dist', 'stylus:compile', 'watch:app']);
['eslint', 'shell:dev', 'copy:dist', 'shell:build-css', 'watch:app']);
// Production build
grunt.registerTask('build',
['eslint', 'webpack:build', 'copy:dist', 'stylus:compile']);
['eslint', 'shell:build', 'copy:dist', 'shell:build-css']);
// Build demos
grunt.registerTask('dev-demos', ['build-demos', 'watch:templates']);
@ -331,23 +175,14 @@ module.exports = function (grunt) {
// Build tests
grunt.registerTask('build-test',
['eslint', 'webpack:test', 'copy:dist', 'stylus:compile']);
// Transpile with Babel
grunt.registerTask('dev-modules', ['babel', 'copy:dist']);
['eslint', 'shell:test', 'copy:dist', 'shell:build-css']);
// Tests with coverage
grunt.registerTask('test', ['build-test', 'connect', 'qunit:all']);
// Publish to gh-pages
grunt.registerTask('publish', 'Publish from CLI', [
'build', 'build-demos', 'esdoc', 'gh-pages:publish-lib',
'gh-pages:publish-readme', 'gh-pages:publish-docs'
]);
// Deploy to gh-pages
grunt.registerTask('deploy', 'Publish from Travis', [
'build', 'esdoc', 'check-deploy'
// Build all for deployment from travis
grunt.registerTask('build-all', 'Prepare for deployment', [
'build', 'build-demos', 'esdoc'
]);
// Custom task running QUnit tests for specified files.
@ -414,43 +249,4 @@ module.exports = function (grunt) {
return getFiles(testDir, host);
}
grunt.registerTask('check-deploy', function () {
var env = process.env;
// need this
this.requires(['build', 'esdoc']);
// only deploy under these conditions
if (env.TRAVIS === 'true' &&
env.TRAVIS_SECURE_ENV_VARS === 'true' &&
env.TRAVIS_PULL_REQUEST === 'false') {
grunt.log.writeln('executing deployment');
// queue deploy
grunt.task.run([
'gh-pages:deploy-lib',
'gh-pages:deploy-readme',
'gh-pages:deploy-docs'
]);
} else {
grunt.log.writeln('skipped deployment');
}
});
// Get a formatted commit message to review changes from the commit log
// github will turn some of these into clickable links
function getDeployMessage() {
var ret = '\n\n';
var env = process.env;
if (env.TRAVIS !== 'true') {
ret += 'missing env vars for travis-ci';
return ret;
}
ret += 'branch: ' + env.TRAVIS_BRANCH + '\n';
ret += 'SHA: ' + env.TRAVIS_COMMIT + '\n';
ret += 'range SHA: ' + env.TRAVIS_COMMIT_RANGE + '\n';
ret += 'build id: ' + env.TRAVIS_BUILD_ID + '\n';
ret += 'build number: ' + env.TRAVIS_BUILD_NUMBER + '\n';
return ret;
}
};

24
PULL_REQUEST_TEMPLATE.md Normal file
View file

@ -0,0 +1,24 @@
# Description
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context.
Fixes # (issue)
## Type of change
Please delete options that are not relevant.
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update
- [ ] Development tool configuration change
# Checklist:
- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes do not lower current test coverage
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes

View file

@ -1,6 +1,8 @@
[![Build Status](https://api.travis-ci.org/koalyptus/TableFilter.svg?branch=master)](https://travis-ci.org/koalyptus/TableFilter)
[![Document](http://koalyptus.github.io/TableFilter/docs/badge.svg)](https://koalyptus.github.io/TableFilter/docs/source)
[![Document](https://www.tablefilter.com/docs/badge.svg)](https://www.tablefilter.com/docs/source.html)
[![codecov](https://codecov.io/gh/koalyptus/TableFilter/branch/master/graph/badge.svg)](https://codecov.io/gh/koalyptus/TableFilter)
[![Greenkeeper badge](https://badges.greenkeeper.io/koalyptus/TableFilter.svg)](https://greenkeeper.io/)
[![Donate](https://img.shields.io/badge/donate-%24-green.svg)](https://www.tablefilter.com/donate.html)
# TableFilter
@ -22,7 +24,7 @@ users to filter and limit the data displayed within a long table. By default, th
* Attach to an existing HTML table
* Integration with any server-side technology as this is a pure client-side
solution
* Exhaustive documentation and poweful API
* Exhaustive documentation and powerful API
## Getting started
* Clone the repo using Git:
@ -32,23 +34,40 @@ git clone https://github.com/koalyptus/TableFilter.git
* You can [download](https://github.com/koalyptus/TableFilter/archive/master.zip) this repository.
* Alternatively, install TableFilter files in your npm enabled project using:
* TableFilter is available on [npm repository](https://www.npmjs.com/package/tablefilter), you can install it from the command line using the following command:
```shell
npm install tablefilter --save-dev
```
```
* or get the future features from the ``next`` release channel:
```shell
npm install tablefilter@next --save-dev
```
* If you don't use `npm`, you can also
[access these files on unpkg](https://unpkg.com/tablefilter/), download them
or point your package manager to them.
* Alternatively you can also [access these files from unpkg CDN](https://unpkg.com/tablefilter/), download them or point your package manager to them.
## Setup
### Using modules
Require `TableFilter`:
```javascript
// ES2015 modules
import TableFilter from 'tablefilter';
// CommonJS or AMD modules
var TableFilter = require('tablefilter');
```
### Using distribution scripts
If you are not using a module system, you can reference the distribution scripts directly in your html pages:
```html
<script src="path_to/node_modules/tablefilter/dist/tablefilter/tablefilter.js"></script>
```
### Placing manually the distribution scripts in your project
Copy the ``tablefilter`` directory under ``dist`` and place it at desired location in your project. Then include the main js file in your page:
```shell
<script src="path/to/my/scripts/tablefilter/tablefilter.js"></script>
```
### Usage
Place the following snippet just under the HTML table and always define a ``base_path`` property in the configuration object to reflect the path to the script
```shell
<script>
@ -62,11 +81,11 @@ If the ``base_path`` property is not specified, it will default to ``/tablefilte
```shell
your-page.html
|— tablefilter
```
```
## Development
This project requires node.js and Grunt to be installed:
- install [node.js](https://nodejs.org/)
- install [node.js](https://nodejs.org/) v8.9.4 or higher
- install [Grunt](http://gruntjs.com/getting-started) from the command line using npm (comes with node.js):
```shell
npm install -g grunt-cli
@ -77,24 +96,24 @@ Start by installing any dependencies.
```shell
npm install
```
Use
Use
```shell
npm run dev
```
```
command to launch a build / watch cycle and start the local
sever on port ``8080``.
Use
Use
```shell
npm run build
```
```
command to generate a production build.
The
The
```shell
npm run dist
```
command will create a production build, run the tests and finally generate
```
command will create a production build, run the tests and finally generate
the demos:
To run all the tests and generate the coverage report:
@ -115,7 +134,7 @@ to view the coverage report(s), open the `index.html` under the
[online](https://codecov.io/gh/koalyptus/TableFilter).
## Demos
Check out the online [examples](http://koalyptus.github.io/TableFilter/examples)
Check out the online [examples](http://www.tablefilter.com/examples.html)
or generate the demos locally:
```shell
npm run build:demos
@ -132,7 +151,7 @@ http://localhost:8080/demos/
## Documentation
Find exhaustive documentation on the configuration options in the [WIKI](https://github.com/koalyptus/TableFilter/wiki) section.
Autogenerated documentation of the ES6 modules is available on the website: [docs](http://koalyptus.github.io/TableFilter/docs)
Autogenerated documentation of the ES6 modules is available on the website: [docs](http://www.tablefilter.com/docs)
If you previously used the HTML Table Filter Generator plugin, verify the configuration
options you are using are still supported: [Obsolete](https://github.com/koalyptus/TableFilter/wiki/Obsolete)
@ -143,7 +162,7 @@ npm run esdoc
```
## Support
* GitHub for reporting bugs and feature requests.
* GitHub for [reporting bugs](https://github.com/koalyptus/TableFilter/blob/master/CONTRIBUTING.md#reporting-bugs) and [feature requests](https://github.com/koalyptus/TableFilter/blob/master/CONTRIBUTING.md#suggesting-enhancements-and-features).
## License
[MIT](LICENSE)

6
dist/starter.html vendored
View file

@ -1,10 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>tablefilter v0.4.40 - Starter</title>
<title>tablefilter v0.7.3 - Starter</title>
</head>
<body>
<h1>tablefilter v0.4.40</h1>
<h1>tablefilter v0.7.3</h1>
@ -479,7 +479,7 @@
},
col_widths: [
'150px', '100px', '100px',
'70px', '70px', '70px',
'100px', '100px', '100px',
'70px', '60px', '60px'
],
extensions:[{ name: 'sort' }]

View file

@ -1,6 +1 @@
/**
* tablefilter v0.4.40 by Max Guglielmi
* build date: 2017-02-11T12:40:33.756Z
* MIT License
*/
span.colVisSpan{text-align:left;}span.colVisSpan a.colVis{display:inline-block;padding:7px 5px 0;font-size:inherit;font-weight:inherit;vertical-align:top}div.colVisCont{position:relative;background:#fff;-webkit-box-shadow:3px 3px 2px #888;-moz-box-shadow:3px 3px 2px #888;box-shadow:3px 3px 2px #888;position:absolute;display:none;border:1px solid #ccc;height:auto;width:250px;background-color:#fff;margin:35px 0 0 -100px;z-index:10000;padding:10px 10px 10px 10px;text-align:left;font-size:12px;}div.colVisCont:after,div.colVisCont:before{bottom:100%;left:50%;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}div.colVisCont:after{border-color:rgba(255,255,255,0);border-bottom-color:#fff;border-width:10px;margin-left:-10px}div.colVisCont:before{border-color:rgba(255,255,255,0);border-bottom-color:#ccc;border-width:12px;margin-left:-12px}div.colVisCont p{margin:6px auto 6px auto}div.colVisCont a.colVis{display:initial;font-weight:inherit}ul.cols_checklist{padding:0;margin:0;list-style:none;}ul.cols_checklist label{display:block}ul.cols_checklist input{vertical-align:middle;margin:2px 5px 2px 1px}li.cols_checklist_item{padding:4px;margin:0;}li.cols_checklist_item:hover{background-color:#335ea8;color:#fff}.cols_checklist_slc_item{background-color:#335ea8;color:#fff}
span.colVisSpan{text-align:left;}span.colVisSpan a.colVis{display:inline-block;padding:7px 5px 0;font-size:inherit;font-weight:inherit;vertical-align:top}div.colVisCont{position:relative;background:#fff;-webkit-box-shadow:3px 3px 2px #888;-moz-box-shadow:3px 3px 2px #888;box-shadow:3px 3px 2px #888;position:absolute;display:none;border:1px solid #ccc;height:auto;width:250px;background-color:#fff;margin:35px 0 0 -100px;z-index:10000;padding:10px 10px 10px 10px;text-align:left;font-size:inherit;}div.colVisCont:after,div.colVisCont:before{bottom:100%;left:50%;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}div.colVisCont:after{border-color:rgba(255,255,255,0);border-bottom-color:#fff;border-width:10px;margin-left:-10px}div.colVisCont:before{border-color:rgba(255,255,255,0);border-bottom-color:#ccc;border-width:12px;margin-left:-12px}div.colVisCont p{margin:6px auto 6px auto}div.colVisCont a.colVis{display:initial;font-weight:inherit}ul.cols_checklist{padding:0;margin:0;list-style-type:none;}ul.cols_checklist label{display:block}ul.cols_checklist input{vertical-align:middle;margin:2px 5px 2px 1px}li.cols_checklist_item{padding:4px;margin:0;}li.cols_checklist_item:hover{background-color:#335ea8;color:#fff}.cols_checklist_slc_item{background-color:#335ea8;color:#fff}

View file

@ -1,6 +1 @@
/**
* tablefilter v0.4.40 by Max Guglielmi
* build date: 2017-02-11T12:40:33.756Z
* MIT License
*/
span.expClpFlt a.btnExpClpFlt{width:35px;height:35px;display:inline-block;}span.expClpFlt a.btnExpClpFlt:hover{background-color:#f4f4f4}span.expClpFlt img{padding:8px 11px 11px 11px}

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1 @@
/**
* tablefilter v0.4.40 by Max Guglielmi
* build date: 2017-02-11T12:40:33.756Z
* MIT License
*/
table.TF{border-left:1px solid #ccc;border-top:none;border-right:none;border-bottom:none;}table.TF th{background:#ebecee url("images/bg_th.jpg") left top repeat-x;border-bottom:1px solid #d0d0d0;border-right:1px solid #d0d0d0;border-left:1px solid #fff;border-top:1px solid #fff;color:#333}table.TF td{border-bottom:1px dotted #999;padding:5px}.fltrow{background-color:#ebecee !important;}.fltrow th,.fltrow td{border-bottom:1px dotted #666 !important;padding:1px 3px 1px 3px !important}.flt,select.flt,select.flt_multi,.flt_s,.single_flt,.div_checklist{border:1px solid #999 !important}input.flt{width:99% !important}.inf{height:$min-height;background:#d7d7d7 url("images/bg_infDiv.jpg") 0 0 repeat-x !important}input.reset{background:transparent url("images/btn_eraser.gif") center center no-repeat !important}.helpBtn:hover{background-color:transparent}.nextPage{background:transparent url("images/btn_next_page.gif") center center no-repeat !important;}.nextPage:hover{background:transparent url("images/btn_over_next_page.gif") center center no-repeat !important}.previousPage{background:transparent url("images/btn_previous_page.gif") center center no-repeat !important;}.previousPage:hover{background:transparent url("images/btn_over_previous_page.gif") center center no-repeat !important}.firstPage{background:transparent url("images/btn_first_page.gif") center center no-repeat !important;}.firstPage:hover{background:transparent url("images/btn_over_first_page.gif") center center no-repeat !important}.lastPage{background:transparent url("images/btn_last_page.gif") center center no-repeat !important;}.lastPage:hover{background:transparent url("images/btn_over_last_page.gif") center center no-repeat !important}div.grd_Cont{background-color:#ebecee !important;border:1px solid #ccc !important;padding:0 !important;}div.grd_Cont .even{background-color:#fff}div.grd_Cont .odd{background-color:#d5d5d5}div.grd_headTblCont{background-color:#ebecee !important;border-bottom:none !important;}div.grd_headTblCont table{border-right:none !important}div.grd_tblCont table th,div.grd_headTblCont table th,div.grd_headTblCont table td{background:#ebecee url("images/bg_th.jpg") left top repeat-x !important;border-bottom:1px solid #d0d0d0 !important;border-right:1px solid #d0d0d0 !important;border-left:1px solid #fff !important;border-top:1px solid #fff !important}div.grd_tblCont table td{border-bottom:1px solid #999 !important}.grd_inf{background:#d7d7d7 url("images/bg_infDiv.jpg") 0 0 repeat-x !important;border-top:1px solid #d0d0d0 !important}.loader{border:1px solid #999}.defaultLoader{width:32px;height:32px;background:transparent url("images/img_loading.gif") 0 0 no-repeat !important}.even{background-color:#fff}.odd{background-color:#d5d5d5}span.expClpFlt a.btnExpClpFlt:hover{background-color:transparent !important}.activeHeader{background:#999 !important}

View file

@ -1,6 +1 @@
/**
* tablefilter v0.4.40 by Max Guglielmi
* build date: 2017-02-11T12:40:33.756Z
* MIT License
*/
table.TF{border-left:1px dotted #81963b;border-top:none;border-right:0;border-bottom:none;}table.TF th{background:#39424b url("images/bg_headers.jpg") left top repeat-x;border-bottom:0;border-right:1px dotted #d0d0d0;border-left:0;border-top:0;color:#fff}table.TF td{border-bottom:1px dotted #81963b;border-right:1px dotted #81963b;padding:5px}.fltrow{background-color:#81963b !important;}.fltrow th,.fltrow td{border-bottom:1px dotted #39424b !important;border-right:1px dotted #fff !important;border-left:0 !important;border-top:0 !important;padding:1px 3px 1px 3px !important}.flt,select.flt,select.flt_multi,.flt_s,.single_flt,.div_checklist{border:1px solid #687830 !important}input.flt{width:99% !important}.inf{background:#d8d8d8;height:$min-height}input.reset{width:53px;background:transparent url("images/btn_filter.png") center center no-repeat !important}.helpBtn:hover{background-color:transparent}.nextPage{background:transparent url("images/btn_next_page.gif") center center no-repeat !important}.previousPage{background:transparent url("images/btn_previous_page.gif") center center no-repeat !important}.firstPage{background:transparent url("images/btn_first_page.gif") center center no-repeat !important}.lastPage{background:transparent url("images/btn_last_page.gif") center center no-repeat !important}div.grd_Cont{background:#81963b url("images/bg_headers.jpg") left top repeat-x !important;border:1px solid #ccc !important;padding:0 1px 1px 1px !important;}div.grd_Cont .even{background-color:#bccd83}div.grd_Cont .odd{background-color:#fff}div.grd_headTblCont{background-color:#ebecee !important;border-bottom:none !important}div.grd_tblCont table{border-right:none !important;}div.grd_tblCont table td{border-bottom:1px dotted #81963b;border-right:1px dotted #81963b}div.grd_tblCont table th,div.grd_headTblCont table th{background:transparent url("images/bg_headers.jpg") 0 0 repeat-x !important;border-bottom:0 !important;border-right:1px dotted #d0d0d0 !important;border-left:0 !important;border-top:0 !important;padding:0 4px 0 4px !important;color:#fff !important;height:35px !important}div.grd_headTblCont table td{border-bottom:1px dotted #39424b !important;border-right:1px dotted #fff !important;border-left:0 !important;border-top:0 !important;background-color:#81963b !important;padding:1px 3px 1px 3px !important}.grd_inf{background-color:#d8d8d8;border-top:1px solid #d0d0d0 !important}.loader{border:0 !important;background:#81963b !important}.defaultLoader{width:32px;height:32px;background:transparent url("images/img_loading.gif") 0 0 no-repeat !important}.even{background-color:#bccd83}.odd{background-color:#fff}span.expClpFlt a.btnExpClpFlt:hover{background-color:transparent !important}.activeHeader{background:#81963b !important}

View file

@ -1,6 +1 @@
/**
* tablefilter v0.4.40 by Max Guglielmi
* build date: 2017-02-11T12:40:33.756Z
* MIT License
*/
table.TF{padding:0;color:#000;border-right:1px solid #a4bed4;border-top:1px solid #a4bed4;border-left:1px solid #a4bed4;border-bottom:0;}table.TF th{margin:0;color:inherit;background:#d1e5fe url("images/bg_skyblue.gif") 0 0 repeat-x;border-color:#fdfdfd #a4bed4 #a4bed4 #fdfdfd;border-width:1px;border-style:solid}table.TF td{margin:0;padding:5px;color:inherit;border-bottom:1px solid #a4bed4;border-left:0;border-top:0;border-right:0}.fltrow{background-color:#d1e5fe !important;}.fltrow th,.fltrow td{padding:1px 3px 1px 3px !important}.flt,select.flt,select.flt_multi,.flt_s,.single_flt,.div_checklist{border:1px solid #a4bed4 !important}input.flt{width:99% !important}.inf{background-color:#e3efff !important;border:1px solid #a4bed4;height:$min-height;color:#004a6f}div.tot,div.status{border-right:0 !important}.helpBtn:hover{background-color:transparent}input.reset{background:transparent url("images/icn_clear_filters.png") center center no-repeat !important}.nextPage{background:transparent url("images/btn_next_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.nextPage:hover{background:#ffe4ab url("images/btn_next_page.gif") center center no-repeat !important;border:1px solid #ffb552 !important}.previousPage{background:transparent url("images/btn_prev_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.previousPage:hover{background:#ffe4ab url("images/btn_prev_page.gif") center center no-repeat !important;border:1px solid #ffb552 !important}.firstPage{background:transparent url("images/btn_first_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.firstPage:hover{background:#ffe4ab url("images/btn_first_page.gif") center center no-repeat !important;border:1px solid #ffb552 !important}.lastPage{background:transparent url("images/btn_last_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.lastPage:hover{background:#ffe4ab url("images/btn_last_page.gif") center center no-repeat !important;border:1px solid #ffb552 !important}.activeHeader{background:#ffe4ab !important;border:1px solid #ffb552 !important;color:inherit !important}div.grd_Cont{background-color:#d9eaed !important;border:1px solid #9cc !important;padding:0 !important;}div.grd_Cont .even{background-color:#fff}div.grd_Cont .odd{background-color:#e3efff}div.grd_headTblCont{background-color:#d9eaed !important;border-bottom:none !important}div.grd_tblCont table{border-right:none !important}div.grd_tblCont table th,div.grd_headTblCont table th,div.grd_headTblCont table td{background:#d9eaed url("images/bg_skyblue.gif") left top repeat-x;border-bottom:1px solid #a4bed4;border-right:1px solid #a4bed4 !important;border-left:1px solid #fff !important;border-top:1px solid #fff !important}div.grd_tblCont table td{border-bottom:1px solid #a4bed4 !important;border-right:0 !important;border-left:0 !important;border-top:0 !important}.grd_inf{background-color:#cce2fe;color:#004a6f;border-top:1px solid #9cc !important;}.grd_inf a{text-decoration:none;font-weight:bold}.loader{background-color:#2d8eef;border:1px solid #cce2fe;border-radius:5px}.even{background-color:#fff}.odd{background-color:#e3efff}span.expClpFlt a.btnExpClpFlt:hover{background-color:transparent !important}.ezActiveRow{background-color:#ffdc61 !important;color:inherit}.ezSelectedRow{background-color:#ffe4ab !important;color:inherit}.ezActiveCell{background-color:#fff !important;color:#000 !important;font-weight:bold}.ezETSelectedCell{background-color:#fff !important;font-weight:bold;color:#000 !important}

View file

@ -1,6 +1 @@
/**
* tablefilter v0.4.40 by Max Guglielmi
* build date: 2017-02-11T12:40:33.756Z
* MIT License
*/
table.TF{padding:0;color:inherit;border-right:1px solid transparent;border-top:1px solid transparent;border-left:1px solid transparent;border-bottom:0;}table.TF th{margin:0;color:inherit;background-color:transparent;border-color:transparent;border-width:1px;border-style:solid;}table.TF th:last-child{border-right:1px solid transparent}table.TF td{margin:0;padding:5px;color:inherit;border-bottom:1px solid transparent;border-left:0;border-top:0;border-right:0}.fltrow{background-color:transparent;}.fltrow th,.fltrow td{padding:1px 3px 1px 3px;border-bottom:1px solid transparent !important;}.fltrow th:last-child,.fltrow td:last-child{border-right:1px solid transparent}.flt,select.flt,select.flt_multi,.flt_s,.single_flt,.div_checklist{border:1px solid #a4bed4}input.flt{width:99% !important}.inf{background-color:transparent;border:1px solid transparent;height:$min-height;color:inherit}div.tot,div.status{border-right:0 !important}.helpBtn:hover{background-color:transparent}input.reset{background:transparent url("images/icn_clear_filters.png") center center no-repeat !important}.nextPage{background:transparent url("images/btn_next_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.nextPage:hover{background:#f7f7f7 url("images/btn_next_page.gif") center center no-repeat !important;border:1px solid #f7f7f7 !important}.previousPage{background:transparent url("images/btn_prev_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.previousPage:hover{background:#f7f7f7 url("images/btn_prev_page.gif") center center no-repeat !important;border:1px solid #f7f7f7 !important}.firstPage{background:transparent url("images/btn_first_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.firstPage:hover{background:#f7f7f7 url("images/btn_first_page.gif") center center no-repeat !important;border:1px solid #f7f7f7 !important}.lastPage{background:transparent url("images/btn_last_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.lastPage:hover{background:#f7f7f7 url("images/btn_last_page.gif") center center no-repeat !important;border:1px solid #f7f7f7 !important}.activeHeader{background:#f7f7f7 !important;border:1px solid transparent;color:inherit !important}div.grd_Cont{-webkit-box-shadow:0 0 0 0 rgba(50,50,50,0.75);-moz-box-shadow:0 0 0 0 rgba(50,50,50,0.75);box-shadow:0 0 0 0 rgba(50,50,50,0.75);background-color:transparent;border:1px solid transparent;padding:0 !important;}div.grd_Cont .even{background-color:transparent}div.grd_Cont .odd{background-color:#f7f7f7}div.grd_headTblCont{background-color:transparent;border-bottom:none !important}div.grd_tblCont table{border-right:none !important}div.grd_tblCont table th,div.grd_headTblCont table th,div.grd_headTblCont table td{background:transparent;border-bottom:1px solid transparent;border-right:1px solid transparent !important;border-left:1px solid transparent;border-top:1px solid transparent}div.grd_tblCont table td{border-bottom:1px solid transparent;border-right:0 !important;border-left:0 !important;border-top:0 !important}.grd_inf{background-color:transparent;color:inherit;border-top:1px solid transparent;}.grd_inf a{text-decoration:none;font-weight:bold}.loader{background-color:#f7f7f7;border:1px solid #f7f7f7;border-radius:5px;color:#000;text-shadow:none}.even{background-color:transparent}.odd{background-color:#f7f7f7}span.expClpFlt a.btnExpClpFlt:hover{background-color:transparent !important}.ezActiveRow{background-color:#ccc !important;color:inherit}.ezSelectedRow{background-color:#ccc !important;color:inherit}.ezActiveCell{background-color:transparent;color:inherit;font-weight:bold}.ezETSelectedCell{background-color:transparent;font-weight:bold;color:inherit}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

12319
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
{
"name": "tablefilter",
"version": "0.4.40",
"version": "0.7.3",
"description": "A Javascript library making HTML tables filterable and a bit more",
"license": "MIT",
"author": {
@ -22,54 +22,58 @@
"pagination"
],
"scripts": {
"dev": "grunt dev",
"build": "grunt build",
"lint": "eslint src/**/*.js test/*.js *.js",
"dev": "webpack --colors --config webpack.dev.config.js",
"build": "webpack --colors --config webpack.config.js",
"build:css": "stylus -c static/style/tablefilter.styl -o dist/tablefilter/style && stylus -c static/style/extensions -o dist/tablefilter/style && stylus -c static/style/themes/default -o dist/tablefilter/style/themes/default && stylus -c static/style/themes/mytheme -o dist/tablefilter/style/themes/mytheme && stylus -c static/style/themes/skyblue -o dist/tablefilter/style/themes/skyblue && stylus -c static/style/themes/transparent -o dist/tablefilter/style/themes/transparent",
"build:demos": "grunt build-demos",
"server": "grunt server",
"eslint": "grunt eslint",
"build:test": "webpack --colors --config webpack.test.config.js",
"server": "webpack-dev-server --colors --hot --config ./webpack.dev.config.js",
"test": "grunt test",
"codecov": "./node_modules/.bin/codecov",
"esdoc": "grunt esdoc",
"esdoc": "esdoc",
"dist": "grunt",
"deploy": "grunt deploy",
"build:all": "grunt build-all",
"start": "npm run server"
},
"publishConfig": {
"tag": "next"
},
"devDependencies": {
"babel-core": "^6.22.1",
"babel-eslint": "7.1.1",
"babel-loader": "^6.2.9",
"babel-plugin-transform-es2015-classes": "^6.22.0",
"babel-preset-es2015": "^6.22.0",
"clean-webpack-plugin": "^0.1.15",
"codecov": "1.0.1",
"@babel/core": "7.10.0",
"@babel/preset-env": "7.10.0",
"babel-eslint": "10.1.0",
"babel-loader": "^8.0.2",
"babel-preset-env": "1.7.0",
"clean-webpack-plugin": "^3.0.0",
"codecov": "3.7.1",
"diacritics": "1.3.0",
"esdoc": "1.1.0",
"esdoc-standard-plugin": "1.0.0",
"eslint": "6.5.0",
"format-number": "3.0.0",
"grunt": "^1.0.1",
"grunt-babel": "^6.0.0",
"grunt-cli": "1.2.0",
"grunt-contrib-clean": "^1.0.0",
"grunt-contrib-connect": "^1.0.2",
"grunt-cli": "1.3.2",
"grunt-contrib-clean": "^2.0.0",
"grunt-contrib-connect": "^2.0.0",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-stylus": "^1.2.0",
"grunt-contrib-watch": "^1.0.0",
"grunt-esdoc": "^0.0.4",
"grunt-eslint": "19.0.0",
"grunt-gh-pages": "^2.0.0",
"grunt-qunit-istanbul": "1.0.0",
"grunt-qunit-istanbul": "1.1.0",
"grunt-shell": "3.0.0",
"grunt-string-replace": "^1.3.1",
"grunt-webpack": "^2.0.1",
"isparta-loader": "2.0.0",
"script-loader": "^0.7.0",
"string-replace-webpack-plugin": "^0.0.5",
"sugar-date": "2.0.4",
"webpack": "^2.2.1",
"webpack-dev-server": "^2.3.0"
"string-replace-webpack-plugin": "^0.1.3",
"stylus": "^0.54.5",
"sugar-date": "2.0.6",
"uglifyjs-webpack-plugin": "2.2.0",
"webpack": "^4.38.0",
"webpack-cli": "^3.0.8",
"webpack-dev-server": "^3.1.11"
},
"dependencies": {},
"bugs": {
"url": "https://github.com/koalyptus/TableFilter/issues"
},
"homepage": "http://koalyptus.github.io/TableFilter"
"homepage": "https://www.tablefilter.com"
}

View file

@ -19,4 +19,4 @@ export const has = (arr, val, caseSensitive) => {
}
}
return false;
}
};

View file

@ -18,7 +18,7 @@ export const getText = (node) => {
return trim(node.innerText);
}
return trim(node.textContent);
}
};
/**
* Returns the first text node contained in the supplied node
@ -32,11 +32,11 @@ export const getFirstTextNode = (node) => {
return n.data;
}
}
}
};
/**
* Creates an html element with given collection of attributes
* @param {String} tag a string of the html tag to create
* @param {String} tag html tag name
* @param {Array} an undetermined number of arrays containing the with 2
* items, the attribute name and its value ['id','myId']
* @return {Object} created element
@ -55,9 +55,8 @@ export const createElm = (...args) => {
el.setAttribute(arg[0], arg[1]);
}
}
return el;
}
};
/**
* Removes passed node from DOM
@ -88,7 +87,7 @@ export const hasClass = (ele, cls) => {
return ele.classList.contains(cls);
}
return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}
};
/**
* Adds the specified class to the passed element
@ -111,7 +110,7 @@ export const addClass = (ele, cls) => {
else if (!hasClass(ele, cls)) {
ele.className += ' ' + cls;
}
}
};
/**
* Removes the specified class to the passed element
@ -129,7 +128,7 @@ export const removeClass = (ele, cls) => {
}
let reg = new RegExp('(\\s|^)' + cls + '(\\s|$)', 'g');
ele.className = ele.className.replace(reg, '');
}
};
/**
* Creates and returns an option element
@ -141,27 +140,29 @@ export const removeClass = (ele, cls) => {
export const createOpt = (text, value, isSel) => {
let isSelected = isSel ? true : false;
let opt = isSelected ?
createElm('option', ['value', value], ['selected', 'true']) :
createElm('option', ['value', value]);
createElm('option', ['value', value], ['selected', 'true']) :
createElm('option', ['value', value]);
opt.appendChild(createText(text));
return opt;
}
};
/**
* Creates and returns a checklist item
* @param {String} id index of check item
* @param {String} chkValue check item value
* @param {String} labelText check item label text
* @param {Array} extraAttr array containing attribute name and its value
* @return {Object} li DOM element
*/
export const createCheckItem = (id, chkValue, labelText) => {
export const createCheckItem = (id, chkValue, labelText, extraAttr = []) => {
let li = createElm('li');
let label = createElm('label', ['for', id]);
let check = createElm('input',
['id', id],
['name', id],
['type', 'checkbox'],
['value', chkValue]
['value', chkValue],
extraAttr
);
label.appendChild(check);
label.appendChild(createText(labelText));
@ -169,7 +170,7 @@ export const createCheckItem = (id, chkValue, labelText) => {
li.label = label;
li.check = check;
return li;
}
};
/**
* Returns the element matching the supplied Id

View file

@ -99,3 +99,26 @@ export const keyCode = (evt) => {
return evt.charCode ? evt.charCode :
(evt.keyCode ? evt.keyCode : (evt.which ? evt.which : 0));
};
/**
* Check code of pressed key is one of the expected key codes
*
* @param {Event} evt key event
* @param {Array} keyCodes list of keycodes to check
*/
export const isKeyPressed = (evt, keyCodes = []) => {
return keyCodes.indexOf(keyCode(evt)) !== -1;
};
/**
* Bind passed function to passed scope
* @param {Function} fn function
* @param {Object} scope object instance
*/
export function bound(fn, scope) {
let boundFnName = `${fn.name}_bound`;
if (!scope[boundFnName]) {
scope[boundFnName] = fn.bind(scope);
}
return scope[boundFnName];
}

View file

@ -1,6 +1,7 @@
import {Feature} from '../../feature';
import {tag} from '../../dom';
import {INPUT} from '../../const';
import {defaultsStr} from '../../settings';
import {root} from '../../root';
const INSTANTIATION_ERROR = `Failed to instantiate EditTable object.
@ -20,19 +21,19 @@ export default class AdapterEzEditTable extends Feature {
* @param {Object} cfg Configuration options for ezEditTable library
*/
constructor(tf, cfg) {
super(tf, cfg.name);
super(tf, AdapterEzEditTable);
/**
* Module description
* @type {String}
*/
this.desc = cfg.description || 'ezEditTable adapter';
this.desc = defaultsStr(cfg.description, 'ezEditTable adapter');
/**
* Filename of ezEditTable library
* @type {String}
*/
this.filename = cfg.filename || 'ezEditTable.js';
this.filename = defaultsStr(cfg.filename, 'ezEditTable.js');
/**
* Path to ezEditTable library
@ -50,13 +51,15 @@ export default class AdapterEzEditTable extends Feature {
* Path to ezEditTable stylesheet
* @type {String}
*/
this.stylesheet = cfg.stylesheet || this.vendorPath + 'ezEditTable.css';
this.stylesheet = defaultsStr(cfg.stylesheet,
this.vendorPath + 'ezEditTable.css');
/**
* Name of ezEditTable stylesheet
* @type {String}
*/
this.stylesheetName = cfg.stylesheet_name || 'ezEditTableCss';
this.stylesheetName = defaultsStr(cfg.stylesheet_name,
'ezEditTableCss');
// Enable the ezEditTable's scroll into view behaviour if grid layout on
cfg.scroll_into_view = cfg.scroll_into_view === false ?
@ -117,7 +120,7 @@ export default class AdapterEzEditTable extends Feature {
//start row for EditTable constructor needs to be calculated
let startRow,
cfg = this.cfg,
thead = tag(tf.tbl, 'thead');
thead = tag(tf.dom(), 'thead');
//if thead exists and startRow not specified, startRow is calculated
//automatically by EditTable
@ -158,7 +161,7 @@ export default class AdapterEzEditTable extends Feature {
et.ClearSelections();
/* eslint-enable */
let cellIndex = selectedElm.cellIndex,
row = tf.tbl.rows[nextRowIndex];
row = tf.dom().rows[nextRowIndex];
if (et.defaultSelection === 'both') {
/* eslint-disable */
slc.SelectRowByIndex(nextRowIndex);
@ -172,7 +175,7 @@ export default class AdapterEzEditTable extends Feature {
}
//Table is filtered
if (tf.validRowsIndex.length !== tf.getRowsNb()) {
let r = tf.tbl.rows[nextRowIndex];
let r = tf.dom().rows[nextRowIndex];
if (r) {
r.scrollIntoView(false);
}
@ -208,7 +211,7 @@ export default class AdapterEzEditTable extends Feature {
paging = tf.feature('paging'),
//pgup/pgdown keys
d = keyCode === 34 || keyCode === 33 ?
(paging && paging.pagingLength || et.nbRowsPerPage) :
(paging && paging.pageLength || et.nbRowsPerPage) :
1;
//If next row is not valid, next valid filtered row needs to be
@ -278,11 +281,11 @@ export default class AdapterEzEditTable extends Feature {
if (tf.feature('paging').nbPages > 1) {
let paging = tf.feature('paging');
//page length is re-assigned in case it has changed
et.nbRowsPerPage = paging.pagingLength;
et.nbRowsPerPage = paging.pageLength;
let validIndexes = tf.validRowsIndex,
validIdxLen = validIndexes.length,
pagingEndRow = parseInt(paging.startPagingRow, 10) +
parseInt(paging.pagingLength, 10);
parseInt(paging.pageLength, 10);
let rowIndex = row.rowIndex;
if ((rowIndex === validIndexes[validIdxLen - 1]) &&
@ -502,3 +505,5 @@ export default class AdapterEzEditTable extends Feature {
this.initialized = false;
}
}
AdapterEzEditTable.meta = {altName: 'advancedGrid'};

View file

@ -1,7 +1,11 @@
import {Feature} from '../../feature';
import {createText, elm} from '../../dom';
import {isArray, isFn, isUndef, isEmpty, EMPTY_FN} from '../../types';
import {isArray, isEmpty, EMPTY_FN} from '../../types';
import {numSortAsc} from '../../sort';
import {FORMATTED_NUMBER} from '../../const';
import formatNumber from 'format-number';
import {defaultsFn, defaultsArr} from '../../settings';
import {bound} from '../../event';
const EVENTS = [
'after-filtering',
@ -29,21 +33,19 @@ export default class ColOps extends Feature {
* @param {Object} opts Configuration object
*/
constructor(tf, opts) {
super(tf, opts.name);
super(tf, ColOps);
/**
* Callback fired before columns operations start
* @type {Function}
*/
this.onBeforeOperation = isFn(opts.on_before_operation) ?
opts.on_before_operation : EMPTY_FN;
this.onBeforeOperation = defaultsFn(opts.on_before_operation, EMPTY_FN);
/**
* Callback fired after columns operations are completed
* @type {Function}
*/
this.onAfterOperation = isFn(opts.on_after_operation) ?
opts.on_after_operation : EMPTY_FN;
this.onAfterOperation = defaultsFn(opts.on_after_operation, EMPTY_FN);
/**
* Configuration options
@ -55,46 +57,53 @@ export default class ColOps extends Feature {
* List of DOM element IDs containing column's calculation result
* @type {Array}
*/
this.labelIds = opts.id || [];
this.labelIds = defaultsArr(opts.id, []);
/**
* List of columns' indexes for calculations
* @type {Array}
*/
this.colIndexes = opts.col || [];
this.colIndexes = defaultsArr(opts.col, []);
/**
* List of operations - possible values: 'sum', 'mean', 'min', 'max',
* 'median', 'q1', 'q3'
* @type {Array}
*/
this.operations = opts.operation || [];
this.operations = defaultsArr(opts.operation, []);
/**
* List of write methods used to write the result - possible values:
* 'innerHTML', 'setValue', 'createTextNode'
* @type {Array}
*/
this.outputTypes = opts.write_method || [];
this.outputTypes = defaultsArr(opts.write_method, []);
/**
* List of format objects used for formatting the result -
* refer to https://github.com/componitable/format-number to check
* configuration options
* @type {Array}
*/
this.formatResults = defaultsArr(opts.format_result, []);
/**
* List of row indexes displaying the results
* @type {Array}
*/
this.totRowIndexes = opts.tot_row_index || [];
this.totRowIndexes = defaultsArr(opts.tot_row_index, []);
/**
* List of row indexes excluded from calculations
* @type {Array}
*/
this.excludeRows = opts.exclude_row || [];
this.excludeRows = defaultsArr(opts.exclude_row, []);
/**
* List of decimal precision for calculation results
* @type {Array}
*/
this.decimalPrecisions = isUndef(opts.decimal_precision) ?
2 : opts.decimal_precision;
this.decimalPrecisions = defaultsArr(opts.decimal_precision, 2);
this.enable();
}
@ -107,7 +116,7 @@ export default class ColOps extends Feature {
return;
}
// subscribe to events
this.emitter.on(EVENTS, () => this.calcAll());
this.emitter.on(EVENTS, bound(this.calcAll, this));
this.calcAll();
@ -140,13 +149,9 @@ export default class ColOps extends Feature {
this.onBeforeOperation(tf, this);
this.emitter.emit('before-column-operation', tf, this);
let colIndexes = this.colIndexes,
colOperations = this.operations,
outputTypes = this.outputTypes,
totRowIndexes = this.totRowIndexes,
excludeRows = this.excludeRows,
decimalPrecisions = isUndef(this.decimalPrecisions) ?
2 : this.decimalPrecisions;
let { colIndexes, operations: colOperations, outputTypes,
totRowIndexes, excludeRows, formatResults,
decimalPrecisions } = this;
//nuovella: determine unique list of columns to operate on
let uIndexes = [];
@ -157,7 +162,7 @@ export default class ColOps extends Feature {
});
let nbCols = uIndexes.length,
rows = tf.tbl.rows,
rows = tf.dom().rows,
colValues = [];
for (let u = 0; u < nbCols; u++) {
@ -165,7 +170,7 @@ export default class ColOps extends Feature {
//use uIndexes because we only want to pass through this loop
//once for each column get the values in this unique column
colValues.push(
tf.getFilteredDataCol(uIndexes[u], false, true, excludeRows)
tf.getVisibleColumnData(uIndexes[u], false, excludeRows)
);
let curValues = colValues[u];
@ -176,6 +181,7 @@ export default class ColOps extends Feature {
precisions = [],
labels = [],
writeType,
formatResult = [],
idx = 0;
for (let k = 0; k < colIndexes.length; k++) {
@ -186,6 +192,8 @@ export default class ColOps extends Feature {
precisions[idx] = decimalPrecisions[k];
labels[idx] = this.labelIds[k];
writeType = isArray(outputTypes) ? outputTypes[k] : null;
formatResult[idx] =
this.configureFormat(uIndexes[u], formatResults[k]);
idx++;
}
@ -219,7 +227,8 @@ export default class ColOps extends Feature {
result,
labels[i],
writeType,
precisions[i]
precisions[i],
formatResult[i]
);
}//for i
@ -245,8 +254,8 @@ export default class ColOps extends Feature {
*/
columnCalc(colIndex, operation = SUM, precision) {
let excludeRows = this.excludeRows || [];
let colValues =
this.tf.getFilteredDataCol(colIndex, false, true, excludeRows);
let colValues = tf.getVisibleColumnData(colIndex, false, excludeRows);
return Number(this.calc(colValues, operation, precision));
}
@ -402,7 +411,8 @@ export default class ColOps extends Feature {
* @param {Number} [precision=2] Applied decimal precision
* @private
*/
writeResult(result = 0, label, writeType = 'innerhtml', precision = 2) {
writeResult(result = 0, label, writeType = 'innerhtml',
precision = 2, format = {}) {
let labelElm = elm(label);
if (!labelElm) {
@ -412,6 +422,8 @@ export default class ColOps extends Feature {
result = result.toFixed(precision);
if (isNaN(result) || !isFinite(result)) {
result = '';
} else {
result = formatNumber(format)(result);
}
switch (writeType.toLowerCase()) {
@ -429,13 +441,38 @@ export default class ColOps extends Feature {
}
}
/**
* Configure the format options used to format the operation result based
* on column type.
* @param {Number} colIndex Column index
* @param {Object} [format={}] Format object
* @returns {Object}
* @private
*/
configureFormat(colIndex, format = {}) {
let tf = this.tf;
if (tf.hasType(colIndex, [FORMATTED_NUMBER])) {
let colType = tf.colTypes[colIndex];
if (colType.decimal && !format.decimal) {
format.decimal = colType.decimal;
}
if (colType.thousands && !format.integerSeparator) {
format.integerSeparator = colType.thousands;
}
} else {
format.decimal = format.decimal || '';
format.integerSeparator = format.integerSeparator || '';
}
return format;
}
/** Remove extension */
destroy() {
if (!this.initialized) {
return;
}
// unsubscribe to events
this.emitter.off(EVENTS, () => this.calcAll());
this.emitter.off(EVENTS, bound(this.calcAll, this));
this.initialized = false;
}

View file

@ -1,11 +1,16 @@
import {Feature} from '../../feature';
import {
addClass, removeClass, createCheckItem, createElm, elm, removeElm,
getText
getText, tag
} from '../../dom';
import {isFn, EMPTY_FN} from '../../types';
import {isUndef, EMPTY_FN, isNull} from '../../types';
import {addEvt, targetEvt, removeEvt} from '../../event';
import {root} from '../../root';
import {NONE} from '../../const';
import {
defaultsBool, defaultsStr, defaultsFn, defaultsNb, defaultsArr
} from '../../settings';
import {RIGHT} from '../../modules/toolbar';
/**
* Columns Visibility extension
@ -18,7 +23,7 @@ export default class ColsVisibility extends Feature {
* @param {Object} Configuration object
*/
constructor(tf, f) {
super(tf, f.name);
super(tf, ColsVisibility);
// Configuration object
let cfg = this.config;
@ -33,7 +38,7 @@ export default class ColsVisibility extends Feature {
* Module description
* @type {String}
*/
this.desc = f.description || 'Columns visibility manager';
this.desc = defaultsStr(f.description, 'Columns visibility manager');
/**
* show/hide columns container element
@ -57,13 +62,13 @@ export default class ColsVisibility extends Feature {
* Enable tick to hide a column, defaults to true
* @type {Boolean}
*/
this.tickToHide = f.tick_to_hide === false ? false : true;
this.tickToHide = defaultsBool(f.tick_to_hide, true);
/**
* Enable columns manager UI, defaults to true
* @type {Boolean}
*/
this.manager = f.manager === false ? false : true;
this.manager = defaultsBool(f.manager, true);
/**
* Headers HTML table reference only if headers are external
@ -75,112 +80,115 @@ export default class ColsVisibility extends Feature {
* Headers row index only if headers are external
* @type {Number}
*/
this.headersIndex = f.headers_index || 1;
this.headersIndex = defaultsNb(f.headers_index, 1);
/**
* ID of main container element
* @type {String}
*/
this.contElTgtId = f.container_target_id || null;
this.contElTgtId = defaultsStr(f.container_target_id, null);
/**
* Alternative text for column headers in column manager UI
* @type {Array}
*/
this.headersText = f.headers_text || null;
this.headersText = defaultsArr(f.headers_text, []);
/**
* ID of button's container element
* @type {String}
*/
this.btnTgtId = f.btn_target_id || null;
this.btnTgtId = defaultsStr(f.btn_target_id, null);
/**
* Button's text, defaults to Columns&#9660;
* @type {String}
*/
this.btnText = f.btn_text || 'Columns&#9660;';
this.btnText = defaultsStr(f.btn_text, 'Columns&#9660;');
/**
* Button's inner HTML
* @type {String}
*/
this.btnHtml = f.btn_html || null;
this.btnHtml = defaultsStr(f.btn_html, null);
/**
* Css class for button
* @type {String}
*/
this.btnCssClass = f.btn_css_class || 'colVis';
this.btnCssClass = defaultsStr(f.btn_css_class, 'colVis');
/**
* Columns manager UI close link text, defaults to 'Close'
* @type {String}
*/
this.btnCloseText = f.btn_close_text || 'Close';
this.btnCloseText = defaultsStr(f.btn_close_text, 'Close');
/**
* Columns manager UI close link HTML
* @type {String}
*/
this.btnCloseHtml = f.btn_close_html || null;
this.btnCloseHtml = defaultsStr(f.btn_close_html, null);
/**
* Css for columns manager UI close link
* @type {String}
*/
this.btnCloseCssClass = f.btn_close_css_class || this.btnCssClass;
this.btnCloseCssClass = defaultsStr(f.btn_close_css_class,
this.btnCssClass);
/**
* Extension's stylesheet filename
* @type {String}
*/
this.stylesheet = f.stylesheet || 'colsVisibility.css';
this.stylesheet = defaultsStr(f.stylesheet, 'colsVisibility.css');
/**
* Css for columns manager UI span
* @type {String}
*/
this.spanCssClass = f.span_css_class || 'colVisSpan';
this.spanCssClass = defaultsStr(f.span_css_class, 'colVisSpan');
/**
* Css for columns manager UI main container
* @type {String}
*/
this.contCssClass = f.cont_css_class || 'colVisCont';
this.contCssClass = defaultsStr(f.cont_css_class, 'colVisCont');
/**
* Css for columns manager UI checklist (ul)
* @type {String}
*/
this.listCssClass = cfg.list_css_class || 'cols_checklist';
this.listCssClass = defaultsStr(cfg.list_css_class, 'cols_checklist');
/**
* Css for columns manager UI checklist item (li)
* @type {String}
*/
this.listItemCssClass = cfg.checklist_item_css_class ||
'cols_checklist_item';
this.listItemCssClass = defaultsStr(cfg.checklist_item_css_class,
'cols_checklist_item');
/**
* Css for columns manager UI checklist item selected state (li)
* @type {String}
*/
this.listSlcItemCssClass = cfg.checklist_selected_item_css_class ||
'cols_checklist_slc_item';
this.listSlcItemCssClass = defaultsStr(
cfg.checklist_selected_item_css_class,
'cols_checklist_slc_item'
);
/**
* Text preceding the columns list, defaults to 'Hide' or 'Show'
* depending on tick mode (tick_to_hide option)
* @type {String}
*/
this.text = f.text || (this.tickToHide ? 'Hide: ' : 'Show: ');
this.text = defaultsStr(f.text, this.tickToHide ? 'Hide: ' : 'Show: ');
/**
* List of columns indexes to be hidden at initialization
* @type {Array}
*/
this.atStart = f.at_start || [];
this.atStart = defaultsArr(f.at_start, []);
/**
* Enable hover behaviour on columns manager button/link
@ -198,7 +206,13 @@ export default class ColsVisibility extends Feature {
* Text for select all option, defaults to 'Select all:'
* @type {String}
*/
this.tickAllText = f.tick_all_text || 'Select all:';
this.tickAllText = defaultsStr(f.tick_all_text, 'Select all:');
/**
* Default position in toolbar ('left'|'center'|'right')
* @type {String}
*/
this.toolbarPosition = defaultsStr(f.toolbar_position, RIGHT);
/**
* List of indexes of hidden columns
@ -216,73 +230,66 @@ export default class ColsVisibility extends Feature {
* Callback fired when the extension is initialized
* @type {Function}
*/
this.onLoaded = isFn(f.on_loaded) ? f.on_loaded : EMPTY_FN;
this.onLoaded = defaultsFn(f.on_loaded, EMPTY_FN);
/**
* Callback fired before the columns manager is opened
* @type {Function}
*/
this.onBeforeOpen = isFn(f.on_before_open) ?
f.on_before_open : EMPTY_FN;
this.onBeforeOpen = defaultsFn(f.on_before_open, EMPTY_FN);
/**
* Callback fired after the columns manager is opened
* @type {Function}
*/
this.onAfterOpen = isFn(f.on_after_open) ? f.on_after_open : EMPTY_FN;
this.onAfterOpen = defaultsFn(f.on_after_open, EMPTY_FN);
/**
* Callback fired before the columns manager is closed
* @type {Function}
*/
this.onBeforeClose = isFn(f.on_before_close) ?
f.on_before_close : EMPTY_FN;
this.onBeforeClose = defaultsFn(f.on_before_close, EMPTY_FN);
/**
* Callback fired after the columns manager is closed
* @type {Function}
*/
this.onAfterClose = isFn(f.on_after_close) ?
f.on_after_close : EMPTY_FN;
this.onAfterClose = defaultsFn(f.on_after_close, EMPTY_FN);
/**
* Callback fired before a column is hidden
* @type {Function}
*/
this.onBeforeColHidden = isFn(f.on_before_col_hidden) ?
f.on_before_col_hidden : EMPTY_FN;
this.onBeforeColHidden = defaultsFn(f.on_before_col_hidden, EMPTY_FN);
/**
* Callback fired after a column is hidden
* @type {Function}
*/
this.onAfterColHidden = isFn(f.on_after_col_hidden) ?
f.on_after_col_hidden : EMPTY_FN;
this.onAfterColHidden = defaultsFn(f.on_after_col_hidden, EMPTY_FN);
/**
* Callback fired before a column is displayed
* @type {Function}
*/
this.onBeforeColDisplayed = isFn(f.on_before_col_displayed) ?
f.on_before_col_displayed : EMPTY_FN;
this.onBeforeColDisplayed = defaultsFn(f.on_before_col_displayed,
EMPTY_FN);
/**
* Callback fired after a column is displayed
* @type {Function}
*/
this.onAfterColDisplayed = isFn(f.on_after_col_displayed) ?
f.on_after_col_displayed : EMPTY_FN;
this.onAfterColDisplayed = defaultsFn(f.on_after_col_displayed,
EMPTY_FN);
//Grid layout support
if (tf.gridLayout) {
this.headersTbl = tf.feature('gridLayout').headTbl; //headers table
this.headersIndex = 0; //headers index
this.onAfterColDisplayed = function () { };
this.onAfterColHidden = function () { };
}
//Loads extension stylesheet
tf.import(f.name + 'Style', tf.stylePath + this.stylesheet, null,
tf.import(f.name + 'Style', tf.getStylePath() + this.stylesheet, null,
'link');
this.enable();
@ -324,7 +331,7 @@ export default class ColsVisibility extends Feature {
}
this.contEl.style.display = contDisplay === 'inline' ?
'none' : 'inline';
NONE : 'inline';
if (contDisplay !== 'inline') {
this.onAfterOpen(this);
@ -369,6 +376,9 @@ export default class ColsVisibility extends Feature {
return;
}
this.emitter.emit('initializing-extension', this,
!isNull(this.btnTgtId));
this.emitter.on(['hide-column'],
(tf, colIndex) => this.hideCol(colIndex));
@ -381,6 +391,7 @@ export default class ColsVisibility extends Feature {
this.boundMouseup = this.onMouseup.bind(this);
this.emitter.emit('columns-visibility-initialized', this.tf, this);
this.emitter.emit('extension-initialized', this);
// Hide columns at start at very end of initialization, do not move
// as order is important
@ -398,11 +409,10 @@ export default class ColsVisibility extends Feature {
let span = createElm('span');
span.className = this.spanCssClass;
//Container element (rdiv or custom element)
if (!this.btnTgtId) {
tf.setToolbar();
}
let targetEl = !this.btnTgtId ? tf.rDiv : elm(this.btnTgtId);
// Container element (rdiv or custom element)
let targetEl = !this.btnTgtId ?
tf.feature('toolbar').container(this.toolbarPosition) :
elm(this.btnTgtId);
if (!this.btnTgtId) {
let firstChild = targetEl.firstChild;
@ -423,7 +433,7 @@ export default class ColsVisibility extends Feature {
} else {
addEvt(btn, 'mouseover', (evt) => this.toggle(evt));
}
} else { //Custom html
} else { // Custom html
span.innerHTML = this.btnHtml;
let colVisEl = span.firstChild;
if (!this.enableHover) {
@ -459,7 +469,7 @@ export default class ColsVisibility extends Feature {
let ul = createElm('ul');
ul.className = this.listCssClass;
let tbl = this.headersTbl ? this.headersTbl : tf.tbl;
let tbl = this.headersTbl || tf.dom();
let headerIndex = this.headersTbl ?
this.headersIndex : tf.getHeadersRowIndex();
let headerRow = tbl.rows[headerIndex];
@ -485,8 +495,7 @@ export default class ColsVisibility extends Feature {
for (let i = 0; i < headerRow.cells.length; i++) {
let cell = headerRow.cells[i];
let cellText = this.headersText && this.headersText[i] ?
this.headersText[i] : this._getHeaderText(cell);
let cellText = this.headersText[i] || this._getHeaderText(cell);
let liElm = createCheckItem('col_' + i + '_' + tf.id, cellText,
cellText);
addClass(liElm, this.listItemCssClass);
@ -535,18 +544,17 @@ export default class ColsVisibility extends Feature {
*/
setHidden(colIndex, hide) {
let tf = this.tf;
let tbl = tf.tbl;
let tbl = tf.dom();
if (hide) {
this.onBeforeColHidden(this, colIndex);
}
if (!hide) {
} else {
this.onBeforeColDisplayed(this, colIndex);
}
this._hideCells(tbl, colIndex, hide);
this._hideElements(tbl, colIndex, hide);
if (this.headersTbl) {
this._hideCells(this.headersTbl, colIndex, hide);
this._hideElements(this.headersTbl, colIndex, hide);
}
let hiddenCols = this.hiddenCols;
@ -561,46 +569,11 @@ export default class ColsVisibility extends Feature {
}
}
let gridLayout;
let headTbl;
let gridColElms;
if (hide) {
//This event is fired just after a column is displayed for
//grid_layout support
//TODO: grid layout module should be responsible for those
//calculations
if (tf.gridLayout) {
gridLayout = tf.feature('gridLayout');
headTbl = gridLayout.headTbl;
gridColElms = gridLayout.colElms;
let hiddenWidth = parseInt(
gridColElms[colIndex].style.width, 10);
let headTblW = parseInt(headTbl.style.width, 10);
headTbl.style.width = headTblW - hiddenWidth + 'px';
tbl.style.width = headTbl.style.width;
}
this.onAfterColHidden(this, colIndex);
this.emitter.emit('column-hidden', tf, this, colIndex,
this.hiddenCols);
}
if (!hide) {
//This event is fired just after a column is displayed for
//grid_layout support
//TODO: grid layout module should be responsible for those
//calculations
if (tf.gridLayout) {
gridLayout = tf.feature('gridLayout');
headTbl = gridLayout.headTbl;
gridColElms = gridLayout.colElms;
let width = parseInt(gridColElms[colIndex].style.width, 10);
headTbl.style.width =
(parseInt(headTbl.style.width, 10) + width) + 'px';
tf.tbl.style.width = headTbl.style.width;
}
} else {
this.onAfterColDisplayed(this, colIndex);
this.emitter.emit('column-shown', tf, this, colIndex,
this.hiddenCols);
@ -612,7 +585,7 @@ export default class ColsVisibility extends Feature {
* @param {Number} colIndex Column index
*/
showCol(colIndex) {
if (colIndex === undefined || !this.isColHidden(colIndex)) {
if (isUndef(colIndex) || !this.isColHidden(colIndex)) {
return;
}
if (this.manager && this.contEl) {
@ -630,7 +603,7 @@ export default class ColsVisibility extends Feature {
* @param {Number} colIndex Column index
*/
hideCol(colIndex) {
if (colIndex === undefined || this.isColHidden(colIndex)) {
if (isUndef(colIndex) || this.isColHidden(colIndex)) {
return;
}
if (this.manager && this.contEl) {
@ -659,7 +632,7 @@ export default class ColsVisibility extends Feature {
* @param {Number} colIndex Column index
*/
toggleCol(colIndex) {
if (colIndex === undefined || this.isColHidden(colIndex)) {
if (isUndef(colIndex) || this.isColHidden(colIndex)) {
this.showCol(colIndex);
} else {
this.hideCol(colIndex);
@ -721,16 +694,29 @@ export default class ColsVisibility extends Feature {
return '';
}
_hideCells(tbl, colIndex, hide) {
_hideElements(tbl, colIdx, hide) {
this._hideCells(tbl, colIdx, hide);
this._hideCol(tbl, colIdx, hide);
}
_hideCells(tbl, colIdx, hide) {
for (let i = 0; i < tbl.rows.length; i++) {
let row = tbl.rows[i];
let cell = row.cells[colIndex];
let cell = row.cells[colIdx];
if (cell) {
cell.style.display = hide ? 'none' : '';
cell.style.display = hide ? NONE : '';
}
}
}
_hideCol(tbl, colIdx, hide) {
let colElms = tag(tbl, 'col');
if (colElms.length === 0) {
return;
}
colElms[colIdx].style.display = hide ? NONE : '';
}
_hideAtStart() {
this.atStart.forEach((colIdx) => {
this.hideCol(colIdx);

View file

@ -1,7 +1,11 @@
import {Feature} from '../../feature';
import {createElm, removeElm, elm} from '../../dom';
import {isFn, isUndef, EMPTY_FN} from '../../types';
import {EMPTY_FN, isNull} from '../../types';
import {addEvt} from '../../event';
import {
defaultsBool, defaultsStr, defaultsFn, defaultsNb,
} from '../../settings';
import {RIGHT} from '../../modules/toolbar';
/**
* Filters Visibility extension
@ -14,7 +18,7 @@ export default class FiltersVisibility extends Feature {
* @param {Object} Configuration object
*/
constructor(tf, f) {
super(tf, f.name);
super(tf, FiltersVisibility);
/**
* Module name
@ -26,25 +30,26 @@ export default class FiltersVisibility extends Feature {
* Module description
* @type {String}
*/
this.desc = f.description || 'Filters row visibility manager';
this.desc = defaultsStr(f.description,
'Filters row visibility manager');
/**
* Extension's stylesheet filename
* @type {String}
*/
this.stylesheet = f.stylesheet || 'filtersVisibility.css';
this.stylesheet = defaultsStr(f.stylesheet , 'filtersVisibility.css');
/**
* Expand icon filename
* @type {String}
*/
this.icnExpand = f.expand_icon_name || 'icn_exp.png';
this.icnExpand = defaultsStr(f.expand_icon_name, 'icn_exp.png');
/**
* Collapse icon filename
* @type {String}
*/
this.icnCollapse = f.collapse_icon_name || 'icn_clp.png';
this.icnCollapse = defaultsStr(f.collapse_icon_name, 'icn_clp.png');
/**
* Main container element
@ -88,13 +93,13 @@ export default class FiltersVisibility extends Feature {
* Enable expand/collapse icon, defaults to true
* @type {Boolean}
*/
this.enableIcon = f.enable_icon === false ? false : true;
this.enableIcon = defaultsBool(f.enable_icon, true);
/**
* Custom text for button
* @type {String}
*/
this.btnText = f.btn_text || '';
this.btnText = defaultsStr(f.btn_text, '');
/**
* Collapse button HTML
@ -116,62 +121,65 @@ export default class FiltersVisibility extends Feature {
* Button's custom HTML
* @type {String}
*/
this.btnHtml = f.btn_html || null;
this.btnHtml = defaultsStr(f.btn_html, null);
/**
* Css class for expand/collapse filters button
* @type {String}
*/
this.btnCssClass = f.btn_css_class || 'btnExpClpFlt';
this.btnCssClass = defaultsStr(f.btn_css_class, 'btnExpClpFlt');
/**
* Css class for main container
* @type {String}
*/
this.contCssClass = f.cont_css_class || 'expClpFlt';
this.contCssClass = defaultsStr(f.cont_css_class, 'expClpFlt');
/**
* Filters row index
* @type {Number}
*/
this.filtersRowIndex = !isUndef(f.filters_row_index) ?
f.filters_row_index : tf.getFiltersRowIndex();
this.filtersRowIndex = defaultsNb(f.filters_row_index,
tf.getFiltersRowIndex());
/**
* Make filters visible at initialization, defaults to true
* @type {Boolean}
*/
this.visibleAtStart = !isUndef(f.visible_at_start) ?
Boolean(f.visible_at_start) : true;
this.visibleAtStart = defaultsNb(f.visible_at_start, true);
/**
* Default position in toolbar ('left'|'center'|'right')
* @type {String}
*/
this.toolbarPosition = defaultsStr(f.toolbar_position, RIGHT);
/**
* Callback fired before filters row is shown
* @type {Function}
*/
this.onBeforeShow = isFn(f.on_before_show) ?
f.on_before_show : EMPTY_FN;
this.onBeforeShow = defaultsFn(f.on_before_show, EMPTY_FN);
/**
* Callback fired after filters row is shown
* @type {Function}
*/
this.onAfterShow = isFn(f.on_after_show) ? f.on_after_show : EMPTY_FN;
this.onAfterShow = defaultsFn(f.on_after_show, EMPTY_FN);
/**
* Callback fired before filters row is hidden
* @type {Function}
*/
this.onBeforeHide = isFn(f.on_before_hide) ?
f.on_before_hide : EMPTY_FN;
this.onBeforeHide = defaultsFn(f.on_before_hide, EMPTY_FN);
/**
* Callback fired after filters row is hidden
* @type {Function}
*/
this.onAfterHide = isFn(f.on_after_hide) ? f.on_after_hide : EMPTY_FN;
this.onAfterHide = defaultsFn(f.on_after_hide, EMPTY_FN);
//Import extension's stylesheet
tf.import(f.name + 'Style', tf.stylePath + this.stylesheet, null,
tf.import(f.name + 'Style', tf.getStylePath() + this.stylesheet, null,
'link');
this.enable();
@ -185,15 +193,17 @@ export default class FiltersVisibility extends Feature {
return;
}
this.emitter.emit('initializing-extension', this,
!isNull(this.targetId));
this.buildUI();
/**
* @inherited
*/
/** @inherited */
this.initialized = true;
this.emitter.on(['show-filters'], (tf, visible) => this.show(visible));
this.emitter.emit('filters-visibility-initialized', this.tf, this);
this.emitter.emit('extension-initialized', this);
}
/**
@ -204,11 +214,10 @@ export default class FiltersVisibility extends Feature {
let span = createElm('span');
span.className = this.contCssClass;
//Container element (rdiv or custom element)
if (!this.targetId) {
tf.setToolbar();
}
let targetEl = !this.targetId ? tf.rDiv : elm(this.targetId);
// Container element (rdiv or custom element)
let targetEl = !this.targetId ?
tf.feature('toolbar').container(this.toolbarPosition) :
elm(this.targetId);
if (!this.targetId) {
let firstChild = targetEl.firstChild;
@ -224,7 +233,7 @@ export default class FiltersVisibility extends Feature {
btn.title = this.btnText || this.defaultText;
btn.innerHTML = this.collapseBtnHtml;
span.appendChild(btn);
} else { //Custom html
} else { // Custom html
span.innerHTML = this.btnHtml;
btn = span.firstChild;
}
@ -244,7 +253,7 @@ export default class FiltersVisibility extends Feature {
*/
toggle() {
let tf = this.tf;
let tbl = tf.gridLayout ? tf.feature('gridLayout').headTbl : tf.tbl;
let tbl = tf.gridLayout ? tf.feature('gridLayout').headTbl : tf.dom();
let fltRow = tbl.rows[this.filtersRowIndex];
let isDisplayed = fltRow.style.display === '';
@ -258,7 +267,7 @@ export default class FiltersVisibility extends Feature {
*/
show(visible = true) {
let tf = this.tf;
let tbl = tf.gridLayout ? tf.feature('gridLayout').headTbl : tf.tbl;
let tbl = tf.gridLayout ? tf.feature('gridLayout').headTbl : tf.dom();
let fltRow = tbl.rows[this.filtersRowIndex];
if (visible) {

View file

@ -1,12 +1,13 @@
import {Feature} from '../../feature';
import {isArray, isFn, isUndef, isObj, EMPTY_FN} from '../../types';
import {createElm, elm, getText, tag} from '../../dom';
import {addEvt} from '../../event';
import {isUndef, isObj, EMPTY_FN} from '../../types';
import {createElm, elm, tag} from '../../dom';
import {addEvt, bound} from '../../event';
import {parse as parseNb} from '../../number';
import {
NONE, CELL_TAG, HEADER_TAG, STRING, NUMBER, DATE, FORMATTED_NUMBER,
IP_ADDRESS
} from '../../const';
import {defaultsStr, defaultsFn, defaultsArr} from '../../settings';
/**
* SortableTable Adapter module
@ -19,7 +20,7 @@ export default class AdapterSortableTable extends Feature {
* @param {Object} opts Configuration object
*/
constructor(tf, opts) {
super(tf, opts.name);
super(tf, AdapterSortableTable);
/**
* Module name
@ -31,7 +32,7 @@ export default class AdapterSortableTable extends Feature {
* Module description
* @type {String}
*/
this.desc = opts.description || 'Sortable table';
this.desc = defaultsStr(opts.description, 'Sortable table');
/**
* Indicate whether table previously sorted
@ -44,15 +45,14 @@ export default class AdapterSortableTable extends Feature {
* List of sort type per column basis
* @type {Array}
*/
this.sortTypes = isArray(opts.types) ? opts.types : tf.colTypes;
this.sortTypes = defaultsArr(opts.types, tf.colTypes);
/**
* Column to be sorted at initialization, ie:
* sort_col_at_start: [1, true]
* @type {Array}
*/
this.sortColAtStart = isArray(opts.sort_col_at_start) ?
opts.sort_col_at_start : null;
this.sortColAtStart = defaultsArr(opts.sort_col_at_start, null);
/**
* Enable asynchronous sort, if triggers are external
@ -64,7 +64,7 @@ export default class AdapterSortableTable extends Feature {
* List of element IDs triggering sort on a per column basis
* @type {Array}
*/
this.triggerIds = isArray(opts.trigger_ids) ? opts.trigger_ids : [];
this.triggerIds = defaultsArr(opts.trigger_ids, []);
// edit .sort-arrow.descending / .sort-arrow.ascending in
// tablefilter.css to reflect any path change
@ -72,58 +72,57 @@ export default class AdapterSortableTable extends Feature {
* Path to images
* @type {String}
*/
this.imgPath = opts.images_path || tf.themesPath;
this.imgPath = defaultsStr(opts.images_path, tf.themesPath);
/**
* Blank image file name
* @type {String}
*/
this.imgBlank = opts.image_blank || 'blank.png';
this.imgBlank = defaultsStr(opts.image_blank, 'blank.png');
/**
* Css class for sort indicator image
* @type {String}
*/
this.imgClassName = opts.image_class_name || 'sort-arrow';
this.imgClassName = defaultsStr(opts.image_class_name, 'sort-arrow');
/**
* Css class for ascending sort indicator image
* @type {String}
*/
this.imgAscClassName = opts.image_asc_class_name || 'ascending';
this.imgAscClassName = defaultsStr(opts.image_asc_class_name,
'ascending');
/**
* Css class for descending sort indicator image
* @type {String}
*/
this.imgDescClassName = opts.image_desc_class_name || 'descending';
this.imgDescClassName = defaultsStr(opts.image_desc_class_name,
'descending');
/**
* Cell attribute key storing custom value used for sorting
* @type {String}
*/
this.customKey = opts.custom_key || 'data-tf-sortKey';
this.customKey = defaultsStr(opts.custom_key, 'data-tf-sortKey');
/**
* Callback fired when sort extension is instanciated
* @type {Function}
*/
this.onSortLoaded = isFn(opts.on_sort_loaded) ?
opts.on_sort_loaded : EMPTY_FN;
this.onSortLoaded = defaultsFn(opts.on_sort_loaded, EMPTY_FN);
/**
* Callback fired before a table column is sorted
* @type {Function}
*/
this.onBeforeSort = isFn(opts.on_before_sort) ?
opts.on_before_sort : EMPTY_FN;
this.onBeforeSort = defaultsFn(opts.on_before_sort, EMPTY_FN);
/**
* Callback fired after a table column is sorted
* @type {Function}
*/
this.onAfterSort = isFn(opts.on_after_sort) ?
opts.on_after_sort : EMPTY_FN;
this.onAfterSort = defaultsFn(opts.on_after_sort, EMPTY_FN);
/**
* SortableTable instance
@ -190,8 +189,7 @@ export default class AdapterSortableTable extends Feature {
this.stt.sort(sortColAtStart[0], sortColAtStart[1]);
}
this.emitter.on(['sort'],
(tf, colIdx, desc) => this.sortByColumnIndex(colIdx, desc));
this.emitter.on(['sort'], bound(this.sortByColumnIndexHandler, this));
/** @inherited */
this.initialized = true;
@ -208,6 +206,11 @@ export default class AdapterSortableTable extends Feature {
this.stt.sort(colIdx, desc);
}
/** @private */
sortByColumnIndexHandler(tf, colIdx, desc) {
this.sortByColumnIndex(colIdx, desc);
}
/**
* Set SortableTable overrides for TableFilter integration
*/
@ -358,17 +361,17 @@ export default class AdapterSortableTable extends Feature {
/**
* Overrides getInnerText in order to avoid Firefox unexpected sorting
* behaviour with untrimmed text elements
* @param {Object} oNode DOM element
* @param {Object} cell DOM element
* @return {String} DOM element inner text
*/
SortableTable.getInnerText = function (oNode) {
if (!oNode) {
SortableTable.getInnerText = function (cell) {
if (!cell) {
return;
}
if (oNode.getAttribute(adpt.customKey)) {
return oNode.getAttribute(adpt.customKey);
if (cell.getAttribute(adpt.customKey)) {
return cell.getAttribute(adpt.customKey);
} else {
return getText(oNode);
return tf.getCellValue(cell);
}
};
}
@ -378,8 +381,8 @@ export default class AdapterSortableTable extends Feature {
*/
addSortType(...args) {
// Extract the arguments
let [id, caster, sorter] = args;
SortableTable.prototype.addSortType(id, caster, sorter);
let [id, caster, sorter, getRowValue] = args;
SortableTable.prototype.addSortType(id, caster, sorter, getRowValue);
}
/**
@ -391,7 +394,7 @@ export default class AdapterSortableTable extends Feature {
sortTypes = this.sortTypes,
_sortTypes = [];
for (let i = 0; i < tf.nbCells; i++) {
tf.eachCol((i) => {
let colType;
if (sortTypes[i]) {
colType = sortTypes[i];
@ -421,7 +424,7 @@ export default class AdapterSortableTable extends Feature {
colType = STRING;
}
_sortTypes.push(colType);
}
});
//Public TF method to add sort type
@ -430,7 +433,7 @@ export default class AdapterSortableTable extends Feature {
this.addSortType(STRING);
this.addSortType(IP_ADDRESS, ipAddress, sortIP);
this.stt = new SortableTable(tf.tbl, _sortTypes);
this.stt = new SortableTable(tf.dom(), _sortTypes);
/*** external table headers adapter ***/
if (this.asyncSort && this.triggerIds.length > 0) {
@ -487,8 +490,7 @@ export default class AdapterSortableTable extends Feature {
return;
}
let tf = this.tf;
this.emitter.off(['sort'],
(tf, colIdx, desc) => this.sortByColumnIndex(colIdx, desc));
this.emitter.off(['sort'], bound(this.sortByColumnIndexHandler, this));
this.sorted = false;
this.stt.destroy();
@ -506,9 +508,12 @@ export default class AdapterSortableTable extends Feature {
}
AdapterSortableTable.meta = {altName: 'sort'};
//Converters
function ipAddress(value) {
let vals = value.split('.');
// eslint-disable-next-line no-unused-vars
for (let x in vals) {
let val = vals[x];
while (3 > val.length) {

View file

@ -1,5 +1,6 @@
import {toCamelCase} from './string';
const NOTIMPLEMENTED = 'Not implemented.';
const NOT_IMPLEMENTED = 'Not implemented.';
/**
* Base class defining the interface of a TableFilter feature
@ -8,9 +9,11 @@ export class Feature {
/**
* Creates an instance of Feature
* @param {Object} tf TableFilter instance
* @param {String} feature Feature name known by TableFilter
* @param {Class} feature Feature class for TableFilter registration
*/
constructor(tf, feature) {
constructor(tf, cls) {
cls.meta = cls.meta || {};
/**
* TableFilter instance
* @type {TableFilter}
@ -18,16 +21,18 @@ export class Feature {
this.tf = tf;
/**
* Feature name
* Feature name is the camelised class name as per TableFilter's
* convention
* @type {String}
*/
this.feature = feature;
this.feature = cls.meta.altName || cls.meta.name
|| toCamelCase(cls.name);
/**
* TableFilter feature setting
* @type {Boolean}
*/
this.enabled = tf[feature];
this.enabled = tf[this.feature];
/**
* TableFilter configuration
@ -55,7 +60,7 @@ export class Feature {
* Initialize the feature
*/
init() {
throw new Error(NOTIMPLEMENTED);
throw new Error(NOT_IMPLEMENTED);
}
/**
@ -70,7 +75,7 @@ export class Feature {
* Destroy the feature
*/
destroy() {
throw new Error(NOTIMPLEMENTED);
throw new Error(NOT_IMPLEMENTED);
}
/**
@ -92,6 +97,6 @@ export class Feature {
* @returns {Boolean}
*/
isEnabled() {
return this.enabled;
return this.enabled === true;
}
}

View file

@ -1,5 +1,7 @@
import {Feature} from '../feature';
import {addClass, removeClass} from '../dom';
import {defaultsStr} from '../settings';
import {bound} from '../event';
/**
* Rows with alternating background color for improved readability
@ -12,20 +14,21 @@ export class AlternateRows extends Feature {
* @param {Object} tf TableFilter instance
*/
constructor(tf) {
super(tf, 'alternateRows');
super(tf, AlternateRows);
let config = this.config;
/**
* Css class for even rows (default: 'even')
* @type {String}
*/
this.evenCss = config.even_row_css_class || 'even';
this.evenCss = defaultsStr(config.even_row_css_class, 'even');
/**
* Css class for odd rows (default: 'odd')
* @type {String}
*/
this.oddCss = config.odd_row_css_class || 'odd';
this.oddCss = defaultsStr(config.odd_row_css_class, 'odd');
}
/**
@ -40,10 +43,9 @@ export class AlternateRows extends Feature {
// Subscribe to events
this.emitter.on(['row-processed', 'row-paged'],
(tf, rowIndex, arrIndex, isValid) =>
this.processRow(rowIndex, arrIndex, isValid));
this.emitter.on(['column-sorted'], () => this.processAll());
this.emitter.on(['rows-changed'], () => this.processAll());
bound(this.processRowHandler, this));
this.emitter.on(['column-sorted', 'rows-changed'],
bound(this.processAll, this));
/** @inherited */
this.initialized = true;
@ -94,7 +96,7 @@ export class AlternateRows extends Feature {
if (!this.isEnabled() || isNaN(rowIdx)) {
return;
}
let rows = this.tf.tbl.rows;
let rows = this.tf.dom().rows;
let i = isNaN(idx) ? rowIdx : idx;
this.removeRowBg(rowIdx);
@ -110,11 +112,16 @@ export class AlternateRows extends Feature {
if (isNaN(idx)) {
return;
}
let rows = this.tf.tbl.rows;
let rows = this.tf.dom().rows;
removeClass(rows[idx], this.oddCss);
removeClass(rows[idx], this.evenCss);
}
/** @private */
processRowHandler(tf, rowIndex, arrIndex, isValid) {
this.processRow(rowIndex, arrIndex, isValid);
}
/**
* Removes all alternating backgrounds
*/
@ -122,17 +129,15 @@ export class AlternateRows extends Feature {
if (!this.initialized) {
return;
}
let nbRows = this.tf.getRowsNb(true);
for (let i = 0; i < nbRows; i++) {
this.removeRowBg(i);
}
let eachRow = this.tf.eachRow(0);
eachRow((row, i) => this.removeRowBg(i));
// Unsubscribe to events
this.emitter.off(['row-processed', 'row-paged'],
(tf, rowIndex, arrIndex, isValid) =>
this.processRow(rowIndex, arrIndex, isValid));
this.emitter.off(['column-sorted'], () => this.processAll());
this.emitter.off(['rows-changed'], () => this.processAll());
bound(this.processRowHandler, this));
this.emitter.off(['column-sorted', 'rows-changed'],
bound(this.processAll, this));
this.initialized = false;
}

160
src/modules/baseDropdown.js Normal file
View file

@ -0,0 +1,160 @@
import {Feature} from '../feature';
import {
ignoreCase, numSortAsc, numSortDesc,
dateSortAsc, dateSortDesc, sortNumberStr, sortDateStr
} from '../sort';
import {isArray, isObj, isEmpty} from '../types';
import {NUMBER, FORMATTED_NUMBER, DATE} from '../const';
/**
* Base class for Dropdown and CheckList UI components
* @export
* @class BaseDropdown
* @extends {Feature}
*/
export class BaseDropdown extends Feature {
/**
* Creates an instance of BaseDropdown
* @param {TableFilter} tf
*/
constructor(tf, cls) {
super(tf, cls);
let f = this.config;
/**
* Filter options custom sorter on a column basis
* @type {Object}
*/
this.customSorter = isObj(f.filter_options_sorter) &&
isArray(f.filter_options_sorter.col) &&
isArray(f.filter_options_sorter.comparer) ?
f.filter_options_sorter :
null;
// TODO: move here all properties shared by Dropdown and CheckList
/**
* Has custom options
* @type {Boolean}
* @private
*/
this.isCustom = false;
/**
* List of options values
* @type {Array}
* @private
*/
this.opts = [];
/**
* List of options texts for custom values
* @type {Array}
* @private
*/
this.optsTxt = [];
/**
* List of options to be excluded from the checklist filter
* @type {Array}
* @private
*/
this.excludedOpts = [];
}
/**
* Sort passed options based on the type of the specified column
* @param {Number} colIndex Column index
* @param {Array} [options=[]] Collection of values
* @return {Array} Sorted values
* @private
*/
sortOptions(colIndex, options = []) {
let {tf} = this;
if (tf.isCustomOptions(colIndex) || !tf.sortSlc ||
(isArray(tf.sortSlc) && tf.sortSlc.indexOf(colIndex) === -1)) {
return options;
}
let { caseSensitive, sortFilterOptionsDesc } = tf;
let isSortDesc = sortFilterOptionsDesc.indexOf(colIndex) !== -1;
let compareFn;
if (this.customSorter &&
this.customSorter.col.indexOf(colIndex) !== -1) {
var idx = this.customSorter.col.indexOf(colIndex);
compareFn = this.customSorter.comparer[idx];
}
else if (tf.hasType(colIndex, [NUMBER, FORMATTED_NUMBER])) {
let decimal = tf.getDecimal(colIndex);
let comparer = isSortDesc ? numSortDesc : numSortAsc;
compareFn = sortNumberStr(comparer, decimal);
}
else if (tf.hasType(colIndex, [DATE])) {
let locale = tf.feature('dateType').getLocale(colIndex);
let comparer = isSortDesc ? dateSortDesc : dateSortAsc;
compareFn = sortDateStr(comparer, locale);
} else { // string
compareFn = caseSensitive ? undefined : ignoreCase;
if (isSortDesc) {
return options.sort(compareFn).reverse();
}
}
return options.sort(compareFn);
}
/**
* Regenerate filters of specified columns and maintain selection if any
* @param {Array} colIndexes Collection of column indexes
* @private
*/
refreshFilters(colIndexes) {
colIndexes.forEach((colIdx) => {
let values = this.getValues(colIdx);
this.build(colIdx, this.tf.linkedFilters);
this.selectOptions(colIdx, values);
});
}
/**
* Check passed row contains a valid linked value
* @param {Number} rowIdx Row index
* @param {Number} activeFilterIdx Current active filter index
* @returns {Boolean}
*/
isValidLinkedValue(rowIdx, activeFilterIdx) {
let tf = this.tf;
if (tf.disableExcludedOptions) {
return true;
}
if (tf.paging) {
if (!isEmpty(activeFilterIdx) && tf.isRowValid(rowIdx)) {
return true;
}
} else {
if (tf.isRowDisplayed(rowIdx)) {
return true;
}
}
return false;
}
/**
* Refresh linked filters to offer only selected options
*/
linkFilters() {
let tf = this.tf;
if (!tf.linkedFilters || !tf.activeFilterId) {
return;
}
this.refreshAll();
}
}

View file

@ -1,29 +1,28 @@
import {Feature} from '../feature';
import {BaseDropdown} from './baseDropdown';
import {
addClass, createCheckItem, createText, createElm, elm, getText,
removeClass, tag
addClass, createCheckItem, createText, createElm, elm, removeClass, tag
} from '../dom';
import {has} from '../array';
import {matchCase, trim, rgxEsc} from '../string';
import {ignoreCase, numSortAsc, numSortDesc} from '../sort';
import {addEvt, removeEvt, targetEvt} from '../event';
import {isEmpty} from '../types';
import {CHECKLIST, NONE} from '../const';
const SORT_ERROR = 'Filter options for column {0} cannot be sorted in ' +
'{1} manner.';
import {defaultsStr, defaultsBool} from '../settings';
/**
* Checklist filter UI component
* @export
* @class CheckList
* @extends {BaseDropdown}
*/
export class CheckList extends Feature {
export class CheckList extends BaseDropdown {
/**
* Creates an instance of CheckList
* @param {TableFilter} tf TableFilter instance
*/
constructor(tf) {
super(tf, 'checkList');
super(tf, CheckList);
let f = this.config;
@ -37,48 +36,57 @@ export class CheckList extends Feature {
* Css class for the container of the checklist filter (div)
* @type {String}
*/
this.containerCssClass = f.div_checklist_css_class || 'div_checklist';
this.containerCssClass = defaultsStr(f.div_checklist_css_class,
'div_checklist');
/**
* Css class for the checklist filter element (ul)
* @type {String}
*/
this.filterCssClass = f.checklist_css_class || 'flt_checklist';
this.filterCssClass = defaultsStr(f.checklist_css_class,
'flt_checklist');
/**
* Css class for the item of a checklist (li)
* @type {String}
*/
this.itemCssClass = f.checklist_item_css_class || 'flt_checklist_item';
this.itemCssClass = defaultsStr(f.checklist_item_css_class,
'flt_checklist_item');
/**
* Css class for a selected item of a checklist (li)
* @type {String}
*/
this.selectedItemCssClass =
f.checklist_selected_item_css_class || 'flt_checklist_slc_item';
this.selectedItemCssClass = defaultsStr(
f.checklist_selected_item_css_class,
'flt_checklist_slc_item'
);
/**
* Text placed in the filter's container when load filter on demand
* feature is enabled
* @type {String}
*/
this.activateText =
f.activate_checklist_text || 'Click to load filter data';
this.activateText = defaultsStr(
f.activate_checklist_text,
'Click to load filter data'
);
/**
* Css class for a disabled item of a checklist (li)
* @type {String}
*/
this.disabledItemCssClass = f.checklist_item_disabled_css_class ||
'flt_checklist_item_disabled';
this.disabledItemCssClass = defaultsStr(
f.checklist_item_disabled_css_class,
'flt_checklist_item_disabled'
);
/**
* Enable the reset filter option as first item
* @type {Boolean}
*/
this.enableResetOption = f.enable_checklist_reset_filter === false ?
false : true;
this.enableResetOption = defaultsBool(f.enable_checklist_reset_filter,
true);
/**
* Prefix for container element ID
@ -86,34 +94,6 @@ export class CheckList extends Feature {
* @private
*/
this.prfx = 'chkdiv_';
/**
* Has custom options
* @type {Boolean}
* @private
*/
this.isCustom = false;
/**
* List of options values
* @type {Array}
* @private
*/
this.opts = [];
/**
* List of options texts for custom values
* @type {Array}
* @private
*/
this.optsTxt = [];
/**
* List of options to be excluded from the checklist filter
* @type {Array}
* @private
*/
this.excludedOpts = [];
}
/**
@ -126,7 +106,7 @@ export class CheckList extends Feature {
let tf = this.tf;
this.emitter.emit('filter-focus', tf, elm);
this.setCheckListValues(elm);
this.setItemOption(elm);
tf.filter();
}
@ -149,13 +129,8 @@ export class CheckList extends Feature {
* Refresh all checklist filters
*/
refreshAll() {
let tf = this.tf;
let fltsIdxs = tf.getFiltersByType(CHECKLIST, true);
fltsIdxs.forEach((colIdx) => {
let values = this.getValues(colIdx);
this.build(colIdx, tf.linkedFilters);
this.selectOptions(colIdx, values);
});
let colIdxs = this.tf.getFiltersByType(CHECKLIST, true);
this.refreshFilters(colIdxs);
}
/**
@ -167,7 +142,7 @@ export class CheckList extends Feature {
init(colIndex, isExternal, container) {
let tf = this.tf;
let externalFltTgtId = isExternal ?
tf.externalFltTgtIds[colIndex] : null;
tf.externalFltIds[colIndex] : null;
let divCont = createElm('div',
['id', `${this.prfx}${colIndex}_${tf.id}`],
@ -203,6 +178,8 @@ export class CheckList extends Feature {
this.emitter.on(['rows-changed'], () => this.refreshAll());
this.emitter.on(['after-filtering'], () => this.linkFilters());
/** @inherited */
this.initialized = true;
}
@ -214,11 +191,13 @@ export class CheckList extends Feature {
*/
build(colIndex, isLinked = false) {
let tf = this.tf;
colIndex = parseInt(colIndex, 10);
colIndex = Number(colIndex);
this.emitter.emit('before-populating-filter', tf, colIndex);
/** @inherited */
this.opts = [];
/** @inherited */
this.optsTxt = [];
let flt = this.containers[colIndex];
@ -227,71 +206,10 @@ export class CheckList extends Feature {
['colIndex', colIndex]);
ul.className = this.filterCssClass;
let rows = tf.tbl.rows;
let nbRows = tf.getRowsNb(true);
let caseSensitive = tf.caseSensitive;
/** @inherited */
this.isCustom = tf.isCustomOptions(colIndex);
let activeIdx;
let activeFilterId = tf.getActiveFilterId();
if (isLinked && activeFilterId) {
activeIdx = tf.getColumnIndexFromFilterId(activeFilterId);
}
let filteredDataCol = [];
if (isLinked && tf.disableExcludedOptions) {
this.excludedOpts = [];
}
flt.innerHTML = '';
for (let k = tf.refRow; k < nbRows; k++) {
// always visible rows don't need to appear on selects as always
// valid
if (tf.hasVisibleRows && tf.visibleRows.indexOf(k) !== -1) {
continue;
}
let cells = rows[k].cells;
let ncells = cells.length;
// checks if row has exact cell #
if (ncells !== tf.nbCells || this.isCustom) {
continue;
}
// this loop retrieves cell data
for (let j = 0; j < ncells; j++) {
if (colIndex !== j) {
continue;
}
if (isLinked && !tf.disableExcludedOptions &&
(!tf.paging && !tf.isRowDisplayed(k)) ||
(tf.paging && activeIdx && !tf.isRowValid(k))) {
continue;
}
let cellValue = tf.getCellValue(cells[j]);
//Vary Peter's patch
let cellString = matchCase(cellValue, caseSensitive);
// checks if celldata is already in array
if (!has(this.opts, cellString, caseSensitive)) {
this.opts.push(cellValue);
}
let filteredCol = filteredDataCol[j];
if (isLinked && tf.disableExcludedOptions) {
if (!filteredCol) {
filteredCol = tf.getFilteredDataCol(j);
}
if (!has(filteredCol, cellString, caseSensitive) &&
!has(this.excludedOpts, cellString,
caseSensitive)) {
this.excludedOpts.push(cellValue);
}
}
}
}
//Retrieves custom values
if (this.isCustom) {
let customValues = tf.getCustomOptions(colIndex);
@ -299,48 +217,64 @@ export class CheckList extends Feature {
this.optsTxt = customValues[1];
}
if (tf.sortSlc && !this.isCustom) {
if (!caseSensitive) {
this.opts.sort(ignoreCase);
if (this.excludedOpts) {
this.excludedOpts.sort(ignoreCase);
let activeIdx;
let activeFilterId = tf.getActiveFilterId();
if (isLinked && activeFilterId) {
activeIdx = tf.getColumnIndexFromFilterId(activeFilterId);
}
let filteredDataCol = [];
if (isLinked && tf.disableExcludedOptions) {
/** @inherited */
this.excludedOpts = [];
}
flt.innerHTML = '';
let eachRow = tf.eachRow();
eachRow(
(row) => {
let cellValue = tf.getCellValue(row.cells[colIndex]);
//Vary Peter's patch
let cellString = matchCase(cellValue, caseSensitive);
// checks if celldata is already in array
if (!has(this.opts, cellString, caseSensitive)) {
this.opts.push(cellValue);
}
} else {
this.opts.sort();
if (this.excludedOpts) {
this.excludedOpts.sort();
let filteredCol = filteredDataCol[colIndex];
if (isLinked && tf.disableExcludedOptions) {
if (!filteredCol) {
filteredCol = tf.getVisibleColumnValues(colIndex);
}
if (!has(filteredCol, cellString, caseSensitive) &&
!has(this.excludedOpts, cellString, caseSensitive)) {
this.excludedOpts.push(cellValue);
}
}
},
// continue conditions function
(row, k) => {
// excluded rows don't need to appear on selects as always valid
if (tf.excludeRows.indexOf(k) !== -1) {
return true;
}
// checks if row has expected number of cells
if (row.cells.length !== tf.nbCells || this.isCustom) {
return true;
}
if (isLinked && !this.isValidLinkedValue(k, activeIdx)) {
return true;
}
}
}
//asc sort
if (tf.sortNumAsc.indexOf(colIndex) !== -1) {
try {
this.opts.sort(numSortAsc);
if (this.excludedOpts) {
this.excludedOpts.sort(numSortAsc);
}
if (this.isCustom) {
this.optsTxt.sort(numSortAsc);
}
} catch (e) {
throw new Error(SORT_ERROR.replace('{0}', colIndex)
.replace('{1}', 'ascending'));
}//in case there are alphanumeric values
}
//desc sort
if (tf.sortNumDesc.indexOf(colIndex) !== -1) {
try {
this.opts.sort(numSortDesc);
if (this.excludedOpts) {
this.excludedOpts.sort(numSortDesc);
}
if (this.isCustom) {
this.optsTxt.sort(numSortDesc);
}
} catch (e) {
throw new Error(SORT_ERROR.replace('{0}', colIndex)
.replace('{1}', 'descending'));
}//in case there are alphanumeric values
);
//sort options
this.opts = this.sortOptions(colIndex, this.opts);
if (this.excludedOpts) {
this.excludedOpts = this.sortOptions(colIndex, this.excludedOpts);
}
this.addChecks(colIndex, ul);
@ -368,7 +302,9 @@ export class CheckList extends Feature {
let val = this.opts[y]; //item value
let lbl = this.isCustom ? this.optsTxt[y] : val; //item text
let fltId = tf.fltIds[colIndex];
let li = createCheckItem(`${fltId}_${(y + chkCt)}`, val, lbl);
let lblIdx = y + chkCt;
let li = createCheckItem(`${fltId}_${lblIdx}`, val, lbl,
['data-idx', lblIdx]);
li.className = this.itemCssClass;
if (tf.linkedFilters && tf.disableExcludedOptions &&
@ -400,7 +336,7 @@ export class CheckList extends Feature {
let chkCt = 1;
let fltId = tf.fltIds[colIndex];
let li0 = createCheckItem(`${fltId}_0`, '',
tf.getClearFilterText(colIndex));
tf.getClearFilterText(colIndex), ['data-idx', 0]);
li0.className = this.itemCssClass;
ul.appendChild(li0);
@ -412,7 +348,7 @@ export class CheckList extends Feature {
if (tf.enableEmptyOption) {
let li1 = createCheckItem(`${fltId}_1`, tf.emOperator,
tf.emptyText);
tf.emptyText, ['data-idx', 1]);
li1.className = this.itemCssClass;
ul.appendChild(li1);
addEvt(li1.check, 'click', evt => this.optionClick(evt));
@ -421,7 +357,7 @@ export class CheckList extends Feature {
if (tf.enableNonEmptyOption) {
let li2 = createCheckItem(`${fltId}_2`, tf.nmOperator,
tf.nonEmptyText);
tf.nonEmptyText, ['data-idx', 2]);
li2.className = this.itemCssClass;
ul.appendChild(li2);
addEvt(li2.check, 'click', evt => this.optionClick(evt));
@ -431,81 +367,73 @@ export class CheckList extends Feature {
}
/**
* Store checked options in DOM element attribute
* Set/unset value of passed item option in filter's DOM element attribute
* @param {Object} o checklist option DOM element
* @private
*/
setCheckListValues(o) {
setItemOption(o) {
if (!o) {
return;
}
let tf = this.tf;
let chkValue = o.value; //checked item value
// TODO: provide helper to extract column index, ugly!
let chkIndex = parseInt(o.id.split('_')[2], 10);
let chkIndex = o.dataset.idx;
let colIdx = tf.getColumnIndexFromFilterId(o.id);
let itemTag = 'LI';
let n = tf.getFilterElement(parseInt(colIdx, 10));
let li = n.childNodes[chkIndex];
let colIndex = n.getAttribute('colIndex');
let fltValue = n.getAttribute('value'); //filter value (ul tag)
let fltIndexes = n.getAttribute('indexes'); //selected items (ul tag)
let items = n.childNodes;
let li = items[chkIndex];
//selected values (ul tag)
let slcValues = n.getAttribute('value') || '';
//selected items indexes (ul tag)
let slcIndexes = n.getAttribute('indexes') || '';
if (o.checked) {
//show all item
if (chkValue === '') {
if ((fltIndexes && fltIndexes !== '')) {
//items indexes
let indSplit = fltIndexes.split(tf.separator);
//checked items loop
for (let u = 0; u < indSplit.length; u++) {
//checked item
let cChk = elm(tf.fltIds[colIndex] + '_' +
indSplit[u]);
if (cChk) {
cChk.checked = false;
removeClass(n.childNodes[indSplit[u]],
this.selectedItemCssClass);
}
//items indexes
let indexes = slcIndexes.split(tf.separator);
indexes.forEach(idx => {
idx = Number(idx);
let li = items[idx];
let chx = tag(li, 'input')[0];
if (chx && idx > 0) {
chx.checked = false;
removeClass(li, this.selectedItemCssClass);
}
}
});
n.setAttribute('value', '');
n.setAttribute('indexes', '');
} else {
fltValue = (fltValue) ? fltValue : '';
chkValue = trim(fltValue + ' ' + chkValue + ' ' +
tf.orOperator);
chkIndex = fltIndexes + chkIndex + tf.separator;
n.setAttribute('value', chkValue);
n.setAttribute('indexes', chkIndex);
//1st option unchecked
if (elm(tf.fltIds[colIndex] + '_0')) {
elm(tf.fltIds[colIndex] + '_0').checked = false;
let indexes = slcIndexes + chkIndex + tf.separator;
let values =
trim(slcValues + ' ' + chkValue + ' ' + tf.orOperator);
n.setAttribute('value', values);
n.setAttribute('indexes', indexes);
//uncheck first option
let chx0 = tag(items[0], 'input')[0];
if (chx0) {
chx0.checked = false;
}
}
if (li.nodeName === itemTag) {
removeClass(n.childNodes[0], this.selectedItemCssClass);
addClass(li, this.selectedItemCssClass);
}
removeClass(items[0], this.selectedItemCssClass);
addClass(li, this.selectedItemCssClass);
} else { //removes values and indexes
if (chkValue !== '') {
let replaceValue = new RegExp(
rgxEsc(chkValue + ' ' + tf.orOperator));
fltValue = fltValue.replace(replaceValue, '');
n.setAttribute('value', trim(fltValue));
let replaceValue =
new RegExp(rgxEsc(chkValue + ' ' + tf.orOperator));
let values = slcValues.replace(replaceValue, '');
let replaceIndex = new RegExp(rgxEsc(chkIndex + tf.separator));
let indexes = slcIndexes.replace(replaceIndex, '');
let replaceIndex = new RegExp(
rgxEsc(chkIndex + tf.separator));
fltIndexes = fltIndexes.replace(replaceIndex, '');
n.setAttribute('indexes', fltIndexes);
}
if (li.nodeName === itemTag) {
removeClass(li, this.selectedItemCssClass);
}
n.setAttribute('value', trim(values));
n.setAttribute('indexes', indexes);
removeClass(li, this.selectedItemCssClass);
}
}
@ -517,39 +445,36 @@ export class CheckList extends Feature {
selectOptions(colIndex, values = []) {
let tf = this.tf;
let flt = tf.getFilterElement(colIndex);
if (tf.getFilterType(colIndex) !== CHECKLIST || !flt ||
values.length === 0) {
if (!flt || values.length === 0) {
return;
}
let lisNb = tag(flt, 'li').length;
let lis = tag(flt, 'li');
flt.setAttribute('value', '');
flt.setAttribute('indexes', '');
for (let k = 0; k < lisNb; k++) {
let li = tag(flt, 'li')[k];
let lbl = tag(li, 'label')[0];
[].forEach.call(lis, (li) => {
let chk = tag(li, 'input')[0];
let lblTxt = matchCase(getText(lbl), tf.caseSensitive);
let chkVal = matchCase(chk.value, tf.caseSensitive);
if (lblTxt !== '' && has(values, lblTxt, tf.caseSensitive)) {
if (chkVal !== '' && has(values, chkVal, tf.caseSensitive)) {
chk.checked = true;
} else {
// Check non-empty-text or empty-text option
if (values.indexOf(tf.nmOperator) !== -1 &&
lblTxt === matchCase(tf.nonEmptyText, tf.caseSensitive)) {
chkVal === matchCase(tf.nonEmptyText, tf.caseSensitive)) {
chk.checked = true;
}
else if (values.indexOf(tf.emOperator) !== -1 &&
lblTxt === matchCase(tf.emptyText, tf.caseSensitive)) {
chkVal === matchCase(tf.emptyText, tf.caseSensitive)) {
chk.checked = true;
} else {
chk.checked = false;
}
}
this.setCheckListValues(chk);
}
this.setItemOption(chk);
});
}
/**
@ -560,9 +485,12 @@ export class CheckList extends Feature {
getValues(colIndex) {
let tf = this.tf;
let flt = tf.getFilterElement(colIndex);
if (!flt) {
return [];
}
let fltAttr = flt.getAttribute('value');
let values = isEmpty(fltAttr) ? '' : fltAttr;
//removes last operator ||
values = values.substr(0, values.length - 3);
//turn || separated values into array
@ -584,6 +512,7 @@ export class CheckList extends Feature {
(tf, colIndex, values) => this.selectOptions(colIndex, values)
);
this.emitter.off(['rows-changed'], () => this.refreshAll());
this.emitter.off(['after-filtering'], () => this.linkFilters());
this.initialized = false;
}

View file

@ -1,6 +1,9 @@
import {Feature} from '../feature';
import {createElm, createText, elm, removeElm} from '../dom';
import {addEvt} from '../event';
import {defaultsStr} from '../settings';
import {isNull} from '../types';
import {RIGHT} from './toolbar';
/**
* Clear button UI component
@ -12,15 +15,48 @@ export class ClearButton extends Feature {
* @param {TableFilter} tf TableFilter instance
*/
constructor(tf) {
super(tf, 'btnReset');
super(tf, ClearButton);
let f = this.config;
let f = this.config.btn_reset || {};
/**
* Container element ID
* @type {String}
*/
this.targetId = f.btn_reset_target_id || null;
this.targetId = defaultsStr(f.target_id, null);
/**
* Text for the clear button
* @type {String}
*/
this.text = defaultsStr(f.text, null);
/**
* Css class for reset button
* @type {String}
*/
this.cssClass = defaultsStr(f.css_class, 'reset');
/**
* Tooltip text for the clear button
* @type {String}
*/
this.tooltip = f.tooltip || 'Clear filters';
/**
* Custom Html string for the clear button
* @type {String}
*/
this.html = defaultsStr(f.html,
(!tf.enableIcons || this.text ? null :
'<input type="button" value="" class="' + this.cssClass +
'" ' + 'title="' + this.tooltip + '" />'));
/**
* Default position in toolbar ('left'|'center'|'right')
* @type {String}
*/
this.toolbarPosition = defaultsStr(f.toolbar_position, RIGHT);
/**
* Clear button container element
@ -35,33 +71,6 @@ export class ClearButton extends Feature {
* @private
*/
this.element = null;
/**
* Text for the clear button
* @type {String}
*/
this.text = f.btn_reset_text || 'Reset';
/**
* Css class for reset button
* @type {String}
*/
this.cssClass = f.btn_reset_css_class || 'reset';
/**
* Tooltip text for the clear button
* @type {String}
*/
this.tooltip = f.btn_reset_tooltip || 'Clear filters';
/**
* Custom Html string for the clear button
* @type {String}
*/
this.html = f.btn_reset_html ||
(!tf.enableIcons ? null :
'<input type="button" value="" class="' + this.cssClass +
'" ' + 'title="' + this.tooltip + '" />');
}
/**
@ -85,13 +94,13 @@ export class ClearButton extends Feature {
return;
}
this.emitter.emit('initializing-feature', this, !isNull(this.targetId));
let cont = createElm('span');
// reset button is added to defined element
if (!this.targetId) {
tf.setToolbar();
}
let targetEl = !this.targetId ? tf.rDiv : elm(this.targetId);
let targetEl = !this.targetId ?
tf.feature('toolbar').container(this.toolbarPosition) :
elm(this.targetId);
targetEl.appendChild(cont);
if (!this.html) {
@ -110,6 +119,8 @@ export class ClearButton extends Feature {
/** @inherited */
this.initialized = true;
this.emitter.emit('feature-initialized', this);
}
/**
@ -126,3 +137,6 @@ export class ClearButton extends Feature {
this.initialized = false;
}
}
// TODO: remove as soon as feature name is fixed
ClearButton.meta = {altName: 'btnReset'};

View file

@ -17,7 +17,7 @@ export class DateType extends Feature {
* @param {TableFilter} tf TableFilter instance
*/
constructor(tf) {
super(tf, 'dateType');
super(tf, DateType);
/**
* Global locale
@ -94,6 +94,16 @@ export class DateType extends Feature {
return isObj(colType) ? colType : {};
}
/**
* Return the locale code for supplied column index as per configuration
* or global setting
* @param {Number} colIndex Column index
* @returns {String} Locale code (ie: 'en-us')
*/
getLocale(colIndex) {
return this.getOptions(colIndex).locale || this.locale;
}
/**
* Add date time format(s) to a locale as specified by the passed
* collection of column types, ie:

View file

@ -1,25 +1,25 @@
import {Feature} from '../feature';
import {BaseDropdown} from './baseDropdown';
import {createElm, createOpt, elm} from '../dom';
import {has} from '../array';
import {matchCase} from '../string';
import {ignoreCase, numSortAsc, numSortDesc} from '../sort';
import {addEvt, targetEvt} from '../event';
import {SELECT, MULTIPLE, NONE} from '../const';
const SORT_ERROR = 'Filter options for column {0} cannot be sorted in ' +
'{1} manner.';
import {defaultsStr, defaultsBool} from '../settings';
/**
* Dropdown filter UI component
* @export
* @class Dropdown
* @extends {BaseDropdown}
*/
export class Dropdown extends Feature {
export class Dropdown extends BaseDropdown {
/**
* Creates an instance of Dropdown
* @param {TableFilter} tf TableFilter instance
*/
constructor(tf) {
super(tf, 'dropdown');
super(tf, Dropdown);
// Configuration object
let f = this.config;
@ -28,41 +28,21 @@ export class Dropdown extends Feature {
* Enable the reset filter option as first item
* @type {Boolean}
*/
this.enableSlcResetFilter = f.enable_slc_reset_filter === false ?
false : true;
this.enableSlcResetFilter =
defaultsBool(f.enable_slc_reset_filter, true);
/**
* Non empty option text
* @type {String}
*/
this.nonEmptyText = f.non_empty_text || '(Non empty)';
this.nonEmptyText = defaultsStr(f.non_empty_text, '(Non empty)');
/**
* Tooltip text appearing on multiple select
* @type {String}
*/
this.multipleSlcTooltip = f.multiple_slc_tooltip ||
'Use Ctrl/Cmd key for multiple selections';
/**
* Indicates drop-down has custom options
* @private
*/
this.isCustom = null;
/**
* List of options values
* @type {Array}
* @private
*/
this.opts = null;
/**
* List of options texts for custom values
* @type {Array}
* @private
*/
this.optsTxt = null;
this.multipleSlcTooltip = defaultsStr(f.multiple_slc_tooltip,
'Use Ctrl/Cmd key for multiple selections');
}
@ -96,15 +76,10 @@ export class Dropdown extends Feature {
* Refresh all drop-down filters
*/
refreshAll() {
let tf = this.tf;
let selectFlts = tf.getFiltersByType(SELECT, true);
let multipleFlts = tf.getFiltersByType(MULTIPLE, true);
let flts = selectFlts.concat(multipleFlts);
flts.forEach((colIdx) => {
let values = this.getValues(colIdx);
this.build(colIdx, tf.linkedFilters);
this.selectOptions(colIdx, values);
});
let selectFlts = this.tf.getFiltersByType(SELECT, true);
let multipleFlts = this.tf.getFiltersByType(MULTIPLE, true);
let colIdxs = selectFlts.concat(multipleFlts);
this.refreshFilters(colIdxs);
}
/**
@ -117,7 +92,7 @@ export class Dropdown extends Feature {
let tf = this.tf;
let col = tf.getFilterType(colIndex);
let externalFltTgtId = isExternal ?
tf.externalFltTgtIds[colIndex] : null;
tf.externalFltIds[colIndex] : null;
let slc = createElm(SELECT,
['id', tf.buildFilterId(colIndex)],
@ -162,6 +137,8 @@ export class Dropdown extends Feature {
);
this.emitter.on(['rows-changed'], () => this.refreshAll());
this.emitter.on(['after-filtering'], () => this.linkFilters());
/** @inherited */
this.initialized = true;
}
@ -173,21 +150,28 @@ export class Dropdown extends Feature {
*/
build(colIndex, isLinked = false) {
let tf = this.tf;
colIndex = parseInt(colIndex, 10);
colIndex = Number(colIndex);
this.emitter.emit('before-populating-filter', tf, colIndex);
/** @inherited */
this.opts = [];
/** @inherited */
this.optsTxt = [];
let slcId = tf.fltIds[colIndex];
let slc = elm(slcId);
let rows = tf.tbl.rows;
let nbRows = tf.getRowsNb(true);
let slc = tf.getFilterElement(colIndex);
//custom select test
/** @inherited */
this.isCustom = tf.isCustomOptions(colIndex);
//Retrieves custom values
if (this.isCustom) {
let customValues = tf.getCustomOptions(colIndex);
this.opts = customValues[0];
this.optsTxt = customValues[1];
}
//custom selects text
let activeIdx;
let activeFilterId = tf.getActiveFilterId();
@ -202,35 +186,12 @@ export class Dropdown extends Feature {
filteredDataCol = [];
}
for (let k = tf.refRow; k < nbRows; k++) {
// always visible rows don't need to appear on selects as always
// valid
if (tf.hasVisibleRows && tf.visibleRows.indexOf(k) !== -1) {
continue;
}
let cell = rows[k].cells,
nchilds = cell.length;
// checks if row has exact cell #
if (nchilds !== tf.nbCells || this.isCustom) {
continue;
}
// this loop retrieves cell data
for (let j = 0; j < nchilds; j++) {
if (colIndex !== j) {
continue;
}
if (isLinked && !tf.disableExcludedOptions &&
(!tf.paging && !tf.isRowDisplayed(k)) ||
(tf.paging && activeIdx && !tf.isRowValid(k))) {
continue;
}
let cellValue = tf.getCellValue(cell[j]),
//Vary Peter's patch
cellString = matchCase(cellValue, tf.caseSensitive);
let eachRow = tf.eachRow();
eachRow(
(row) => {
let cellValue = tf.getCellValue(row.cells[colIndex]);
//Vary Peter's patch
let cellString = matchCase(cellValue, tf.caseSensitive);
// checks if celldata is already in array
if (!has(this.opts, cellString, tf.caseSensitive)) {
@ -238,66 +199,38 @@ export class Dropdown extends Feature {
}
if (isLinked && tf.disableExcludedOptions) {
let filteredCol = filteredDataCol[j];
let filteredCol = filteredDataCol[colIndex];
if (!filteredCol) {
filteredCol = tf.getFilteredDataCol(j);
filteredCol = tf.getVisibleColumnValues(colIndex);
}
if (!has(filteredCol, cellString, tf.caseSensitive) &&
!has(excludedOpts, cellString, tf.caseSensitive)) {
excludedOpts.push(cellValue);
}
}
}//for j
}//for k
//Retrieves custom values
if (this.isCustom) {
let customValues = tf.getCustomOptions(colIndex);
this.opts = customValues[0];
this.optsTxt = customValues[1];
}
if (tf.sortSlc && !this.isCustom) {
if (!tf.caseSensitive) {
this.opts.sort(ignoreCase);
if (excludedOpts) {
excludedOpts.sort(ignoreCase);
},
// continue conditions function
(row, k) => {
// excluded rows don't need to appear on selects as always valid
if (tf.excludeRows.indexOf(k) !== -1) {
return true;
}
// checks if row has expected number of cells
if (row.cells.length !== tf.nbCells || this.isCustom) {
return true;
}
if (isLinked && !this.isValidLinkedValue(k, activeIdx)) {
return true;
}
} else {
this.opts.sort();
if (excludedOpts) { excludedOpts.sort(); }
}
}
);
//asc sort
if (tf.sortNumAsc.indexOf(colIndex) !== -1) {
try {
this.opts.sort(numSortAsc);
if (excludedOpts) {
excludedOpts.sort(numSortAsc);
}
if (this.isCustom) {
this.optsTxt.sort(numSortAsc);
}
} catch (e) {
throw new Error(SORT_ERROR.replace('{0}', colIndex)
.replace('{1}', 'ascending'));
}//in case there are alphanumeric values
}
//desc sort
if (tf.sortNumDesc.indexOf(colIndex) !== -1) {
try {
this.opts.sort(numSortDesc);
if (excludedOpts) {
excludedOpts.sort(numSortDesc);
}
if (this.isCustom) {
this.optsTxt.sort(numSortDesc);
}
} catch (e) {
throw new Error(SORT_ERROR.replace('{0}', colIndex)
.replace('{1}', 'ascending'));
}//in case there are alphanumeric values
//sort options
this.opts = this.sortOptions(colIndex, this.opts);
if (excludedOpts) {
excludedOpts = this.sortOptions(colIndex, excludedOpts);
}
//populates drop-down
@ -437,6 +370,7 @@ export class Dropdown extends Feature {
(tf, colIndex, values) => this.selectOptions(colIndex, values)
);
this.emitter.off(['rows-changed'], () => this.refreshAll());
this.emitter.off(['after-filtering'], () => this.linkFilters());
this.initialized = false;
}
}

View file

@ -3,6 +3,9 @@ import {createElm, removeElm, elm, tag} from '../dom';
import {addEvt, targetEvt} from '../event';
import {contains} from '../string';
import {NONE} from '../const';
import {
defaultsBool, defaultsStr, defaultsNb, defaultsArr
} from '../settings';
/**
* Grid layout, table with fixed headers
@ -14,77 +17,76 @@ export class GridLayout extends Feature {
* @param {TableFilter} tf TableFilter instance
*/
constructor(tf) {
super(tf, 'gridLayout');
super(tf, GridLayout);
let f = this.config;
let f = this.config.grid_layout || {};
/**
* Grid-layout container width as CSS string
* @type {String}
*/
this.width = f.grid_width || null;
this.width = defaultsStr(f.width, null);
/**
* Grid-layout container height as CSS string
* @type {String}
*/
this.height = f.grid_height || null;
this.height = defaultsStr(f.height, null);
/**
* Css class for main container element
* @type {String}
*/
this.mainContCssClass = f.grid_cont_css_class || 'grd_Cont';
this.mainContCssClass = defaultsStr(f.cont_css_class, 'grd_Cont');
/**
* Css class for body table container element
* @type {String}
*/
this.contCssClass = f.grid_tbl_cont_css_class || 'grd_tblCont';
this.contCssClass = defaultsStr(f.tbl_cont_css_class, 'grd_tblCont');
/**
* Css class for headers table container element
* @type {String}
*/
this.headContCssClass = f.grid_tblHead_cont_css_class ||
'grd_headTblCont';
this.headContCssClass = defaultsStr(f.tbl_head_css_class,
'grd_headTblCont');
/**
* Css class for toolbar container element (rows counter, paging etc.)
* @type {String}
*/
this.infDivCssClass = f.grid_inf_grid_css_class || 'grd_inf';
this.infDivCssClass = defaultsStr(f.inf_grid_css_class, 'grd_inf');
/**
* Index of the headers row, default: 0
* @type {Number}
*/
this.headRowIndex = f.grid_headers_row_index || 0;
this.headRowIndex = defaultsNb(f.headers_row_index, 0);
/**
* Collection of the header row indexes to be moved into headers table
* @type {Array}
*/
this.headRows = f.grid_headers_rows || [0];
this.headRows = defaultsArr(f.headers_rows, [0]);
/**
* Enable or disable column filters generation, default: true
* @type {Boolean}
*/
this.enableFilters = f.grid_enable_default_filters === false ?
false : true;
this.filters = defaultsBool(f.filters, true);
/**
* Enable or disable column headers, default: false
* @type {Boolean}
*/
this.noHeaders = Boolean(f.grid_no_headers);
this.noHeaders = Boolean(f.no_headers);
/**
* Grid-layout default column widht as CSS string
* @type {String}
*/
this.defaultColWidth = f.grid_default_col_width || '100px';
this.defaultColWidth = defaultsStr(f.default_col_width, '100px');
/**
* List of column elements
@ -112,14 +114,14 @@ export class GridLayout extends Feature {
* @type {String}
* @private
*/
this.sourceTblHtml = tf.tbl.outerHTML;
this.sourceTblHtml = tf.dom().outerHTML;
/**
* Indicates if working table has column elements
* @type {Boolean}
* @private
*/
this.tblHasColTag = tag(tf.tbl, 'col').length > 0 ? true : false;
this.tblHasColTag = tag(tf.dom(), 'col').length > 0 ? true : false;
/**
* Main container element
@ -146,7 +148,7 @@ export class GridLayout extends Feature {
this.headTbl = null;
// filters flag at TF level
tf.fltGrid = this.enableFilters;
tf.fltGrid = this.filters;
}
/**
@ -155,7 +157,7 @@ export class GridLayout extends Feature {
*/
init() {
let tf = this.tf;
let tbl = tf.tbl;
let tbl = tf.dom();
if (this.initialized) {
return;
@ -167,9 +169,6 @@ export class GridLayout extends Feature {
// Assign default column widths
this.setDefaultColWidths();
// Initial table width
let tblW = this.initialTableWidth();
//Main container: it will contain all the elements
this.tblMainCont = this.createContainer(
'div', this.mainContCssClass);
@ -190,6 +189,7 @@ export class GridLayout extends Feature {
//In case table width is expressed in %
if (tbl.style.width === '') {
let tblW = this.initialTableWidth();
tbl.style.width = (contains('%', tblW) ?
tbl.clientWidth : tblW) + 'px';
}
@ -200,7 +200,6 @@ export class GridLayout extends Feature {
//Headers table container: div wrapping headers table
this.headTblCont = this.createContainer(
'div', this.headContCssClass);
this.setConfigWidth(this.headTblCont);
//Headers table
this.headTbl = createElm('table');
@ -233,22 +232,16 @@ export class GridLayout extends Feature {
tbl.removeChild(thead[0]);
}
//Headers table style
// ensure table layout is always set even if already set in css
// definitions, potentially with custom css class this could be lost
this.headTbl.style.tableLayout = 'fixed';
tbl.style.tableLayout = 'fixed';
this.headTbl.cellPadding = tbl.cellPadding;
this.headTbl.cellSpacing = tbl.cellSpacing;
// this.headTbl.style.width = tbl.style.width;
//content table without headers needs col widths to be reset
tf.setColWidths(this.headTbl);
//Headers container width
// this.headTblCont.style.width = this.tblCont.clientWidth+'px';
tbl.style.width = '';
//
this.headTbl.style.width = tbl.clientWidth + 'px';
this.headTbl.style.width = tbl.style.width;
//
//scroll synchronisation
@ -288,10 +281,6 @@ export class GridLayout extends Feature {
filtersRow.style.display = NONE;
}
if (tbl.clientWidth !== this.headTbl.clientWidth) {
tbl.style.width = this.headTbl.clientWidth + 'px';
}
/** @inherited */
this.initialized = true;
}
@ -305,7 +294,6 @@ export class GridLayout extends Feature {
tf.refRow = 0;
tf.headersRow = 0;
tf.filtersRowIndex = 1;
tf.isExternalFlt = true;
}
/**
@ -314,12 +302,13 @@ export class GridLayout extends Feature {
*/
setDefaultColWidths() {
let tf = this.tf;
if (tf.hasColWidths) {
if (tf.colWidths.length > 0) {
return;
}
for (let k = 0, len = tf.getCellsNb(); k < len; k++) {
tf.eachCol((k) => {
let colW;
let cell = tf.tbl.rows[tf.getHeadersRowIndex()].cells[k];
let cell = tf.dom().rows[tf.getHeadersRowIndex()].cells[k];
if (cell.width !== '') {
colW = cell.width;
} else if (cell.style.width !== '') {
@ -328,8 +317,8 @@ export class GridLayout extends Feature {
colW = this.defaultColWidth;
}
tf.colWidths[k] = colW;
}
tf.hasColWidths = true;
});
tf.setColWidths();
}
@ -339,7 +328,7 @@ export class GridLayout extends Feature {
* @private
*/
initialTableWidth() {
let tbl = this.tf.tbl;
let tbl = this.tf.dom();
let width; //initial table width
if (tbl.width !== '') {
@ -374,14 +363,14 @@ export class GridLayout extends Feature {
createFiltersRow() {
let tf = this.tf;
let filtersRow = createElm('tr');
if (this.enableFilters && tf.fltGrid) {
tf.externalFltTgtIds = [];
for (let j = 0; j < tf.getCellsNb(); j++) {
if (this.filters && tf.fltGrid) {
tf.externalFltIds = [];
tf.eachCol((j) => {
let fltTdId = `${tf.prfxFlt + j + this.prfxGridFltTd + tf.id}`;
let cl = createElm(tf.fltCellTag, ['id', fltTdId]);
filtersRow.appendChild(cl);
tf.externalFltTgtIds[j] = fltTdId;
}
tf.externalFltIds[j] = fltTdId;
});
}
return filtersRow;
}
@ -392,15 +381,15 @@ export class GridLayout extends Feature {
*/
setColumnElements() {
let tf = this.tf;
let cols = tag(tf.tbl, 'col');
let cols = tag(tf.dom(), 'col');
this.tblHasColTag = cols.length > 0;
for (let k = (tf.nbCells - 1); k >= 0; k--) {
for (let k = (tf.getCellsNb() - 1); k >= 0; k--) {
let col;
if (!this.tblHasColTag) {
col = createElm('col');
tf.tbl.insertBefore(col, tf.tbl.firstChild);
tf.dom().insertBefore(col, tf.dom().firstChild);
} else {
col = cols[k];
}
@ -423,7 +412,7 @@ export class GridLayout extends Feature {
} else {
// Headers row are moved from content table to headers table
for (let i = 0; i < this.headRows.length; i++) {
let row = this.tf.tbl.rows[this.headRows[i]];
let row = this.tf.dom().rows[this.headRows[i]];
tableHead.appendChild(row);
}
}
@ -454,7 +443,7 @@ export class GridLayout extends Feature {
getSortTriggerIds(row) {
let tf = this.tf;
let sortTriggers = [];
for (let n = 0; n < tf.getCellsNb(); n++) {
tf.eachCol((n) => {
let c = row.cells[n];
let thId = c.getAttribute('id');
if (!thId || thId === '') {
@ -462,7 +451,7 @@ export class GridLayout extends Feature {
c.setAttribute('id', thId);
}
sortTriggers.push(thId);
}
});
return sortTriggers;
}
@ -471,7 +460,7 @@ export class GridLayout extends Feature {
*/
destroy() {
let tf = this.tf;
let tbl = tf.tbl;
let tbl = tf.dom();
if (!this.initialized) {
return;

View file

@ -86,7 +86,7 @@ export class Hash {
}
/**
* Converts a URL hash into a state JSON object
* Converts a URL hash into a JSON object
*
* @param {String} hash URL hash fragment
* @returns {Object} JSON object

View file

@ -3,10 +3,13 @@ import {createElm, createText, elm, removeElm} from '../dom';
import {addEvt, targetEvt, removeEvt} from '../event';
import {NONE} from '../const';
import {root} from '../root';
import {isEmpty, isNull} from '../types';
import {defaultsStr, defaultsNb} from '../settings';
import {RIGHT} from './toolbar';
const WIKI_URL = 'https://github.com/koalyptus/TableFilter/wiki/' +
'4.-Filter-operators';
const WEBSITE_URL = 'http://koalyptus.github.io/TableFilter/';
const WEBSITE_URL = 'https://www.tablefilter.com/';
/**
* Help UI component
@ -18,29 +21,27 @@ export class Help extends Feature {
* @param {TableFilter} tf TableFilter instance
*/
constructor(tf) {
super(tf, 'help');
super(tf, Help);
let f = this.config;
let f = this.config.help_instructions || {};
/**
* ID of main custom container element
* @type {String}
*/
this.tgtId = f.help_instructions_target_id || null;
this.tgtId = defaultsStr(f.target_id, null);
/**
* ID of custom container element for instructions
* @type {String}
*/
this.contTgtId = f.help_instructions_container_target_id ||
null;
this.contTgtId = defaultsStr(f.container_target_id, null);
/**
* Instructions text (accepts HTML)
* @type {String}
*/
this.instrText = f.help_instructions_text ?
f.help_instructions_text :
this.instrText = !isEmpty(f.text) ? f.text :
'Use the filters above each column to filter and limit table ' +
'data. Advanced searches can be performed by using the following ' +
'operators: <br /><b>&lt;</b>, <b>&lt;=</b>, <b>&gt;</b>, ' +
@ -53,32 +54,31 @@ export class Help extends Feature {
* Instructions HTML
* @type {String}
*/
this.instrHtml = f.help_instructions_html || null;
this.instrHtml = defaultsStr(f.html, null);
/**
* Help button text ('?')
* @type {String}
*/
this.btnText = f.help_instructions_btn_text || '?';
this.btnText = defaultsStr(f.btn_text, '?');
/**
* Custom help button HTML
* @type {String}
*/
this.btnHtml = f.help_instructions_btn_html || null;
this.btnHtml = defaultsStr(f.btn_html, null);
/**
* Css class for help button
* @type {String}
*/
this.btnCssClass = f.help_instructions_btn_css_class || 'helpBtn';
this.btnCssClass = defaultsStr(f.btn_css_class, 'helpBtn');
/**
* Css class for help container element
* @type {String}
*/
this.contCssClass = f.help_instructions_container_css_class ||
'helpCont';
this.contCssClass = defaultsStr(f.container_css_class, 'helpCont');
/**
* Button DOM element
@ -92,6 +92,15 @@ export class Help extends Feature {
*/
this.cont = null;
/**
* Adjust container left position when table's horizontal scroll is
* on, typically when `responsive` option is enabled.
* @type {Number}
* @defaultValue 25
*/
this.contAdjustLeftPosition =
defaultsNb(f.container_adjust_left_position, 25);
/**
* Bound mouseup wrapper
* @private
@ -109,6 +118,12 @@ export class Help extends Feature {
'<div align="center" style="margin-top:8px;">' +
'<a href="javascript:void(0);" class="close">Close</a></div></div>';
/**
* Default position in toolbar ('left'|'center'|'right')
* @type {String}
*/
this.toolbarPosition = defaultsStr(f.toolbar_position, RIGHT);
this.emitter.on(['init-help'], () => this.init());
}
@ -138,6 +153,8 @@ export class Help extends Feature {
return;
}
this.emitter.emit('initializing-feature', this, !isNull(this.tgtId));
let tf = this.tf;
let btn = createElm('span');
@ -146,10 +163,9 @@ export class Help extends Feature {
this.boundMouseup = this.onMouseup.bind(this);
//help button is added to defined element
if (!this.tgtId) {
tf.setToolbar();
}
let targetEl = !this.tgtId ? tf.rDiv : elm(this.tgtId);
let targetEl = !this.tgtId ?
tf.feature('toolbar').container(this.toolbarPosition) :
elm(this.tgtId);
targetEl.appendChild(btn);
let divContainer = !this.contTgtId ? btn : elm(this.contTgtId);
@ -187,15 +203,17 @@ export class Help extends Feature {
this.btn = btn;
/** @inherited */
this.initialized = true;
this.emitter.emit('feature-initialized', this);
}
/**
* Toggle help pop-up
*/
toggle() {
// check only if explicitily set to false as in this case undefined
// check only if explicitily disabled as in this case undefined
// signifies the help feature is enabled by default
if (this.enabled === false) {
if (!this.isEnabled()) {
return;
}
@ -205,9 +223,21 @@ export class Help extends Feature {
let divDisplay = this.cont.style.display;
if (divDisplay === '' || divDisplay === NONE) {
this.cont.style.display = 'inline';
// if table element has an horizontal scrollbar adjust container
// left position accordingly
if (this.tf.dom().scrollLeft > 0) {
this.cont.style.left = `${
this.btn.offsetLeft
- this.tf.dom().scrollLeft
+ this.contAdjustLeftPosition
}px`;
}
addEvt(root, 'mouseup', this.boundMouseup);
} else {
this.cont.style.display = NONE;
this.cont.style.left = '';
}
}
@ -225,8 +255,10 @@ export class Help extends Feature {
this.cont = null;
this.boundMouseup = null;
this.initialized = false;
}
}
// TODO: remove as soon as feature name is fixed
Help.meta = {alwaysInstantiate: true};

View file

@ -1,6 +1,7 @@
import {createText, createElm, getText} from '../dom';
import {isArray} from '../types';
import {isNull} from '../types';
import {rgxEsc} from '../string';
import {defaultsStr} from '../settings';
/**
* Highlight matched keywords upon filtering
@ -21,7 +22,7 @@ export class HighlightKeyword {
* Css class for highlighted term
* @type {String}
*/
this.highlightCssClass = f.highlight_css_class || 'keyword';
this.highlightCssClass = defaultsStr(f.highlight_css_class, 'keyword');
/**
* TableFilter instance
@ -99,12 +100,13 @@ export class HighlightKeyword {
* @param {String} cssClass Css class to remove
*/
unhighlight(term, cssClass) {
let highlightedNodes = this.tf.tbl.querySelectorAll(`.${cssClass}`);
let highlightedNodes = this.tf.dom().querySelectorAll(`.${cssClass}`);
for (let i = 0; i < highlightedNodes.length; i++) {
let n = highlightedNodes[i];
let nodeVal = getText(n);
if (nodeVal.toLowerCase().indexOf(term.toLowerCase()) !== -1) {
if (isNull(term) ||
nodeVal.toLowerCase().indexOf(term.toLowerCase()) !== -1) {
let parentNode = n.parentNode;
parentNode.replaceChild(createText(nodeVal), n);
parentNode.normalize();
@ -119,15 +121,8 @@ export class HighlightKeyword {
if (!this.tf.highlightKeywords) {
return;
}
// iterate filters values to unhighlight all values
this.tf.getFiltersValue().forEach((val) => {
if (isArray(val)) {
val.forEach((item) =>
this.unhighlight(item, this.highlightCssClass));
} else {
this.unhighlight(val, this.highlightCssClass);
}
});
this.unhighlight(null, this.highlightCssClass);
}
/** Remove feature */
@ -177,3 +172,9 @@ export class HighlightKeyword {
this.highlight(cell, term, this.highlightCssClass);
}
}
// TODO: remove as soon as feature name is fixed
HighlightKeyword.meta = {
name: 'highlightKeyword',
altName: 'highlightKeywords'
};

View file

@ -1,10 +1,11 @@
import {Feature} from '../feature';
import {createElm, createText, elm, removeElm} from '../dom';
import {isFn, EMPTY_FN} from '../types';
import {EMPTY_FN} from '../types';
import {root} from '../root';
import {NONE} from '../const';
import {defaultsStr, defaultsFn} from '../settings';
const EVENTS = [
const BEFORE_ACTION_EVENTS = [
'before-filtering',
'before-populating-filter',
'before-page-change',
@ -16,6 +17,18 @@ const EVENTS = [
'before-loading-themes'
];
const AFTER_ACTION_EVENTS = [
'after-filtering',
'after-populating-filter',
'after-page-change',
'after-clearing-filters',
'after-page-length-change',
'after-reset-page',
'after-reset-page-length',
'after-loading-extensions',
'after-loading-themes'
];
/**
* Activity indicator
*
@ -31,15 +44,15 @@ export class Loader extends Feature {
* @param {TableFilter} tf TableFilter instance
*/
constructor(tf) {
super(tf, 'loader');
super(tf, Loader);
let f = this.config;
let f = this.config.loader || {};
/**
* ID of custom container element
* @type {String}
*/
this.targetId = f.loader_target_id || null;
this.targetId = defaultsStr(f.target_id, null);
/**
* Loader container DOM element
@ -51,19 +64,19 @@ export class Loader extends Feature {
* Text displayed when indicator is visible
* @type {String}
*/
this.text = f.loader_text || 'Loading...';
this.text = defaultsStr(f.text, 'Loading...');
/**
* Custom HTML injected in Loader's container element
* @type {String}
*/
this.html = f.loader_html || null;
this.html = defaultsStr(f.html, null);
/**
* Css class for Loader's container element
* @type {String}
*/
this.cssClass = f.loader_css_class || 'loader';
this.cssClass = defaultsStr(f.css_class, 'loader');
/**
* Close delay in milliseconds
@ -75,14 +88,13 @@ export class Loader extends Feature {
* Callback fired when loader is displayed
* @type {Function}
*/
this.onShow = isFn(f.on_show_loader) ?
f.on_show_loader : EMPTY_FN;
this.onShow = defaultsFn(f.on_show_loader, EMPTY_FN);
/**
* Callback fired when loader is closed
* @type {Function}
*/
this.onHide = isFn(f.on_hide_loader) ? f.on_hide_loader : EMPTY_FN;
this.onHide = defaultsFn(f.on_hide_loader, EMPTY_FN);
}
/**
@ -100,9 +112,9 @@ export class Loader extends Feature {
containerDiv.className = this.cssClass;
let targetEl = !this.targetId ?
tf.tbl.parentNode : elm(this.targetId);
tf.dom().parentNode : elm(this.targetId);
if (!this.targetId) {
targetEl.insertBefore(containerDiv, tf.tbl);
targetEl.insertBefore(containerDiv, tf.dom());
} else {
targetEl.appendChild(containerDiv);
}
@ -116,12 +128,10 @@ export class Loader extends Feature {
this.show(NONE);
// Subscribe to events
emitter.on(EVENTS, () => this.show(''));
emitter.on(EVENTS, () => this.show(NONE));
emitter.on(BEFORE_ACTION_EVENTS, () => this.show(''));
emitter.on(AFTER_ACTION_EVENTS, () => this.show(NONE));
/**
* @inherited
*/
/** @inherited */
this.initialized = true;
}
@ -134,7 +144,7 @@ export class Loader extends Feature {
return;
}
let displayLoader = () => {
function displayLoader() {
if (!this.cont) {
return;
}
@ -148,7 +158,7 @@ export class Loader extends Feature {
};
let t = p === NONE ? this.closeDelay : 1;
root.setTimeout(displayLoader, t);
root.setTimeout(displayLoader.bind(this), t);
}
/**
@ -165,8 +175,8 @@ export class Loader extends Feature {
this.cont = null;
// Unsubscribe to events
emitter.off(EVENTS, () => this.show(''));
emitter.off(EVENTS, () => this.show(NONE));
emitter.off(BEFORE_ACTION_EVENTS, () => this.show(''));
emitter.off(AFTER_ACTION_EVENTS, () => this.show(NONE));
this.initialized = false;
}

View file

@ -0,0 +1,146 @@
import {Feature} from '../feature';
import {addClass, removeClass, hasClass} from '../dom';
import {EMPTY_FN} from '../types';
import {defaultsStr, defaultsFn} from '../settings';
/**
* Visual indicator for filtered columns
* @export
* @class MarkActiveColumns
* @extends {Feature}
*/
export class MarkActiveColumns extends Feature {
/**
* Create an instance of MarkActiveColumns
* @param {TableFilter} tf TableFilter instance
*/
constructor(tf) {
super(tf, MarkActiveColumns);
let config = this.config.mark_active_columns || {};
/**
* Css class for filtered (active) columns
* @type {String}
*/
this.headerCssClass = defaultsStr(config.header_css_class,
'activeHeader');
/**
* Css class for filtered (active) column cells
* @type {String}
*/
this.cellCssClass = defaultsStr(config.cell_css_class,
'activeCell');
/**
* Enable/disable column highlighting
* @type {Boolean}
*/
this.highlightColumn = Boolean(config.highlight_column);
/**
* Callback fired before a column is marked as filtered
* @type {Function}
*/
this.onBeforeActiveColumn = defaultsFn(config.on_before_active_column,
EMPTY_FN);
/**
* Callback fired after a column is marked as filtered
* @type {Function}
*/
this.onAfterActiveColumn = defaultsFn(config.on_after_active_column,
EMPTY_FN);
}
/**
* Initialise MarkActiveColumns instance
*/
init() {
if (this.initialized) {
return;
}
this.emitter.on(['before-filtering'], () => this.clearActiveColumns());
this.emitter.on(
['cell-processed'],
(tf, colIndex) => this.markActiveColumn(colIndex)
);
/** @inherited */
this.initialized = true;
}
/**
* Clear filtered columns visual indicator (background color)
*/
clearActiveColumns() {
let tf = this.tf;
tf.eachCol((idx) => {
removeClass(tf.getHeaderElement(idx), this.headerCssClass);
if (this.highlightColumn) {
this.eachColumnCell(idx,
(cell) => removeClass(cell, this.cellCssClass));
}
});
}
/**
* Mark currently filtered column
* @param {Number} colIndex Column index
*/
markActiveColumn(colIndex) {
let tf = this.tf;
let header = tf.getHeaderElement(colIndex);
if (hasClass(header, this.headerCssClass)) {
return;
}
this.onBeforeActiveColumn(this, colIndex);
addClass(header, this.headerCssClass);
if (this.highlightColumn) {
this.eachColumnCell(colIndex,
(cell) => addClass(cell, this.cellCssClass));
}
this.onAfterActiveColumn(this, colIndex);
}
/**
* Column cells iterator
* TODO: make public and move into TableFilter if used elsewhere
* @param {Number} colIndex
* @param {Function} fn
* @param {DOMElement} tbl
* @private
*/
eachColumnCell(colIndex, fn = EMPTY_FN, tbl = this.tf.dom()) {
// TODO: remove [].forEach when polyfill for PhanthomJs is available
[].forEach.call(
tbl.querySelectorAll(`tbody td:nth-child(${colIndex + 1})`), fn);
}
/**
* Remove feature
*/
destroy() {
if (!this.initialized) {
return;
}
this.clearActiveColumns();
this.emitter.off(['before-filtering'], () => this.clearActiveColumns());
this.emitter.off(
['cell-processed'],
(tf, colIndex) => this.markActiveColumn(colIndex)
);
/** @inherited */
this.initialized = false;
}
}

View file

@ -1,7 +1,8 @@
import {Feature} from '../feature';
import {createElm, elm, removeElm} from '../dom';
import {isEmpty, isFn, EMPTY_FN} from '../types';
import {isEmpty, EMPTY_FN} from '../types';
import {NONE} from '../const';
import {defaultsStr, defaultsFn} from '../settings';
/**
* UI when filtering yields no matches
@ -16,28 +17,28 @@ export class NoResults extends Feature {
* @param {TableFilter} tf TableFilter instance
*/
constructor(tf) {
super(tf, 'noResults');
super(tf, NoResults);
//configuration object
let f = this.config.no_results_message;
let f = this.config.no_results_message || {};
/**
* Text (accepts HTML)
* @type {String}
*/
this.content = f.content || 'No results';
this.content = defaultsStr(f.content, 'No results');
/**
* Custom container DOM element
* @type {DOMElement}
*/
this.customContainer = f.custom_container || null;
this.customContainer = defaultsStr(f.custom_container, null);
/**
* ID of custom container element
* @type {String}
*/
this.customContainerId = f.custom_container_id || null;
this.customContainerId = defaultsStr(f.custom_container_id, null);
/**
* Indicates if UI is contained in a external element
@ -51,7 +52,7 @@ export class NoResults extends Feature {
* Css class assigned to container element
* @type {String}
*/
this.cssClass = f.css_class || 'no-results';
this.cssClass = defaultsStr(f.css_class, 'no-results');
/**
* Stores container DOM element
@ -63,29 +64,25 @@ export class NoResults extends Feature {
* Callback fired before the message is displayed
* @type {Function}
*/
this.onBeforeShow = isFn(f.on_before_show_msg) ?
f.on_before_show_msg : EMPTY_FN;
this.onBeforeShow = defaultsFn(f.on_before_show_msg, EMPTY_FN);
/**
* Callback fired after the message is displayed
* @type {Function}
*/
this.onAfterShow = isFn(f.on_after_show_msg) ?
f.on_after_show_msg : EMPTY_FN;
this.onAfterShow = defaultsFn(f.on_after_show_msg, EMPTY_FN);
/**
* Callback fired before the message is hidden
* @type {Function}
*/
this.onBeforeHide = isFn(f.on_before_hide_msg) ?
f.on_before_hide_msg : EMPTY_FN;
this.onBeforeHide = defaultsFn(f.on_before_hide_msg, EMPTY_FN);
/**
* Callback fired after the message is hidden
* @type {Function}
*/
this.onAfterHide = isFn(f.on_after_hide_msg) ?
f.on_after_hide_msg : EMPTY_FN;
this.onAfterHide = defaultsFn(f.on_after_hide_msg, EMPTY_FN);
}
/**
@ -97,7 +94,7 @@ export class NoResults extends Feature {
}
let tf = this.tf;
let target = this.customContainer || elm(this.customContainerId) ||
tf.tbl;
tf.dom();
//container
let cont = createElm('div');
@ -113,14 +110,13 @@ export class NoResults extends Feature {
this.cont = cont;
// subscribe to after-filtering event
this.emitter.on(['after-filtering'], () => this.toggle());
this.emitter.on(
['initialized', 'after-filtering'],
() => this.toggle()
);
/**
* @inherited
*/
/** @inherited */
this.initialized = true;
this.hide();
}
/**
@ -174,16 +170,15 @@ export class NoResults extends Feature {
let tf = this.tf;
if (tf.gridLayout) {
let gridLayout = tf.feature('gridLayout');
this.cont.style.width = gridLayout.tblCont.clientWidth + 'px';
this.cont.style.width = gridLayout.headTbl.clientWidth + 'px';
} else {
this.cont.style.width = (tf.tbl.tHead ? tf.tbl.tHead.clientWidth :
tf.tbl.tBodies[0].clientWidth) + 'px';
this.cont.style.width = (tf.dom().tHead ?
tf.dom().tHead.clientWidth :
tf.dom().tBodies[0].clientWidth) + 'px';
}
}
/**
* Remove feature
*/
/** Remove feature */
destroy() {
if (!this.initialized) {
return;

View file

@ -1,8 +1,12 @@
import {Feature} from '../feature';
import {createElm, createOpt, createText, elm, removeElm} from '../dom';
import {isArray, isFn, isNull, EMPTY_FN} from '../types';
import {addEvt, keyCode, removeEvt} from '../event';
import {isArray, isNull, EMPTY_FN} from '../types';
import {addEvt, removeEvt, isKeyPressed, bound} from '../event';
import {INPUT, SELECT, NONE, ENTER_KEY} from '../const';
import {
defaultsStr, defaultsNb, defaultsBool, defaultsArr, defaultsFn
} from '../settings';
import {CENTER, RIGHT} from './toolbar';
/**
* Paging UI component
@ -17,65 +21,65 @@ export class Paging extends Feature {
* @param {TableFilter} tf TableFilter instance
*/
constructor(tf) {
super(tf, 'paging');
super(tf, Paging);
// Configuration object
var f = this.config;
let f = this.config.paging || {};
/**
* Css class for the paging buttons (previous, next, etc.)
* @type {String}
*/
this.btnPageCssClass = f.paging_btn_css_class || 'pgInp';
this.btnCssClass = defaultsStr(f.btn_css_class, 'pgInp');
/**
/**
* Main select DOM element
* @type {DOMElement}
*/
this.pagingSlc = null;
this.pageSlc = null;
/**
* Results per page select DOM element
* @type {DOMElement}
*/
this.resultsPerPageSlc = null;
this.pageLengthSlc = null;
/**
* ID of custom container element
* @type {String}
*/
this.pagingTgtId = f.paging_target_id || null;
this.tgtId = defaultsStr(f.target_id, null);
/**
* Number of rows contained in a page
* @type {Number}
*/
this.pagingLength = !isNaN(f.paging_length) ? f.paging_length : 10;
this.pageLength = defaultsNb(f.length, 10);
/**
* ID of custom container element for the results per page selector
* @type {String}
*/
this.resultsPerPageTgtId = f.results_per_page_target_id || null;
this.pageLengthTgtId = defaultsStr(f.results_per_page_target_id, null);
/**
* Css class for the paging select element
* @type {String}
*/
this.pgSlcCssClass = f.paging_slc_css_class || 'pgSlc';
this.pgSlcCssClass = defaultsStr(f.slc_css_class, 'pgSlc');
/**
* Css class for the paging input element
* @type {String}
*/
this.pgInpCssClass = f.paging_inp_css_class || 'pgNbInp';
this.pgInpCssClass = defaultsStr(f.inp_css_class, 'pgNbInp');
/**
* Label and values for the results per page select, example of usage:
* ['Records: ', [10,25,50,100]]
* @type {Array}
*/
this.resultsPerPage = f.results_per_page || null;
this.resultsPerPage = defaultsArr(f.results_per_page, null);
/**
* Determines if results per page is configured
@ -87,13 +91,14 @@ export class Paging extends Feature {
* Css class for the results per page select
* @type {String}
*/
this.resultsSlcCssClass = f.results_slc_css_class || 'rspg';
this.resultsSlcCssClass = defaultsStr(f.results_slc_css_class, 'rspg');
/**
* Css class for the label preceding results per page select
* @type {String}
*/
this.resultsSpanCssClass = f.results_span_css_class || 'rspgSpan';
this.resultsSpanCssClass = defaultsStr(f.results_span_css_class,
'rspgSpan');
/**
* Index of the first row of current page
@ -120,105 +125,109 @@ export class Paging extends Feature {
* Next page button text
* @type {String}
*/
this.btnNextPageText = f.btn_next_page_text || '>';
this.btnNextPageText = defaultsStr(f.btn_next_page_text, '>');
/**
* Previous page button text
* @type {String}
*/
this.btnPrevPageText = f.btn_prev_page_text || '<';
this.btnPrevPageText = defaultsStr(f.btn_prev_page_text, '<');
/**
* Last page button text
* @type {String}
*/
this.btnLastPageText = f.btn_last_page_text || '>|';
this.btnLastPageText = defaultsStr(f.btn_last_page_text, '>|');
/**
* First page button text
* @type {String}
*/
this.btnFirstPageText = f.btn_first_page_text || '|<';
this.btnFirstPageText = defaultsStr(f.btn_first_page_text, '|<');
/**
* Next page button HTML
* @type {String}
*/
this.btnNextPageHtml = f.btn_next_page_html ||
this.btnNextPageHtml = defaultsStr(f.btn_next_page_html,
(!tf.enableIcons ? null :
'<input type="button" value="" class="' + this.btnPageCssClass +
' nextPage" title="Next page" />');
'<input type="button" value="" class="' + this.btnCssClass +
' nextPage" title="Next page" />'));
/**
* Previous page button HTML
* @type {String}
*/
this.btnPrevPageHtml = f.btn_prev_page_html ||
this.btnPrevPageHtml = defaultsStr(f.btn_prev_page_html,
(!tf.enableIcons ? null :
'<input type="button" value="" class="' + this.btnPageCssClass +
' previousPage" title="Previous page" />');
'<input type="button" value="" class="' + this.btnCssClass +
' previousPage" title="Previous page" />'));
/**
* First page button HTML
* @type {String}
*/
this.btnFirstPageHtml = f.btn_first_page_html ||
this.btnFirstPageHtml = defaultsStr(f.btn_first_page_html,
(!tf.enableIcons ? null :
'<input type="button" value="" class="' + this.btnPageCssClass +
' firstPage" title="First page" />');
'<input type="button" value="" class="' + this.btnCssClass +
' firstPage" title="First page" />'));
/**
* Last page button HTML
* @type {String}
*/
this.btnLastPageHtml = f.btn_last_page_html ||
this.btnLastPageHtml = defaultsStr(f.btn_last_page_html,
(!tf.enableIcons ? null :
'<input type="button" value="" class="' + this.btnPageCssClass +
' lastPage" title="Last page" />');
'<input type="button" value="" class="' + this.btnCssClass +
' lastPage" title="Last page" />'));
/**
* Text preceeding page selector drop-down
* @type {String}
*/
this.pageText = f.page_text || ' Page ';
this.pageText = defaultsStr(f.page_text, ' Page ');
/**
* Text after page selector drop-down
* @type {String}
*/
this.ofText = f.of_text || ' of ';
this.ofText = defaultsStr(f.of_text, ' of ');
/**
* Css class for the span containing total number of pages
* @type {String}
*/
this.nbPgSpanCssClass = f.nb_pages_css_class || 'nbpg';
this.nbPgSpanCssClass = defaultsStr(f.nb_pages_css_class, 'nbpg');
/**
* Determines if paging buttons are enabled (default: true)
* @type {Boolean}
*/
this.hasPagingBtns = f.paging_btns === false ? false : true;
this.hasBtns = defaultsBool(f.btns, true);
/**
* Defines page selector type, two possible values: 'select', 'input'
* @type {String}
*/
this.pageSelectorType = f.page_selector_type || SELECT;
this.pageSelectorType = defaultsStr(f.page_selector_type, SELECT);
/**
* Default position in toolbar ('left'|'center'|'right')
* @type {String}
*/
this.toolbarPosition = defaultsStr(f.toolbar_position, CENTER);
/**
* Callback fired before the page is changed
* @type {Function}
*/
this.onBeforeChangePage = isFn(f.on_before_change_page) ?
f.on_before_change_page : EMPTY_FN;
this.onBeforeChangePage = defaultsFn(f.on_before_change_page, EMPTY_FN);
/**
* Callback fired after the page is changed
* @type {Function}
*/
this.onAfterChangePage = isFn(f.on_after_change_page) ?
f.on_after_change_page : EMPTY_FN;
this.onAfterChangePage = defaultsFn(f.on_after_change_page, EMPTY_FN);
/**
* Label preciding results per page select
@ -269,12 +278,12 @@ export class Paging extends Feature {
*/
this.pgAfter = null;
var start_row = tf.refRow;
var nrows = tf.getRowsNb(true);
let startRow = tf.refRow;
let nrows = tf.getRowsNb(true);
//calculates page nb
this.nbPages = Math.ceil((nrows - start_row) / this.pagingLength);
this.nbPages = Math.ceil((nrows - startRow) / this.pageLength);
var o = this;
let o = this;
/**
* Paging DOM events handlers
* @type {String}
@ -283,21 +292,21 @@ export class Paging extends Feature {
this.evt = {
slcIndex() {
return (o.pageSelectorType === SELECT) ?
o.pagingSlc.options.selectedIndex :
parseInt(o.pagingSlc.value, 10) - 1;
o.pageSlc.options.selectedIndex :
parseInt(o.pageSlc.value, 10) - 1;
},
nbOpts() {
return (o.pageSelectorType === SELECT) ?
parseInt(o.pagingSlc.options.length, 10) - 1 :
parseInt(o.pageSlc.options.length, 10) - 1 :
(o.nbPages - 1);
},
next() {
var nextIndex = o.evt.slcIndex() < o.evt.nbOpts() ?
let nextIndex = o.evt.slcIndex() < o.evt.nbOpts() ?
o.evt.slcIndex() + 1 : 0;
o.changePage(nextIndex);
},
prev() {
var prevIndex = o.evt.slcIndex() > 0 ?
let prevIndex = o.evt.slcIndex() > 0 ?
o.evt.slcIndex() - 1 : o.evt.nbOpts();
o.changePage(prevIndex);
},
@ -308,8 +317,7 @@ export class Paging extends Feature {
o.changePage(0);
},
_detectKey(e) {
var key = keyCode(e);
if (key === ENTER_KEY) {
if (isKeyPressed(e, [ENTER_KEY])) {
if (tf.sorted) {
tf.filter();
o.changePage(o.evt.slcIndex());
@ -331,27 +339,29 @@ export class Paging extends Feature {
* Initialize DOM elements
*/
init() {
var slcPages;
var tf = this.tf;
var evt = this.evt;
let slcPages;
let tf = this.tf;
let evt = this.evt;
if (this.initialized) {
return;
}
this.emitter.emit('initializing-feature', this, !isNull(this.tgtId));
// Check resultsPerPage is in expected format and initialise the
// results per page component
if (this.hasResultsPerPage) {
if (this.resultsPerPage.length < 2) {
this.hasResultsPerPage = false;
} else {
this.pagingLength = this.resultsPerPage[1][0];
this.pageLength = this.resultsPerPage[1][0];
this.setResultsPerPage();
}
}
evt.slcPagesChange = (event) => {
var slc = event.target;
let slc = event.target;
this.changePage(slc.selectedIndex);
};
@ -370,20 +380,20 @@ export class Paging extends Feature {
}
// btns containers
var btnNextSpan = createElm('span');
var btnPrevSpan = createElm('span');
var btnLastSpan = createElm('span');
var btnFirstSpan = createElm('span');
let btnNextSpan = createElm('span');
let btnPrevSpan = createElm('span');
let btnLastSpan = createElm('span');
let btnFirstSpan = createElm('span');
if (this.hasPagingBtns) {
if (this.hasBtns) {
// Next button
if (!this.btnNextPageHtml) {
var btnNext = createElm(INPUT,
let btnNext = createElm(INPUT,
['type', 'button'],
['value', this.btnNextPageText],
['title', 'Next']
);
btnNext.className = this.btnPageCssClass;
btnNext.className = this.btnCssClass;
addEvt(btnNext, 'click', evt.next);
btnNextSpan.appendChild(btnNext);
} else {
@ -392,12 +402,12 @@ export class Paging extends Feature {
}
// Previous button
if (!this.btnPrevPageHtml) {
var btnPrev = createElm(INPUT,
let btnPrev = createElm(INPUT,
['type', 'button'],
['value', this.btnPrevPageText],
['title', 'Previous']
);
btnPrev.className = this.btnPageCssClass;
btnPrev.className = this.btnCssClass;
addEvt(btnPrev, 'click', evt.prev);
btnPrevSpan.appendChild(btnPrev);
} else {
@ -406,12 +416,12 @@ export class Paging extends Feature {
}
// Last button
if (!this.btnLastPageHtml) {
var btnLast = createElm(INPUT,
let btnLast = createElm(INPUT,
['type', 'button'],
['value', this.btnLastPageText],
['title', 'Last']
);
btnLast.className = this.btnPageCssClass;
btnLast.className = this.btnCssClass;
addEvt(btnLast, 'click', evt.last);
btnLastSpan.appendChild(btnLast);
} else {
@ -420,12 +430,12 @@ export class Paging extends Feature {
}
// First button
if (!this.btnFirstPageHtml) {
var btnFirst = createElm(INPUT,
let btnFirst = createElm(INPUT,
['type', 'button'],
['value', this.btnFirstPageText],
['title', 'First']
);
btnFirst.className = this.btnPageCssClass;
btnFirst.className = this.btnCssClass;
addEvt(btnFirst, 'click', evt.first);
btnFirstSpan.appendChild(btnFirst);
} else {
@ -435,23 +445,22 @@ export class Paging extends Feature {
}
// paging elements (buttons+drop-down list) are added to defined element
if (!this.pagingTgtId) {
tf.setToolbar();
}
var targetEl = !this.pagingTgtId ? tf.mDiv : elm(this.pagingTgtId);
let targetEl = !this.tgtId ?
tf.feature('toolbar').container(this.toolbarPosition) :
elm(this.tgtId);
targetEl.appendChild(btnFirstSpan);
targetEl.appendChild(btnPrevSpan);
var pgBeforeSpan = createElm('span');
let pgBeforeSpan = createElm('span');
pgBeforeSpan.appendChild(createText(this.pageText));
pgBeforeSpan.className = this.nbPgSpanCssClass;
targetEl.appendChild(pgBeforeSpan);
targetEl.appendChild(slcPages);
var pgAfterSpan = createElm('span');
let pgAfterSpan = createElm('span');
pgAfterSpan.appendChild(createText(this.ofText));
pgAfterSpan.className = this.nbPgSpanCssClass;
targetEl.appendChild(pgAfterSpan);
var pgSpan = createElm('span');
let pgSpan = createElm('span');
pgSpan.className = this.nbPgSpanCssClass;
pgSpan.appendChild(createText(' ' + this.nbPages + ' '));
targetEl.appendChild(pgSpan);
@ -465,7 +474,7 @@ export class Paging extends Feature {
this.pgCont = pgSpan;
this.pgBefore = pgBeforeSpan;
this.pgAfter = pgAfterSpan;
this.pagingSlc = slcPages;
this.pageSlc = slcPages;
this.setPagingInfo();
@ -474,14 +483,15 @@ export class Paging extends Feature {
this.setPagingInfo(tf.validRowsIndex);
}
this.emitter.on(['after-filtering'], () => this.resetPagingInfo());
this.emitter.on(['change-page'],
(tf, pageNumber) => this.setPage(pageNumber));
this.emitter.on(['after-filtering'], bound(this.resetPagingInfo, this));
this.emitter.on(['change-page'], bound(this.changePageHandler, this));
this.emitter.on(['change-page-results'],
(tf, pageLength) => this.changeResultsPerPage(pageLength));
bound(this.changePageResultsHandler, this));
/** @inherited */
this.initialized = true;
this.emitter.emit('feature-initialized', this);
}
/**
@ -489,15 +499,11 @@ export class Paging extends Feature {
* @param {Boolean} filterTable Execute filtering once paging instanciated
*/
reset(filterTable = false) {
var tf = this.tf;
if (this.isEnabled()) {
return;
}
this.enable();
this.init();
if (filterTable) {
tf.filter();
this.tf.filter();
}
}
@ -516,36 +522,38 @@ export class Paging extends Feature {
* @param {Array} validRows Collection of valid rows
*/
setPagingInfo(validRows) {
var tf = this.tf;
var mdiv = !this.pagingTgtId ? tf.mDiv : elm(this.pagingTgtId);
let tf = this.tf;
let cont = !this.tgtId ?
tf.feature('toolbar').container(this.toolbarPosition) :
elm(this.tgtId);
//store valid rows indexes
tf.validRowsIndex = validRows || tf.getValidRows(true);
//calculate nb of pages
this.nbPages = Math.ceil(tf.validRowsIndex.length / this.pagingLength);
this.nbPages = Math.ceil(tf.validRowsIndex.length / this.pageLength);
//refresh page nb span
this.pgCont.innerHTML = this.nbPages;
//select clearing shortcut
if (this.pageSelectorType === SELECT) {
this.pagingSlc.innerHTML = '';
this.pageSlc.innerHTML = '';
}
if (this.nbPages > 0) {
mdiv.style.visibility = 'visible';
cont.style.visibility = 'visible';
if (this.pageSelectorType === SELECT) {
for (var z = 0; z < this.nbPages; z++) {
var opt = createOpt(z + 1, z * this.pagingLength, false);
this.pagingSlc.options[z] = opt;
for (let z = 0; z < this.nbPages; z++) {
let opt = createOpt(z + 1, z * this.pageLength, false);
this.pageSlc.options[z] = opt;
}
} else {
//input type
this.pagingSlc.value = this.currentPageNb;
this.pageSlc.value = this.currentPageNb;
}
} else {
/*** if no results paging select and buttons are hidden ***/
mdiv.style.visibility = 'hidden';
cont.style.visibility = 'hidden';
}
this.groupByPage(tf.validRowsIndex);
}
@ -555,10 +563,10 @@ export class Paging extends Feature {
* @param {Array} validRows Collection of valid rows
*/
groupByPage(validRows) {
var tf = this.tf;
var rows = tf.tbl.rows;
var startPagingRow = parseInt(this.startPagingRow, 10);
var endPagingRow = startPagingRow + parseInt(this.pagingLength, 10);
let tf = this.tf;
let rows = tf.dom().rows;
let startPagingRow = parseInt(this.startPagingRow, 10);
let endPagingRow = startPagingRow + parseInt(this.pageLength, 10);
//store valid rows indexes
if (validRows) {
@ -566,11 +574,11 @@ export class Paging extends Feature {
}
//this loop shows valid rows of current page
for (var h = 0, len = tf.getValidRowsNb(true); h < len; h++) {
var validRowIdx = tf.validRowsIndex[h];
var r = rows[validRowIdx];
var isRowValid = r.getAttribute('validRow');
var rowDisplayed = false;
for (let h = 0, len = tf.getValidRowsNb(true); h < len; h++) {
let validRowIdx = tf.validRowsIndex[h];
let r = rows[validRowIdx];
let isRowValid = r.getAttribute('validRow');
let rowDisplayed = false;
if (h >= startPagingRow && h < endPagingRow) {
if (isNull(isRowValid) || Boolean(isRowValid === 'true')) {
@ -601,11 +609,11 @@ export class Paging extends Feature {
* 'previous', 'last', 'first' or page number as per param
*/
setPage(cmd) {
var tf = this.tf;
let tf = this.tf;
if (!tf.isInitialized() || !this.isEnabled()) {
return;
}
var btnEvt = this.evt,
let btnEvt = this.evt,
cmdtype = typeof cmd;
if (cmdtype === 'string') {
switch (cmd.toLowerCase()) {
@ -635,10 +643,10 @@ export class Paging extends Feature {
* Generates UI elements for the number of results per page drop-down
*/
setResultsPerPage() {
var tf = this.tf;
var evt = this.evt;
let tf = this.tf;
let evt = this.evt;
if (this.resultsPerPageSlc || !this.resultsPerPage) {
if (this.pageLengthSlc || !this.resultsPerPage) {
return;
}
@ -647,22 +655,20 @@ export class Paging extends Feature {
ev.target.blur();
};
var slcR = createElm(SELECT);
let slcR = createElm(SELECT);
slcR.className = this.resultsSlcCssClass;
var slcRText = this.resultsPerPage[0],
let slcRText = this.resultsPerPage[0],
slcROpts = this.resultsPerPage[1];
var slcRSpan = createElm('span');
let slcRSpan = createElm('span');
slcRSpan.className = this.resultsSpanCssClass;
// results per page select is added to external element
if (!this.resultsPerPageTgtId) {
tf.setToolbar();
}
var targetEl = !this.resultsPerPageTgtId ?
tf.rDiv : elm(this.resultsPerPageTgtId);
let targetEl = !this.pageLengthTgtId ?
tf.feature('toolbar').container(RIGHT) :
elm(this.pageLengthTgtId);
slcRSpan.appendChild(createText(slcRText));
var help = tf.feature('help');
let help = tf.feature('help');
if (help && help.btn) {
help.btn.parentNode.insertBefore(slcRSpan, help.btn);
help.btn.parentNode.insertBefore(slcR, help.btn);
@ -671,31 +677,31 @@ export class Paging extends Feature {
targetEl.appendChild(slcR);
}
for (var r = 0; r < slcROpts.length; r++) {
var currOpt = new Option(slcROpts[r], slcROpts[r], false, false);
for (let r = 0; r < slcROpts.length; r++) {
let currOpt = new Option(slcROpts[r], slcROpts[r], false, false);
slcR.options[r] = currOpt;
}
addEvt(slcR, 'change', evt.slcResultsChange);
this.slcResultsTxt = slcRSpan;
this.resultsPerPageSlc = slcR;
this.pageLengthSlc = slcR;
}
/**
* Remove number of results per page UI elements
*/
removeResultsPerPage() {
var tf = this.tf;
if (!tf.isInitialized() || !this.resultsPerPageSlc ||
let tf = this.tf;
if (!tf.isInitialized() || !this.pageLengthSlc ||
!this.resultsPerPage) {
return;
}
if (this.resultsPerPageSlc) {
removeElm(this.resultsPerPageSlc);
if (this.pageLengthSlc) {
removeElm(this.pageLengthSlc);
}
if (this.slcResultsTxt) {
removeElm(this.slcResultsTxt);
}
this.resultsPerPageSlc = null;
this.pageLengthSlc = null;
this.slcResultsTxt = null;
}
@ -704,7 +710,7 @@ export class Paging extends Feature {
* @param {Number} index Index of the page (0-n)
*/
changePage(index) {
var tf = this.tf;
let tf = this.tf;
if (!this.isEnabled()) {
return;
@ -714,20 +720,20 @@ export class Paging extends Feature {
if (index === null) {
index = this.pageSelectorType === SELECT ?
this.pagingSlc.options.selectedIndex : this.pagingSlc.value - 1;
this.pageSlc.options.selectedIndex : this.pageSlc.value - 1;
}
if (index >= 0 && index <= (this.nbPages - 1)) {
this.onBeforeChangePage(this, (index + 1));
this.currentPageNb = parseInt(index, 10) + 1;
if (this.pageSelectorType === SELECT) {
this.pagingSlc.options[index].selected = true;
this.pageSlc.options[index].selected = true;
} else {
this.pagingSlc.value = this.currentPageNb;
this.pageSlc.value = this.currentPageNb;
}
this.startPagingRow = (this.pageSelectorType === SELECT) ?
this.pagingSlc.value : (index * this.pagingLength);
this.pageSlc.value : (index * this.pageLength);
this.groupByPage();
@ -746,7 +752,7 @@ export class Paging extends Feature {
return;
}
this.resultsPerPageSlc.value = val;
this.pageLengthSlc.value = val;
this.onChangeResultsPerPage();
}
@ -754,49 +760,51 @@ export class Paging extends Feature {
* Change rows according to page results drop-down
*/
onChangeResultsPerPage() {
var tf = this.tf;
let tf = this.tf;
if (!this.isEnabled()) {
if (!this.isEnabled() || tf.getValidRowsNb() === 0) {
return;
}
this.emitter.emit('before-page-length-change', tf);
let {
pageLengthSlc: slcR, pageSelectorType, pageSlc, emitter
} = this;
var slcR = this.resultsPerPageSlc;
var slcIndex = slcR.selectedIndex;
var slcPagesSelIndex = (this.pageSelectorType === SELECT) ?
this.pagingSlc.selectedIndex :
parseInt(this.pagingSlc.value - 1, 10);
this.pagingLength = parseInt(slcR.options[slcIndex].value, 10);
this.startPagingRow = this.pagingLength * slcPagesSelIndex;
emitter.emit('before-page-length-change', tf);
if (!isNaN(this.pagingLength)) {
let slcIndex = slcR.selectedIndex;
let slcPagesSelIndex = (pageSelectorType === SELECT) ?
pageSlc.selectedIndex : parseInt(pageSlc.value - 1, 10);
this.pageLength = parseInt(slcR.options[slcIndex].value, 10);
this.startPagingRow = this.pageLength * slcPagesSelIndex;
if (!isNaN(this.pageLength)) {
if (this.startPagingRow >= tf.nbFilterableRows) {
this.startPagingRow = (tf.nbFilterableRows - this.pagingLength);
this.startPagingRow = (tf.nbFilterableRows - this.pageLength);
}
this.setPagingInfo();
if (this.pageSelectorType === SELECT) {
var slcIdx =
(this.pagingSlc.options.length - 1 <= slcPagesSelIndex) ?
(this.pagingSlc.options.length - 1) : slcPagesSelIndex;
this.pagingSlc.options[slcIdx].selected = true;
if (pageSelectorType === SELECT) {
let slcIdx = (pageSlc.options.length - 1 <= slcPagesSelIndex) ?
(pageSlc.options.length - 1) :
slcPagesSelIndex;
pageSlc.options[slcIdx].selected = true;
}
}
this.emitter.emit('after-page-length-change', tf, this.pagingLength);
emitter.emit('after-page-length-change', tf, this.pageLength);
}
/**
* Re-set page nb at page re-load
*/
resetPage() {
var tf = this.tf;
let tf = this.tf;
if (!this.isEnabled()) {
return;
}
this.emitter.emit('before-reset-page', tf);
var pgNb = tf.feature('store').getPageNb();
let pgNb = tf.feature('store').getPageNb();
if (pgNb !== '') {
this.changePage((pgNb - 1));
}
@ -807,20 +815,30 @@ export class Paging extends Feature {
* Re-set page length value at page re-load
*/
resetPageLength() {
var tf = this.tf;
let tf = this.tf;
if (!this.isEnabled()) {
return;
}
this.emitter.emit('before-reset-page-length', tf);
var pglenIndex = tf.feature('store').getPageLength();
let pglenIndex = tf.feature('store').getPageLength();
if (pglenIndex !== '') {
this.resultsPerPageSlc.options[pglenIndex].selected = true;
this.pageLengthSlc.options[pglenIndex].selected = true;
this.changeResultsPerPage();
}
this.emitter.emit('after-reset-page-length', tf, pglenIndex);
}
/** @private */
changePageHandler(tf, pageNumber) {
this.setPage(pageNumber);
}
/** @private */
changePageResultsHandler(tf, pageLength) {
this.changeResultsPerPage(pageLength);
}
/**
* Remove paging feature
*/
@ -829,16 +847,16 @@ export class Paging extends Feature {
return;
}
var evt = this.evt;
let evt = this.evt;
if (this.pagingSlc) {
if (this.pageSlc) {
if (this.pageSelectorType === SELECT) {
removeEvt(this.pagingSlc, 'change', evt.slcPagesChange);
removeEvt(this.pageSlc, 'change', evt.slcPagesChange);
}
else if (this.pageSelectorType === INPUT) {
removeEvt(this.pagingSlc, 'keypress', evt._detectKey);
removeEvt(this.pageSlc, 'keypress', evt._detectKey);
}
removeElm(this.pagingSlc);
removeElm(this.pageSlc);
}
if (this.btnNextCont) {
@ -884,15 +902,15 @@ export class Paging extends Feature {
this.removeResultsPerPage();
}
this.emitter.off(['after-filtering'], () => this.resetPagingInfo());
this.emitter.off(['change-page'],
(tf, pageNumber) => this.setPage(pageNumber));
this.emitter.off(['after-filtering'],
bound(this.resetPagingInfo, this));
this.emitter.off(['change-page'], bound(this.changePageHandler, this));
this.emitter.off(['change-page-results'],
(tf, pageLength) => this.changeResultsPerPage(pageLength));
bound(this.changePageResultsHandler, this));
this.pagingSlc = null;
this.pageSlc = null;
this.nbPages = 0;
this.disable();
this.initialized = false;
}
}

View file

@ -1,9 +1,10 @@
import {Feature} from '../feature';
import {isFn, isUndef, EMPTY_FN} from '../types';
import {isUndef, EMPTY_FN} from '../types';
import {createElm, removeElm} from '../dom';
import {addEvt, cancelEvt, stopEvt, targetEvt, removeEvt} from '../event';
import {INPUT, NONE, CHECKLIST, MULTIPLE} from '../const';
import {root} from '../root';
import {defaultsStr, defaultsBool, defaultsArr, defaultsFn} from '../settings';
/**
* Pop-up filter component
@ -18,84 +19,81 @@ export class PopupFilter extends Feature {
* @param {TableFilter} tf TableFilter instance
*/
constructor(tf) {
super(tf, 'popupFilters');
super(tf, PopupFilter);
// Configuration object
let f = this.config;
// Enable external filters
tf.isExternalFlt = true;
tf.externalFltTgtIds = [];
let f = this.config.popup_filters || {};
/**
* Close active popup filter upon filtering, enabled by default
* @type {Boolean}
*/
this.closeOnFiltering = f.popup_filters_close_on_filtering === false ?
false : true;
this.closeOnFiltering = defaultsBool(f.close_on_filtering, true);
/**
* Filter icon path
* @type {String}
*/
this.iconPath = f.popup_filters_image ||
tf.themesPath + 'icn_filter.gif';
this.iconPath = defaultsStr(f.image, tf.themesPath + 'icn_filter.gif');
/**
* Active filter icon path
* @type {string}
*/
this.activeIconPath = f.popup_filters_image_active ||
tf.themesPath + 'icn_filterActive.gif';
this.activeIconPath = defaultsStr(f.image_active,
tf.themesPath + 'icn_filterActive.gif');
/**
* HTML for the filter icon
* @type {string}
*/
this.iconHtml = f.popup_filters_image_html ||
'<img src="' + this.iconPath + '" alt="Column filter" />';
this.iconHtml = defaultsStr(f.image_html,
'<img src="' + this.iconPath + '" alt="Column filter" />');
/**
* Css class assigned to the popup container element
* @type {String}
*/
this.placeholderCssClass = defaultsStr(f.placeholder_css_class,
'popUpPlaceholder');
/**
* Css class assigned to filter container element
* @type {String}
*/
this.containerCssClass = f.popup_div_css_class || 'popUpFilter';
this.containerCssClass = defaultsStr(f.div_css_class, 'popUpFilter');
/**
* Ensure filter's container element width matches column width, enabled
* by default
* @type {Boolean}
*/
this.adjustToContainer =
f.popup_filters_adjust_to_container === false ? false : true;
this.adjustToContainer = defaultsBool(f.adjust_to_container, true);
/**
* Callback fired before a popup filter is opened
* @type {Function}
*/
this.onBeforeOpen = isFn(f.on_before_popup_filter_open) ?
f.on_before_popup_filter_open : EMPTY_FN;
this.onBeforeOpen = defaultsFn(f.on_before_popup_filter_open, EMPTY_FN);
/**
* Callback fired after a popup filter is opened
* @type {Function}
*/
this.onAfterOpen = isFn(f.on_after_popup_filter_open) ?
f.on_after_popup_filter_open : EMPTY_FN;
this.onAfterOpen = defaultsFn(f.on_after_popup_filter_open, EMPTY_FN);
/**
* Callback fired before a popup filter is closed
* @type {Function}
*/
this.onBeforeClose = isFn(f.on_before_popup_filter_close) ?
f.on_before_popup_filter_close : EMPTY_FN;
this.onBeforeClose = defaultsFn(f.on_before_popup_filter_close,
EMPTY_FN);
/**
* Callback fired after a popup filter is closed
* @type {Function}
*/
this.onAfterClose = isFn(f.on_after_popup_filter_close) ?
f.on_after_popup_filter_close : EMPTY_FN;
this.onAfterClose = defaultsFn(f.on_after_popup_filter_close, EMPTY_FN);
/**
* Collection of filters spans
@ -123,7 +121,7 @@ export class PopupFilter extends Feature {
* @type {Array}
* @private
*/
this.fltElms = this.filtersCache || [];
this.fltElms = defaultsArr(this.filtersCache, []);
/**
* Prefix for pop-up filter container ID
@ -198,6 +196,12 @@ export class PopupFilter extends Feature {
let tf = this.tf;
// Enable external filters
tf.externalFltIds = [''];
// Override filters row index supplied by configuration
tf.filtersRowIndex = 0;
// Override headers row index if no grouped headers
// TODO: Because of the filters row generation, headers row index needs
// adjusting: prevent useless row generation
@ -246,18 +250,19 @@ export class PopupFilter extends Feature {
// adjusting: prevent useless row generation
tf.headersRow++;
for (let i = 0; i < tf.nbCells; i++) {
if (tf.getFilterType(i) === NONE) {
continue;
}
let icon = createElm('span', ['ci', i]);
icon.innerHTML = this.iconHtml;
let header = tf.getHeaderElement(i);
header.appendChild(icon);
addEvt(icon, 'click', (evt) => this.onClick(evt));
this.fltSpans[i] = icon;
this.fltIcons[i] = icon.firstChild;
}
tf.eachCol(
(i) => {
let icon = createElm('span', ['ci', i]);
icon.innerHTML = this.iconHtml;
let header = tf.getHeaderElement(i);
header.appendChild(icon);
addEvt(icon, 'click', (evt) => this.onClick(evt));
this.fltSpans[i] = icon;
this.fltIcons[i] = icon.firstChild;
},
// continue condition function
(i) => tf.getFilterType(i) === NONE
);
}
/**
@ -277,12 +282,14 @@ export class PopupFilter extends Feature {
build(colIndex, div) {
let tf = this.tf;
let contId = `${this.prfxDiv}${tf.id}_${colIndex}`;
let cont = div || createElm('div', ['id', contId]);
cont.className = this.containerCssClass;
tf.externalFltTgtIds.push(cont.id);
let placeholder = createElm('div', ['class', this.placeholderCssClass]);
let cont = div ||
createElm('div', ['id', contId], ['class', this.containerCssClass]);
tf.externalFltIds[colIndex] = cont.id;
placeholder.appendChild(cont);
let header = tf.getHeaderElement(colIndex);
header.insertBefore(cont, header.firstChild);
header.insertBefore(placeholder, header.firstChild);
addEvt(cont, 'click', (evt) => stopEvt(evt));
this.fltElms[colIndex] = cont;
}
@ -364,7 +371,7 @@ export class PopupFilter extends Feature {
if (i === exceptIdx) {
continue;
}
let fltType = tf.getFilterType(i);
let fltType = this.tf.getFilterType(i);
let isMultipleFilter =
(fltType === CHECKLIST || fltType === MULTIPLE);
@ -408,6 +415,7 @@ export class PopupFilter extends Feature {
this.filtersCache = [];
for (let i = 0; i < this.fltElms.length; i++) {
let container = this.fltElms[i],
placeholder = container.parentNode,
icon = this.fltSpans[i],
iconImg = this.fltIcons[i];
if (container) {
@ -415,6 +423,10 @@ export class PopupFilter extends Feature {
this.filtersCache[i] = container;
}
container = null;
if (placeholder) {
removeElm(placeholder);
}
placeholder = null;
if (icon) {
removeElm(icon);
}
@ -429,7 +441,7 @@ export class PopupFilter extends Feature {
this.fltIcons = [];
// TODO: expose an API to handle external filter IDs
tf.externalFltTgtIds = [];
this.tf.externalFltIds = [];
// unsubscribe to events
this.emitter.off(['before-filtering'], () => this.setIconsState());
@ -444,3 +456,6 @@ export class PopupFilter extends Feature {
}
}
// TODO: remove as soon as feature name is fixed
PopupFilter.meta = {altName: 'popupFilters'};

View file

@ -1,6 +1,8 @@
import {Feature} from '../feature';
import {createElm, createText, elm, removeElm} from '../dom';
import {isFn, EMPTY_FN} from '../types';
import {EMPTY_FN, isNull} from '../types';
import {defaultsStr, defaultsFn} from '../settings';
import {LEFT} from './toolbar';
/**
* Rows counter UI component
@ -15,16 +17,16 @@ export class RowsCounter extends Feature {
* @param {TableFilter} tf TableFilter instance
*/
constructor(tf) {
super(tf, 'rowsCounter');
super(tf, RowsCounter);
// TableFilter configuration
let f = this.config;
let f = this.config.rows_counter || {};
/**
* ID of custom container element
* @type {String}
*/
this.targetId = f.rows_counter_target_id || null;
this.targetId = defaultsStr(f.target_id, null);
/**
* Container DOM element
@ -44,14 +46,14 @@ export class RowsCounter extends Feature {
* Text preceding the total number of rows
* @type {String}
*/
this.text = f.rows_counter_text || 'Rows: ';
this.text = defaultsStr(f.text, 'Rows: ');
/**
* Separator symbol appearing between the first and last visible rows of
* current page when paging is enabled. ie: Rows: 31-40 / 70
* @type {String}
*/
this.fromToTextSeparator = f.from_to_text_separator || '-';
this.fromToTextSeparator = defaultsStr(f.separator, '-');
/**
* Separator symbol appearing between the first and last visible rows of
@ -59,27 +61,33 @@ export class RowsCounter extends Feature {
* enabled. ie: Rows: 31-40 / 70
* @type {String}
*/
this.overText = f.over_text || ' / ';
this.overText = defaultsStr(f.over_text, ' / ');
/**
* Css class for container element
* @type {String}
*/
this.cssClass = f.tot_rows_css_class || 'tot';
this.cssClass = defaultsStr(f.css_class, 'tot');
/**
* Default position in toolbar ('left'|'center'|'right')
* @type {String}
*/
this.toolbarPosition = defaultsStr(f.toolbar_position, LEFT);
/**
* Callback fired before the counter is refreshed
* @type {Function}
*/
this.onBeforeRefreshCounter = isFn(f.on_before_refresh_counter) ?
f.on_before_refresh_counter : EMPTY_FN;
this.onBeforeRefreshCounter = defaultsFn(f.on_before_refresh_counter,
EMPTY_FN);
/**
* Callback fired after the counter is refreshed
* @type {Function}
*/
this.onAfterRefreshCounter = isFn(f.on_after_refresh_counter) ?
f.on_after_refresh_counter : EMPTY_FN;
this.onAfterRefreshCounter = defaultsFn(f.on_after_refresh_counter,
EMPTY_FN);
}
/**
@ -90,6 +98,8 @@ export class RowsCounter extends Feature {
return;
}
this.emitter.emit('initializing-feature', this, !isNull(this.targetId));
let tf = this.tf;
//rows counter container
@ -101,18 +111,16 @@ export class RowsCounter extends Feature {
countText.appendChild(createText(this.text));
// counter is added to defined element
if (!this.targetId) {
tf.setToolbar();
}
let targetEl = !this.targetId ? tf.lDiv : elm(this.targetId);
let targetEl = !this.targetId ?
tf.feature('toolbar').container(this.toolbarPosition) :
elm(this.targetId);
//default container: 'lDiv'
if (!this.targetId) {
countDiv.appendChild(countText);
countDiv.appendChild(countSpan);
targetEl.appendChild(countDiv);
}
else {
} else {
//custom container, no need to append statusDiv
targetEl.appendChild(countText);
targetEl.appendChild(countSpan);
@ -128,12 +136,13 @@ export class RowsCounter extends Feature {
/** @inherited */
this.initialized = true;
this.refresh();
this.emitter.emit('feature-initialized', this);
}
/**
* Refreshes the rows counter
* @param {Number} p Optional parameter the total number of rows to display
* @returns
*/
refresh(p) {
if (!this.initialized || !this.isEnabled()) {
@ -154,16 +163,17 @@ export class RowsCounter extends Feature {
} else {
let paging = tf.feature('paging');
if (paging) {
let nbValidRows = tf.getValidRowsNb();
//paging start row
let pagingStartRow = parseInt(paging.startPagingRow, 10) +
((tf.getValidRowsNb() > 0) ? 1 : 0);
((nbValidRows > 0) ? 1 : 0);
let pagingEndRow =
(pagingStartRow + paging.pagingLength) - 1 <=
tf.getValidRowsNb() ?
pagingStartRow + paging.pagingLength - 1 :
tf.getValidRowsNb();
(pagingStartRow + paging.pageLength) - 1 <=
nbValidRows ?
pagingStartRow + paging.pageLength - 1 :
nbValidRows;
totTxt = pagingStartRow + this.fromToTextSeparator +
pagingEndRow + this.overText + tf.getValidRowsNb();
pagingEndRow + this.overText + nbValidRows;
}
}

View file

@ -3,6 +3,7 @@ import {Hash} from './hash';
import {Storage} from './storage';
import {isEmpty} from '../string';
import {isArray, isNull, isString, isUndef} from '../types';
import {defaultsBool, defaultsNb} from '../settings';
/**
* Features state object persistable with localStorage, cookie or URL hash
@ -18,9 +19,9 @@ export class State extends Feature {
* @param {TableFilter} tf TableFilter instance
*/
constructor(tf) {
super(tf, 'state');
super(tf, State);
let cfg = this.config.state;
let cfg = this.config.state || {};
/**
* Determines whether state is persisted with URL hash
@ -47,7 +48,7 @@ export class State extends Feature {
* Persist filters values, enabled by default
* @type {Boolean}
*/
this.persistFilters = cfg.filters === false ? false : true;
this.persistFilters = defaultsBool(cfg.filters, true);
/**
* Persist current page number when paging is enabled
@ -83,8 +84,8 @@ export class State extends Feature {
* Cookie duration in hours
* @type {Boolean}
*/
this.cookieDuration = !isNaN(cfg.cookie_duration) ?
parseInt(cfg.cookie_duration, 10) : 87600;
this.cookieDuration = defaultsNb(parseInt(cfg.cookie_duration, 10),
87600);
/**
* Enable Storage if localStorage or cookie is required
@ -212,9 +213,7 @@ export class State extends Feature {
this.storage.init();
}
/**
* @inherited
*/
/** @inherited */
this.initialized = true;
}
@ -366,6 +365,7 @@ export class State extends Feature {
*/
override(state) {
this.state = state;
this.emitter.emit('state-changed', this.tf, state);
}
/**
@ -421,6 +421,10 @@ export class State extends Feature {
let state = this.state;
let tf = this.tf;
// clear all filters
// TODO: use tf.clearFilters() once it allows to not filter the table
tf.eachCol((colIdx) => tf.setFilterValue(colIdx, ''));
Object.keys(state).forEach((key) => {
if (key.indexOf(this.prfxCol) !== -1) {
let colIdx = parseInt(key.replace(this.prfxCol, ''), 10);

View file

@ -1,7 +1,9 @@
import {Feature} from '../feature';
import {root} from '../root';
import {createElm, createText, elm, removeElm} from '../dom';
import {isFn, EMPTY_FN} from '../types';
import {EMPTY_FN, isNull} from '../types';
import {defaultsStr, defaultsFn} from '../settings';
import {LEFT} from './toolbar';
const EVENTS = [
'after-filtering',
@ -28,16 +30,16 @@ export class StatusBar extends Feature {
* @param {TableFilter} tf TableFilter instance
*/
constructor(tf) {
super(tf, 'statusBar');
super(tf, StatusBar);
// Configuration object
let f = this.config;
let f = this.config.status_bar || {};
/**
* ID of custom container element
* @type {String}
*/
this.targetId = f.status_bar_target_id || null;
this.targetId = defaultsStr(f.target_id, null);
/**
* Container DOM element
@ -64,13 +66,13 @@ export class StatusBar extends Feature {
* Text preceding status message
* @type {String}
*/
this.text = f.status_bar_text || '';
this.text = defaultsStr(f.text, '');
/**
* Css class for container element
* @type {String}
*/
this.cssClass = f.status_bar_css_class || 'status';
this.cssClass = defaultsStr(f.css_class, 'status');
/**
* Message visibility duration in milliseconds
@ -83,85 +85,91 @@ export class StatusBar extends Feature {
* Callback fired before the message is displayed
* @type {Function}
*/
this.onBeforeShowMsg = isFn(f.on_before_show_msg) ?
f.on_before_show_msg : EMPTY_FN;
this.onBeforeShowMsg = defaultsFn(f.on_before_show_msg, EMPTY_FN);
/**
* Callback fired after the message is displayed
* @type {Function}
*/
this.onAfterShowMsg = isFn(f.on_after_show_msg) ?
f.on_after_show_msg : EMPTY_FN;
this.onAfterShowMsg = defaultsFn(f.on_after_show_msg, EMPTY_FN);
/**
* Message appearing upon filtering
* @type {String}
*/
this.msgFilter = f.msg_filter || 'Filtering data...';
this.msgFilter = defaultsStr(f.msg_filter, 'Filtering data...');
/**
* Message appearing when a drop-down filter is populated
* @type {String}
*/
this.msgPopulate = f.msg_populate || 'Populating filter...';
this.msgPopulate = defaultsStr(f.msg_populate, 'Populating filter...');
/**
* Message appearing when a checklist filter is populated
* @type {String}
*/
this.msgPopulateCheckList = f.msg_populate_checklist ||
'Populating list...';
this.msgPopulateCheckList = defaultsStr(f.msg_populate_checklist,
'Populating list...');
/**
* Message appearing when a pagination page is changed
* @type {String}
*/
this.msgChangePage = f.msg_change_page || 'Collecting paging data...';
this.msgChangePage = defaultsStr(f.msg_change_page,
'Collecting paging data...');
/**
* Message appearing when filters are cleared
* @type {String}
*/
this.msgClear = f.msg_clear || 'Clearing filters...';
this.msgClear = defaultsStr(f.msg_clear, 'Clearing filters...');
/**
* Message appearing when the page length is changed
* @type {String}
*/
this.msgChangeResults = f.msg_change_results ||
'Changing results per page...';
this.msgChangeResults = defaultsStr(f.msg_change_results,
'Changing results per page...');
/**
* Message appearing when the page is re-set
* @type {String}
*/
this.msgResetPage = f.msg_reset_page || 'Re-setting page...';
this.msgResetPage = defaultsStr(f.msg_reset_page, 'Re-setting page...');
/**
* Message appearing when the page length is re-set
* @type {String}
*/
this.msgResetPageLength = f.msg_reset_page_length ||
'Re-setting page length...';
this.msgResetPageLength = defaultsStr(f.msg_reset_page_length,
'Re-setting page length...');
/**
* Message appearing upon column sorting
* @type {String}
*/
this.msgSort = f.msg_sort || 'Sorting data...';
this.msgSort = defaultsStr(f.msg_sort, 'Sorting data...');
/**
* Message appearing when extensions are loading
* @type {String}
*/
this.msgLoadExtensions = f.msg_load_extensions ||
'Loading extensions...';
this.msgLoadExtensions = defaultsStr(f.msg_load_extensions,
'Loading extensions...');
/**
* Message appearing when themes are loading
* @type {String}
*/
this.msgLoadThemes = f.msg_load_themes || 'Loading theme(s)...';
this.msgLoadThemes = defaultsStr(f.msg_load_themes,
'Loading theme(s)...');
/**
* Default position in toolbar ('left'|'center'|'right')
* @type {String}
*/
this.toolbarPosition = defaultsStr(f.toolbar_position, LEFT);
}
/**
@ -175,23 +183,24 @@ export class StatusBar extends Feature {
let tf = this.tf;
let emitter = this.emitter;
//status bar container
emitter.emit('initializing-feature', this, !isNull(this.targetId));
// status bar container
let statusDiv = createElm('div');
statusDiv.className = this.cssClass;
//status bar label
// status bar label
let statusSpan = createElm('span');
//preceding text
// preceding text
let statusSpanText = createElm('span');
statusSpanText.appendChild(createText(this.text));
// target element container
if (!this.targetId) {
tf.setToolbar();
}
let targetEl = (!this.targetId) ? tf.lDiv : elm(this.targetId);
let targetEl = (!this.targetId) ?
tf.feature('toolbar').container(this.toolbarPosition) :
elm(this.targetId);
//default container: 'lDiv'
// default container
if (!this.targetId) {
statusDiv.appendChild(statusSpanText);
statusDiv.appendChild(statusSpan);
@ -206,7 +215,7 @@ export class StatusBar extends Feature {
this.msgContainer = statusSpan;
this.labelContainer = statusSpanText;
// Subscribe to events
// subscribe to events
emitter.on(['before-filtering'], () => this.message(this.msgFilter));
emitter.on(['before-populating-filter'],
() => this.message(this.msgPopulate));
@ -227,10 +236,10 @@ export class StatusBar extends Feature {
emitter.on(EVENTS, () => this.message(''));
/**
* @inherited
*/
/** @inherited */
this.initialized = true;
emitter.emit('feature-initialized', this);
}
/**

View file

@ -1,4 +1,3 @@
import Cookie from '../cookie';
import {root} from '../root';

224
src/modules/toolbar.js Normal file
View file

@ -0,0 +1,224 @@
import {Feature} from '../feature';
import {createElm, removeElm, elm, tag} from '../dom';
import {defaultsStr} from '../settings';
import {isUndef} from '../types';
const EVENTS = [
'initializing-feature',
'initializing-extension'
];
/** Left position in toolbar */
export const LEFT = 'left';
/** Right position in toolbar */
export const RIGHT = 'right';
/** Center position in toolbar */
export const CENTER = 'center';
/**
* Toolbar UI component
* @export
* @class Toolbar
* @extends {Feature}
*/
export class Toolbar extends Feature {
/**
* Create an instance of Toolbar
* @param {TableFilter} tf TableFilter instance
* @memberof Toolbar
*/
constructor(tf) {
super(tf, Toolbar);
// Configuration object
let f = this.config.toolbar || {};
/**
* Css class for toolbar's container DOM element
* @type {String}
*/
this.contCssClass = defaultsStr(f.container_css_class, 'inf');
/**
* Css class for left-side inner container DOM element
* @type {String}
*/
this.lContCssClass = defaultsStr(f.left_cont_css_class, 'ldiv');
/**
* Css class for right-side inner container DOM element
* @type {String}
*/
this.rContCssClass = defaultsStr(f.right_cont_css_class, 'rdiv');
/**
* Css class for middle inner container DOM element
* @type {String}
*/
this.cContCssClass = defaultsStr(f.center_cont_css_class, 'mdiv');
/**
* Toolbar's custom container ID
* @type {String}
*/
this.tgtId = defaultsStr(f.target_id, null);
/**
* Toolbar's container DOM element
* @type {DOMElement}
* @private
*/
this.cont = null;
/**
* Left-side inner container DOM element (rows counter in toolbar)
* @type {DOMElement}
* @private
*/
this.lCont = null;
/**
* Right-side inner container DOM element (reset button,
* page length selector in toolbar)
* @type {DOMElement}
* @private
*/
this.rCont = null;
/**
* Middle inner container DOM element (paging elements in toolbar)
* @type {DOMElement}
* @private
*/
this.cCont = null;
/**
* Container elements inside toolbar
* @private
*/
this.innerCont = {
left: null,
center: null,
right: null
};
this.emitter.on(EVENTS,
(feature, isExternal) => this.init(isExternal));
/** @inherited */
this.enabled = true;
}
/**
* Initialize toolbar components
* @param {Boolean} isExternal initialize only if component belongs
* to toolbar
*/
init(isExternal) {
if (this.initialized || isExternal) {
return;
}
let tf = this.tf;
// default container
let container = createElm('div');
container.className = this.contCssClass;
// custom container
if (this.tgtId) {
elm(this.tgtId).appendChild(container);
}
// grid-layout
else if (tf.gridLayout) {
let gridLayout = tf.Mod.gridLayout;
gridLayout.tblMainCont.appendChild(container);
container.className = gridLayout.infDivCssClass;
}
// default location: just above the table
else {
let cont = createElm('caption');
cont.appendChild(container);
tf.dom().insertBefore(cont, tf.dom().firstChild);
}
this.cont = container;
// left container
this.lCont = this.createContainer(container, this.lContCssClass);
// right container
this.rCont = this.createContainer(container, this.rContCssClass);
// middle container
this.cCont = this.createContainer(container, this.cContCssClass);
this.innerCont = {
left: this.lCont,
center: this.cCont,
right: this.rCont
};
/** @inherited */
this.initialized = true;
// emit help initialisation only if undefined
if (isUndef(tf.help)) {
// explicitily enable help to initialise feature by
// default, only if setting is undefined
tf.Mod.help.enable();
this.emitter.emit('init-help', tf);
}
}
/**
* Return the container based on requested position inside the toolbar
* @param {String} [position=RIGHT] 3 possible positions: 'left', 'center',
* 'right'
* @param {DOMElement} el optional DOM element to be inserter in container
* @returns {DOMElement}
*/
container(position = RIGHT, el) {
let cont = this.innerCont[position];
if (el) {
cont.appendChild(el);
}
return cont;
}
/**
* Create DOM element inside passed container
* @param {DOMElement} container
* @param {String} css
* @private
*/
createContainer(container, css) {
let div = createElm('div', ['class', css]);
container.appendChild(div);
return div;
}
/**
* Destroy Toolbar instance
*/
destroy() {
if (!this.initialized) {
return;
}
let tf = this.tf;
removeElm(this.cont);
this.cont = null;
let tbl = tf.dom();
let captions = tag(tbl, 'caption');
[].forEach.call(captions, (el) => removeElm(el));
/** @inherited */
this.initialized = false;
}
}
// TODO: remove as soon as feature name is fixed
Toolbar.meta = {alwaysInstantiate: true};

View file

@ -19,11 +19,14 @@ export const parse = (value, decimal = '.') => {
let regex = new RegExp('[^0-9-' + decimal + ']', ['g']);
let unformatted = parseFloat(
('' + value)
.replace(/\((.*)\)/, '-$1') // replace bracketed values with negatives
.replace(regex, '') // strip out any cruft
.replace(decimal, '.') // make sure decimal point is standard
// replace bracketed values with negatives
.replace(/\((.*)\)/, '-$1')
// strip out any cruft
.replace(regex, '')
// make sure decimal point is standard
.replace(decimal, '.')
);
// This will fail silently
return !isNaN(unformatted) ? unformatted : 0;
}
};

53
src/settings.js Normal file
View file

@ -0,0 +1,53 @@
import {isBoolean, isString, isFn, isArray} from './types';
/** Configuration settings helpers */
/**
* If passed value is not of boolean type return the default value
* otherwise return the value itself
* @param {Boolean|Any} value
* @param {Boolean} default value
* @return {Boolean|Any}
*/
export const defaultsBool =
(val, defaultVal) => isBoolean(val) ? val : defaultVal;
/**
* If passed value is not of string type return the default value
* otherwise return the value itself
* @param {String|Any} value
* @param {String} default value
* @return {String|Any}
*/
export const defaultsStr =
(val, defaultVal) => isString(val) ? val : defaultVal;
/**
* If passed value is not of number type return the default value
* otherwise return the value itself
* @param {Number|Any} value
* @param {Number} default value
* @return {Number|Any}
*/
export const defaultsNb =
(val, defaultVal) => isNaN(val) ? defaultVal : val;
/**
* If passed value is not of array type return the default value
* otherwise return the value itself
* @param {Array|Any} value
* @param {Array} default value
* @return {Array|Any}
*/
export const defaultsArr =
(val, defaultVal) => isArray(val) ? val : defaultVal;
/**
* If passed value is not of function type return the default value
* otherwise return the value itself
* @param {Function|Any} value
* @param {Function} default value
* @return {Function|Any}
*/
export const defaultsFn =
(val, defaultVal) => isFn(val) ? val : defaultVal;

View file

@ -1,6 +1,7 @@
/**
* Sorting utilities
*/
import {parse as parseNb} from './number';
import {Date as SugarDate} from 'sugar-date';
/** Sorting utilities */
/**
* Case insensitive compare function for passed strings
@ -13,21 +14,69 @@
export const ignoreCase = (a, b) => {
let x = a.toLowerCase();
let y = b.toLowerCase();
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}
return x < y ? -1 : (x > y ? 1 : 0);
};
/**
* Sorts passed numbers in a ascending manner
* Compare function for sorting passed numbers in ascending manner
* @param {Number} First number
* @param {Number} Second number
* @param {Number} Negative, zero or positive number
* @return {Number} Negative, zero or positive number
*/
export const numSortAsc = (a, b) => (a - b);
/**
* Sorts passed numbers in a descending manner
* Compare function for sorting passed numbers in descending manner
* @param {Number} First number
* @param {Number} Second number
* @param {Number} Negative, zero or positive number
* @return {Number} Negative, zero or positive number
*/
export const numSortDesc = (a, b) => (b - a);
/**
* Compare function for sorting passed dates in ascending manner according to
* the corresponding UTC numeric value (returned by getTime)
* @param {Date} First date object
* @param {Date} Second date object
* @return {Number} Negative, zero or positive number
*/
export const dateSortAsc = (date1, date2) => date1.getTime() - date2.getTime();
/**
* Compare function for sorting passed dates in descending manner according to
* the corresponding UTC numeric value (returned by getTime)
* @param {Date} First date object
* @param {Date} Second date object
* @return {Number} Negative, zero or positive number
*/
export const dateSortDesc = (date1, date2) => date2.getTime() - date1.getTime();
/**
* Curried compare function for sorting passed formatted numbers in desired
* fashion according to supplied compare function and decimal separator
* @param {Function} Compare function
* @param {String} [decimal=','] Decimal separator
* @return {Function} Compare function receiving parsed numeric arguments
*/
export const sortNumberStr = (compareFn, decimal = ',') => {
return (numStr1, numStr2) => {
let num1 = parseNb(numStr1, decimal);
let num2 = parseNb(numStr2, decimal);
return compareFn(num1, num2);
};
};
/**
* Curried compare function for sorting passed formatted dates in desired
* fashion according to supplied compare function and locale
* @param {Function} Compare function
* @param {String} [locale='en-us'] Locale code
* @return {Function} Compare function receiving parsed date arguments
*/
export const sortDateStr = (compareFn, locale = 'en-us') => {
return (dateStr1, dateStr2) => {
let date1 = SugarDate.create(dateStr1, locale);
let date2 = SugarDate.create(dateStr2, locale);
return compareFn(date1, date2);
};
};

View file

@ -14,7 +14,7 @@ export const trim = (text) => {
return text.trim();
}
return text.replace(/^\s*|\s*$/g, '');
}
};
/**
* Checks if passed string is empty
@ -32,7 +32,7 @@ export const rgxEsc = (text) => {
let chars = /[-\/\\^$*+?.()|[\]{}]/g;
let escMatch = '\\$&';
return String(text).replace(chars, escMatch);
}
};
/**
* Returns passed string as lowercase if caseSensitive flag set false. By
@ -45,7 +45,7 @@ export const matchCase = (text, caseSensitive = false) => {
return text.toLowerCase();
}
return text;
}
};
/**
* Checks if passed data contains the searched term
@ -73,4 +73,40 @@ export const contains = (term, data, exactMatch = false, caseSensitive = false,
regexp = new RegExp(rgxEsc(term), modifier);
}
return regexp.test(data);
}
};
/**
* Camelize a string, cutting the string by multiple separators like
* hyphens, underscores and spaces.
* @param {String} text text to camelize
* @return {String} camelized text
*/
export const toCamelCase = (text = '') => {
return text.replace(/^([A-Z])|[\s-_]+(\w)/g, (match, p1, p2) => {
if (p2) {
return p2.toUpperCase();
}
return p1.toLowerCase();
});
};
/**
* Generate a string in the format of a UUID (Universally Unique IDentifier).
* NOTE: This format of 8 chars, followed by 3 groups of 4 chars, followed by 12
* chars is known as a UUID and is defined in RFC4122 and is a standard for
* generating unique IDs. This function DOES NOT implement this standard.
* It simply outputs a string that looks similar. The standard is found here:
* https://www.ietf.org/rfc/rfc4122.txt
* source: https://gist.github.com/gordonbrander/2230317
* @return {String}
*/
export const uuid = () => {
const chr4 = () => Math.random().toString(16).slice(-4);
return chr4() + chr4()
+ '-' + chr4()
+ '-' + chr4()
+ '-' + chr4()
+ '-' + chr4()
+ chr4() + chr4();
};

File diff suppressed because it is too large Load diff

View file

@ -37,7 +37,7 @@ export const isArray =
/**
* Check passed argument is a string
* @param {String} obj objue
* @param {String} obj obj
* @returns {Boolean}
*/
export const isString =
@ -51,6 +51,14 @@ export const isString =
export const isNumber =
(obj) => Object.prototype.toString.call(obj) === '[object Number]';
/**
* Check passed argument is a boolean
* @param {Boolean} obj
* @returns {Boolean}
*/
export const isBoolean =
(obj) => Object.prototype.toString.call(obj) === '[object Boolean]';
/**
* Check passed argument is undefined
* @param {Any} obj

File diff suppressed because it is too large Load diff

View file

@ -5,3 +5,6 @@
.activeHeader
background-color #66AFE9 !important
color #fff !important
.activeCell
background-color rgba(0,0,0,0.075)

View file

@ -34,7 +34,7 @@ div.colVisCont
z-index 10000
padding 10px 10px 10px 10px
text-align left
font-size 12px
font-size inherit
p
margin 6px auto 6px auto
@ -47,7 +47,7 @@ div.colVisCont
ul.cols_checklist
padding 0
margin 0
list-style none
list-style-type none
label
display block

View file

@ -11,7 +11,7 @@ $item-font-color = #fff
.div_checklist
width 100%
height 90px
line-height 24px
line-height 30px
border 1px solid $filter-border-color
overflow auto
text-align left
@ -27,19 +27,20 @@ $item-font-color = #fff
li.flt_checklist_item
padding 1px !important
margin 0 !important
font-size 10px !important
font-size inherit
border-bottom 1px solid $filter-border-color !important
&:hover
background-color $item-bg-color !important
color $item-font-color !important;
color $item-font-color !important
label
display block !important;
display block !important
font-weight inherit !important
input
vertical-align middle !important;
margin 2px 5px 2px 1px !important;
vertical-align middle !important
margin 2px 5px 3px 1px !important
// disabled checklist item
.flt_checklist_item_disabled

View file

@ -43,6 +43,7 @@
// input and select filter type
.flt
font-family inherit
font-size inherit
display block
color $filter-font-color
background-color $filter-bg-color
@ -64,6 +65,7 @@
// multiple select type filter
select.flt_multi
font-family inherit
font-size inherit
color $filter-font-color
background-color $filter-bg-color
border 1px solid $filter-border-color
@ -92,7 +94,7 @@ select.flt_multi
box-sizing initial
display initial
// Pop-up filters elements
// pop-up filters elements
div.popUpFilter
arrow(top, 10px white, 2px $th-bg-color)
box-shadow(3px 3px 2px #888)
@ -103,3 +105,7 @@ div.popUpFilter
background-color $th-bg-color
border 1px solid $filter-row-bg-color
padding 0
// pop-up container
.popUpPlaceholder
position relative

View file

@ -11,7 +11,6 @@ div.grd_Cont
width 800px
height auto
overflow hidden
padding 3px 3px 3px 3px
background-color $grid-layout-bg-color
border 1px solid $grid-layout-border-color
@ -50,8 +49,9 @@ div.grd_tblCont
// headers' table container
div.grd_headTblCont
display block
margin-right 20px
height auto
width 800px
overflow hidden
border-bottom 1px solid $grid-layout-border-color
background-color $grid-layout-bg-color
@ -63,10 +63,6 @@ div.grd_headTblCont table
table-layout fixed
box-sizing initial
div.grd_tblCont table
border-right 1px solid $grid-layout-border-color
box-sizing initial
// headers
div.grd_tblCont table th
div.grd_headTblCont table th

View file

@ -32,6 +32,7 @@ div.helpCont
color #333
background #fff
text-align left
z-index 1000
a
color #cc0000

View file

@ -0,0 +1,7 @@
/**
* Empty content mixin
*/
empty-content()
&:empty:after
content "\00A0"

View file

@ -14,3 +14,8 @@ input.reset
&:hover
background-color $toolbar-hover-color
a.reset
font-weight normal !important
line-height $min-height
padding 5px 5px

View file

@ -26,11 +26,19 @@ table.TF
margin 0
padding $padding
border-bottom 1px solid $td-border-color
text-overflow ellipsis
// responsiveness
// responsive
&.resp
display block
overflow-x auto
overflow-y hidden
.sort-arrow
position initial
// stick headers
&.sticky
th
position sticky
top -1px

View file

@ -0,0 +1,18 @@
/** Main stylesheet */
@import 'active-header'
@import 'alternating-rows'
@import 'ezedittable'
@import 'filter-checklist'
@import 'filters'
@import 'grid-layout'
@import 'help'
@import 'keyword'
@import 'loader'
@import 'noresults'
@import 'paging'
@import 'reset-button'
@import 'rows-counter'
@import 'sort'
@import 'status-bar'
@import 'table'
@import 'toolbar'

View file

@ -3,12 +3,14 @@
*/
@import 'config'
@import 'mixins/empty-content'
// left, middle and right divs container (toolbar)
.inf
clear both
width auto
height $min-height
min-width 400px
background-color $toolbar-bg-color
font-size $toolbar-font-size
margin 0
@ -32,25 +34,25 @@
// left div
.ldiv
empty-content()
float left
width 30%
// height 100%
position inherit
text-align left
// middle div
.mdiv
empty-content()
float left
width 38%
// height 100%
position inherit
text-align center
padding 0
// right div
.rdiv
empty-content()
float right
width 30%
// height 100%
position inherit
text-align right

View file

@ -49,8 +49,9 @@
<script data-config>
var filtersConfig = {
base_path: '../dist/tablefilter/',
grid_layout: true,
grid_width: '900px',
grid_layout: {
width: '900px'
},
alternate_rows: true,
btn_reset: true,
rows_counter: true,

View file

@ -19,15 +19,18 @@
<script data-config>
var filtersConfig = {
base_path: '../dist/tablefilter/',
auto_filter: true,
auto_filter_delay: 750, //milliseconds
auto_filter: {
delay: 750 // milliseconds
},
filters_row_index: 1,
state: true,
alternate_rows: true,
rows_counter: true,
rows_counter_text: 'Rows: ',
rows_counter: {
text: 'Rows: '
},
btn_reset: true,
status_bar: true,
sticky_headers: true,
msg_filter: 'Filtering...'
};

View file

@ -39,8 +39,9 @@ var tfConfig = {
},
alternate_rows: true,
rows_counter: true,
btn_reset: true,
btn_reset_text: 'Clear',
btn_reset: {
text: 'Clear'
},
status_bar: true,
col_1: 'select',
col_2: 'select',

View file

@ -32,40 +32,6 @@ var id = function (id){
var table = id('demo-tot');
var totRowIndex = table.getElementsByTagName('tr').length;
function addCommas(nStr){
nStr += '';
var x = nStr.split('.');
var x1 = x[0];
var x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
function addDots(nStr){
nStr += '';
var x = nStr.split('.');
var x1 = x[0];
var x2 = x.length > 1 ? ',' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + '.' + '$2');
}
return x1 + x2;
}
function formatTotals(){
var tot1 = id('sum1').innerHTML;
tot1 = addDots(tot1);
id('sum1').innerHTML = tot1;
var tot2 = id('sum2').innerHTML;
tot2 = addCommas(tot2);
id('sum2').innerHTML = tot2;
}
/* EXAMPLE 1
*********************** */
var tfConfig = {
@ -107,7 +73,10 @@ var tfConfig = {
exclude_row: [totRowIndex],
decimal_precision: [2, 2],
tot_row_index: [totRowIndex],
on_after_operation: formatTotals
format_result: [
{ prefix: '€ ' },
{ prefix: '$ ' }
]
}
]
};

View file

@ -23,9 +23,10 @@
btn_reset: true,
loader: true,
status_bar: true,
mark_active_columns: true,
mark_active_columns: {
highlight_column: true
},
no_results_message: true,
responsive: true,
custom_options: {
cols:[3],
texts: [
@ -46,8 +47,8 @@
},
col_widths: [
'150px', '100px', '100px',
'70px', '70px', '70px',
'70px', '60px', '60px'
'90px', '90px', '90px',
'90px', '70px', '70px'
],
extensions:[{ name: 'sort' }]
};

View file

@ -82,8 +82,9 @@
var tfConfig = {
base_path: '../dist/tablefilter/',
alternate_rows: true,
rows_counter: true,
rows_counter_text: "Displayed rows: ",
rows_counter: {
text: 'Displayed rows: '
},
loader: true,
status: true,
status_bar: true,
@ -105,8 +106,7 @@ var tfConfig = {
col_8: "none",
/* external filters */
external_flt_grid: true,
external_flt_grid_ids: [
external_flt_ids: [
'slcCountry',
'slcCode',
'slcYear',

View file

@ -26,8 +26,9 @@ var tfConfig = {
'string', 'string', 'string',
'number', 'string', 'string', 'date'
],
rows_counter: true,
rows_counter_text: 'Books: ',
rows_counter: {
text: 'Books: '
},
alternate_rows: true,
btn_reset: true,
@ -36,22 +37,23 @@ var tfConfig = {
col_4: 'select',
col_5: 'select',
/* custom_cell_data delegate used for filtering
images in a column */
custom_cell_data_cols: [0, 4],
custom_cell_data: function(o, cell, colIndex){
if(colIndex === 0){
var img = cell.getElementsByTagName('img')[0];
if(!img){
return '';
}
return img.alt;
} else if(colIndex === 4){
var chk = cell.getElementsByTagName('input')[0];
if(chk.checked){
return 'yes';
} else {
return 'no';
/* cell parser for filtering images in a column */
cell_parser: {
cols: [0, 4],
parse: function(o, cell, colIndex){
if(colIndex === 0){
var img = cell.getElementsByTagName('img')[0];
if(!img){
return '';
}
return img.alt;
} else if(colIndex === 4){
var chk = cell.getElementsByTagName('input')[0];
if(chk.checked){
return 'yes';
} else {
return 'no';
}
}
}
},

View file

@ -22,7 +22,7 @@ var tfConfig = {
col_2: 'checklist',
col_widths: [
'75px', '200px', '200px',
'100px', '75px', ''
'100px', '75px', '400px'
],
paging: true,
alternate_rows: true,

View file

@ -22,6 +22,9 @@
loader: true,
status_bar: true,
no_results_message: true,
mark_active_columns: {
highlight_column: true
},
col_1: 'select',
col_2: 'select',
col_widths: [

View file

@ -58,8 +58,9 @@ var tfConfig = {
rows_counter: true,
btn_reset: true,
status_bar: true,
paging: true,
paging_length: 15,
paging: {
length: 15
},
enable_empty_option: true,
enable_non_empty_option: true,
enable_default_theme: true,

View file

@ -20,14 +20,15 @@ var tfConfig = {
base_path: '../dist/tablefilter/',
col_widths: [
'150px', '100px', '100px',
'70px', '70px', '70px',
'70px', '60px', '60px'
'100px', '100px', '100px',
'90px', '90px', '90px'
],
alternate_rows: true,
rows_counter: true,
btn_reset: true,
status_bar: true,
load_filters_on_demand: true,
sticky_headers: true,
col_0: 'multiple',
col_1: 'select',
col_2: 'checklist'

View file

@ -30,8 +30,9 @@
<script data-config>
var filtersConfig = {
base_path: '../dist/tablefilter/',
paging: true,
results_per_page: ['Records: ', [10,25,50,100]],
paging: {
results_per_page: ['Records: ', [10, 25, 50, 100]]
},
state: {
types: ['local_storage'],
filters: true,
@ -39,15 +40,21 @@
page_length: true,
sort: true
},
responsive: true,
help_instructions: {
container_adjust_left_position: 30
},
alternate_rows: true,
btn_reset: true,
rows_counter: true,
loader: true,
loader_html: '<div id="lblMsg"></div>',
loader_css_class: 'myLoader',
status_bar: true,
status_bar_target_id: 'lblMsg',
status_bar_css_class: 'myStatus',
loader: {
html: '<div id="lblMsg"></div>',
css_class: 'myLoader'
},
status_bar: {
target_id: 'lblMsg',
css_class: 'myStatus'
},
no_results_message: true,
col_0: 'select',
col_1: 'select',

View file

@ -1,69 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>{NAME} v{VERSION} - Development workflow with RequireJs</title>
<!-- @import partials/style.html -->
</head>
<body>
<h1>{NAME} v{VERSION}</h1>
<h2>Development workflow with RequireJs</h2>
<p>
To take advantage of the RequireJs development workflow use the
<code>grunt dev-modules</code> command.
</p>
<p>
If you use extensions, you will need to specify the extensions path as per
configuration example. Sorting feature also requires the third-party
<code>../libs/sortabletable</code> dependency to be imported.
</p>
<!-- @import partials/pre.html -->
<!-- @import partials/countries-by-continent.html -->
<script src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.17/require.min.js"></script>
<script data-config>
requirejs(
['../dist/tablefilter/tablefilter', '../libs/sortabletable'],
function(mod){
var TableFilter = mod.TableFilter;
var tfConfig = {
base_path: '../dist/tablefilter/',
col_1: 'multiple',
col_2: 'checklist',
alternate_rows: true,
rows_counter: true,
enable_default_theme: true,
col_widths: [
'70px', '170px', '170px',
'110px', '90px', '250px'
],
extensions:[
{
name: 'sort',
path: '../dist/tablefilter/extensions/sort/',
types: [
'number', 'string', 'string',
'US', 'none', 'string'
]
},
{
name: 'colsVisibility',
path: '../dist/tablefilter/extensions/colsVisibility/'
},
{
name: 'filtersVisibility',
path: '../dist/tablefilter/extensions/filtersVisibility/'
}
]
};
tf = new TableFilter('demo', tfConfig);
tf.init();
}
);
</script>
<!-- @import partials/pre-inline-script.html -->
</body>
</html>

View file

@ -43,7 +43,7 @@
},
col_widths: [
'150px', '100px', '100px',
'70px', '70px', '70px',
'100px', '100px', '100px',
'70px', '60px', '60px'
],
extensions:[{ name: 'sort' }]

View file

@ -35,28 +35,33 @@ var tfConfig = {
'string', 'string', 'number',
'string', 'string', 'date'
],
rows_counter: true,
rows_counter_text: 'Books: ',
rows_counter: {
text: 'Books: '
},
alternate_rows: true,
btn_reset: true,
mark_active_columns: true,
mark_active_columns: {
highlight_column: true
},
/* Filter types*/
col_3: 'select',
col_4: 'select',
/* delegate for filtering 'In store' column */
custom_cell_data_cols: [3],
custom_cell_data: function(o, cell, colIndex){
if(colIndex === 3){
var chk = cell.getElementsByTagName('input')[0];
if(!chk){
return '';
}
if(chk.checked){
return 'yes';
} else {
return 'no';
/* cell parser for 'In store' column */
cell_parser: {
cols: [3],
parse: function(o, cell, colIndex){
if(colIndex === 3){
var chk = cell.getElementsByTagName('input')[0];
if(!chk){
return '';
}
if(chk.checked){
return 'yes';
} else {
return 'no';
}
}
}
},

View file

@ -6,12 +6,72 @@
mark_active_columns: true
});
tf.init();
var markActiveColumns = tf.feature('markActiveColumns');
module('Sanity checks');
test('Active columns', function() {
deepEqual(tf instanceof TableFilter, true, 'TableFilter instanciated');
notEqual(markActiveColumns, null, 'markActiveColumns instanciated');
deepEqual(tf.markActiveColumns, true, 'markActiveColumns property');
equal(markActiveColumns.emitter.events['before-filtering'].length, 1,
'subscribed to `before-filtering` event');
equal(markActiveColumns.emitter.events['cell-processed'].length, 1,
'subscribed to `cell-processed` event');
});
module('Feature interface');
test('Properties', function() {
deepEqual(markActiveColumns.tf instanceof TableFilter, true,
'TableFilter instance');
deepEqual(markActiveColumns.feature, 'markActiveColumns',
'Feature name');
deepEqual(markActiveColumns.enabled, true, 'Feature enabled');
deepEqual(markActiveColumns.initialized, true, 'Feature initialized');
deepEqual(typeof markActiveColumns.emitter, 'object',
'Feature has emitter instance');
deepEqual(typeof markActiveColumns.config, 'object',
'TF configuration object');
deepEqual(typeof markActiveColumns.init, 'function',
'Feature init method');
deepEqual(typeof markActiveColumns.destroy, 'function',
'Feature destroy method');
deepEqual(typeof markActiveColumns.reset, 'function',
'Feature reset method');
deepEqual(typeof markActiveColumns.enable, 'function',
'Feature enable method');
deepEqual(typeof markActiveColumns.disable, 'function',
'Feature enable method');
deepEqual(typeof markActiveColumns.isEnabled, 'function',
'Feature enable method');
});
test('Can destroy', function() {
markActiveColumns.destroy();
deepEqual(markActiveColumns.initialized, false, 'not initialised');
});
test('Can reset', function() {
markActiveColumns.reset();
deepEqual(markActiveColumns.enabled, true, 'enabled');
});
test('Can disable', function() {
markActiveColumns.disable();
deepEqual(markActiveColumns.enabled, false, 'disabled');
});
test('Can enable', function() {
markActiveColumns.enable();
deepEqual(markActiveColumns.enabled, true, 'enabled');
});
test('Can init', function() {
markActiveColumns.destroy();
markActiveColumns.enable();
markActiveColumns.init();
deepEqual(markActiveColumns.enabled, true, 'enabled');
});
test('Can check is enabled', function() {
markActiveColumns.isEnabled();
deepEqual(markActiveColumns.enabled, true, 'enabled');
});
module('Behaviour');
test('Active columns', function() {
tf.setFilterValue(1, 'Bri');
tf.setFilterValue(3, '>2');
@ -28,6 +88,59 @@
'Active filter indicator');
});
test('can highlight column cells', function() {
// setup
tf.clearFilters();
var markActiveColumns = tf.feature('markActiveColumns');
markActiveColumns.highlightColumn = true;
// act
tf.setFilterValue(3, '>2');
tf.filter();
// assert
deepEqual(tf.dom().rows[6].cells[3].className,
markActiveColumns.cellCssClass, 'cell has expected css class');
deepEqual(
tf.dom()
.querySelectorAll('.' + markActiveColumns.cellCssClass).length,
7,
'number of highlighted column cells'
);
});
test('can unhighlight column cells', function() {
// act
tf.clearFilters();
// assert
deepEqual(
tf.dom()
.querySelectorAll('.' + markActiveColumns.cellCssClass).length,
0,
'number of highlighted column cells'
);
markActiveColumns.highlightColumn = false;
});
test('cannot initialiase if already initialised', function() {
// setup
var hit = 0;
var emitterOn = markActiveColumns.emitter.on;
markActiveColumns.emitter.on = function() {
hit++;
};
// act
markActiveColumns.init();
// assert
deepEqual(hit, 0, 'init exited');
markActiveColumns.emitter.on = emitterOn;
});
test('Active columns with paging', function() {
tf.destroy();
tf = null;
@ -76,8 +189,130 @@
header3.className.indexOf('activeHeader') !== -1,
true,
'Active filter indicator');
});
test('Cannot destroy if not initialised', function() {
// setup
var clearActiveColumns = markActiveColumns.clearActiveColumns;
var hit = 0;
markActiveColumns.clearActiveColumns = function() { hit++; };
markActiveColumns.initialized = false;
// act
markActiveColumns.destroy();
// assert
deepEqual(hit, 0, 'clearActiveColumns not called');
markActiveColumns.clearActiveColumns = clearActiveColumns;
});
module('Callbacks');
test('Can trigger onBeforeActiveColumn callback', function() {
// setup
var colIndex;
markActiveColumns.onBeforeActiveColumn = function(feature, colIdx) {
colIndex = colIdx;
};
// act
markActiveColumns.markActiveColumn(2);
// assert
deepEqual(colIndex, 2,
'expected column index passed to onBeforeActiveColumn');
});
test('Can trigger onAfterActiveColumn callback', function() {
// setup
var colIndex;
markActiveColumns.onAfterActiveColumn = function(feature, colIdx) {
colIndex = colIdx;
};
// act
markActiveColumns.markActiveColumn(3);
// assert
deepEqual(colIndex, 3,
'expected column index passed to onAfterActiveColumn');
});
module('mark_active_columns as configuration object');
test('Sanity checks', function() {
tf.destroy();
var hit = 0;
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
mark_active_columns: {
header_css_class: 'myCssClass',
on_before_active_column: function(feature, colIndex) {
hit = colIndex;
},
on_after_active_column: function(feature, colIndex) {
hit = colIndex;
}
}
});
tf.init();
var markActiveColumns = tf.feature('markActiveColumns');
deepEqual(tf instanceof TableFilter, true, 'TableFilter instanciated');
notEqual(markActiveColumns, null, 'markActiveColumns instanciated');
deepEqual(tf.markActiveColumns, true, 'markActiveColumns property');
test('Custom header CSS class', function() {
// setup
tf.setFilterValue(1, 'Bri');
tf.setFilterValue(3, '>2');
var header1 = tf.getHeaderElement(1);
var header3 = tf.getHeaderElement(3);
// act
tf.filter();
// assert
deepEqual(
header1.className.indexOf('myCssClass') !== -1,
true,
'Active filter indicator');
deepEqual(
header3.className.indexOf('myCssClass') !== -1,
true,
'Active filter indicator');
});
test('on_before_active_column callback', function() {
// setup
tf.clearFilters();
tf.setFilterValue(1, 'Bri');
// act
tf.filter();
// assert
deepEqual(hit, 1,
'expected column index passed to on_before_active_column');
});
test('on_after_active_column callback', function() {
// setup
tf.clearFilters();
tf.setFilterValue(3, '>2');
// act
tf.filter();
// assert
deepEqual(hit, 3,
'expected column index passed to on_after_active_column');
});
module('Tear-down');
test('can destroy', function() {
tf.destroy();
deepEqual(tf.isInitialized(), false, 'Filters removed');
});
});
})(window, TableFilter);

View file

@ -4,7 +4,7 @@ var tf = new TableFilter('demo', {
alternate_rows: true
});
tf.init();
var tbl = tf.tbl;
var tbl = tf.dom();
var altRows = tf.feature('alternateRows');
module('Sanity checks');
@ -91,8 +91,8 @@ test('Clear filters', function() {
tf.clearFilters();
tf.filter();
deepEqual(tbl.querySelectorAll('tr.odd').length, 3, 'Odd bgs removed');
deepEqual(tbl.querySelectorAll('tr.even').length, 4, 'Even bg removed');
deepEqual(tbl.querySelectorAll('tr.odd').length, 4, 'Odd bgs removed');
deepEqual(tbl.querySelectorAll('tr.even').length, 3, 'Even bg removed');
});
test('Set background on a row', function() {
@ -110,7 +110,7 @@ test('Cannot init if initialised', function() {
// setup
var processAll = altRows.processAll;
var hit = 0;
altRows.processAll = function() { hit++ };
altRows.processAll = function() { hit++; };
altRows.initialized = true;
// act
@ -126,7 +126,7 @@ test('Cannot processAll if not enabled', function() {
// setup
var setRowBg = altRows.setRowBg;
var hit = 0;
altRows.setRowBg = function() { hit++ };
altRows.setRowBg = function() { hit++; };
altRows.enabled = false;
// act
@ -142,7 +142,7 @@ test('Cannot setRowBg if not enabled', function() {
// setup
var removeRowBg = altRows.removeRowBg;
var hit = 0;
altRows.removeRowBg = function() { hit++ };
altRows.removeRowBg = function() { hit++; };
altRows.enabled = false;
// act
@ -171,7 +171,7 @@ test('Cannot destroy if not initialised', function() {
// setup
var getRowsNb = altRows.tf.getRowsNb;
var hit = 0;
altRows.tf.getRowsNb = function() { hit++ };
altRows.tf.getRowsNb = function() { hit++; };
altRows.initialized = false;
// act
@ -242,42 +242,6 @@ test('Can handle `row-paged` event', function() {
altRows.processRow = processRow;
});
test('Can handle `column-sorted` event', function() {
// setup
var processAll = altRows.processAll;
var hit = 0;
altRows.processAll = function() {
hit++;
};
// act
altRows.init();
tf.emitter.emit('column-sorted');
// assert
deepEqual(hit, 1, 'processAll called');
altRows.processAll = processAll;
});
test('Can handle `rows-changed` event', function() {
// setup
var processAll = altRows.processAll;
var hit = 0;
altRows.processAll = function() {
hit++;
};
// act
altRows.init();
tf.emitter.emit('rows-changed');
// assert
deepEqual(hit, 1, 'processAll called');
altRows.processAll = processAll;
});
module('Grid layout');
test('Grid layout: initialising alternating rows', function() {
tf.destroy();
@ -288,13 +252,13 @@ test('Grid layout: initialising alternating rows', function() {
alternate_rows: true
});
tf.init();
tbl = tf.tbl;
tbl = tf.dom();
altRows = tf.feature('alternateRows');
deepEqual(
tbl.querySelectorAll('tr.odd').length, 4, 'Expected bg for odd rows');
tbl.querySelectorAll('tr.odd').length, 4, 'Expected bg for odd rows');
deepEqual(
tbl.querySelectorAll('tr.even').length, 3, 'Expected bg for even rows');
tbl.querySelectorAll('tr.even').length, 3, 'Expected bg for even rows');
});
test('Grid layout: filter column', function() {
@ -309,8 +273,8 @@ test('Grid layout: clear filters', function() {
tf.clearFilters();
tf.filter();
deepEqual(tbl.querySelectorAll('tr.odd').length, 3, 'Odd bgs removed');
deepEqual(tbl.querySelectorAll('tr.even').length, 4, 'Even bg removed');
deepEqual(tbl.querySelectorAll('tr.odd').length, 4, 'Odd bgs removed');
deepEqual(tbl.querySelectorAll('tr.even').length, 3, 'Even bg removed');
});
test('Grid layout: set background on a row', function() {
@ -352,7 +316,7 @@ test('Sort: alternating rows with column sorted at start', function() {
deepEqual(altRows.oddCss, 'odd', 'Expected odd css class');
function checkAlternateRows(tf) {
tbl = tf.tbl;
tbl = tf.dom();
altRows = tf.feature('alternateRows');
test('Alternate rows with sort column at start option', function() {

View file

@ -1,115 +0,0 @@
(function(win, TableFilter){
var tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
rows_always_visible: [4, 9]
});
tf.init();
module('Sanity checks');
test('Always visible rows', function() {
deepEqual(tf instanceof TableFilter, true, 'TableFilter type');
deepEqual(tf.hasVisibleRows, true, 'Contains always visible rows');
});
module('Behaviour');
test('for filtered table', function() {
tf.setFilterValue(0, 'Hello');
tf.filter();
var alwaysVisibleRow1 = tf.tbl.rows[4];
var alwaysVisibleRow2 = tf.tbl.rows[9];
deepEqual(
tf.getRowDisplay(alwaysVisibleRow1),
'',
'Row display for alwaysVisibleRow1'
);
deepEqual(
tf.getRowDisplay(alwaysVisibleRow2),
'',
'Row display for alwaysVisibleRow2'
);
});
test('after filters are cleared', function() {
tf.clearFilters();
var alwaysVisibleRow1 = tf.tbl.rows[4];
var alwaysVisibleRow2 = tf.tbl.rows[9];
deepEqual(
tf.getRowDisplay(alwaysVisibleRow1),
'',
'Row display for alwaysVisibleRow1'
);
deepEqual(
tf.getRowDisplay(alwaysVisibleRow2),
'',
'Row display for alwaysVisibleRow2'
);
testPaging();
});
function testPaging(){
tf.destroy();
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
rows_always_visible: [4, 9],
paging: true,
paging_length: 2
});
tf.init();
var paging = tf.feature('paging');
module('Behaviour with paging');
test('for filtered table', function() {
tf.setFilterValue(0, 'Hello');
tf.filter();
var alwaysVisibleRow1 = tf.tbl.rows[4];
var alwaysVisibleRow2 = tf.tbl.rows[9];
deepEqual(
tf.getRowDisplay(alwaysVisibleRow1),
'',
'Row display for alwaysVisibleRow1'
);
deepEqual(
tf.getRowDisplay(alwaysVisibleRow2),
'',
'Row display for alwaysVisibleRow2'
);
});
test('after filters are cleared', function() {
tf.clearFilters();
var alwaysVisibleRow1 = tf.tbl.rows[4];
var alwaysVisibleRow2 = tf.tbl.rows[9];
deepEqual(
tf.getRowDisplay(alwaysVisibleRow1),
'none',
'Row display for alwaysVisibleRow1'
);
deepEqual(
tf.getRowDisplay(alwaysVisibleRow2),
'none',
'Row display for alwaysVisibleRow2'
);
});
test('after changing pagination page', function() {
paging.setPage(2);
var alwaysVisibleRow1 = tf.tbl.rows[4];
var alwaysVisibleRow2 = tf.tbl.rows[9];
deepEqual(
tf.getRowDisplay(alwaysVisibleRow1),
'',
'Row display for alwaysVisibleRow1'
);
deepEqual(
tf.getRowDisplay(alwaysVisibleRow2),
'none',
'Row display for alwaysVisibleRow2'
);
tf.destroy();
});
}
})(window, TableFilter);

View file

@ -14,6 +14,14 @@ var tf1 = new TableFilter('demo1', {
on_loaded: colsVisibilityTests
}]
});
tf1.registerExtension(
{
init: function() {},
destroy: function() {}
},
'myExtension'
);
tf1.init();
module('Sanity checks');
@ -28,6 +36,7 @@ test('TableFilter object', function() {
deepEqual(tf.getFilterId(0), 'flt0_demo', 'Filter DOM element id');
deepEqual(tf.getStartRowIndex(), 2, 'Start of filterable rows');
deepEqual(tf.getLastRowIndex(), 8, 'Last row index');
deepEqual(tf.dom().nodeName, 'TABLE', 'Working DOM element type');
deepEqual(
tf.getHeadersText(),
[
@ -42,7 +51,7 @@ test('TableFilter object', function() {
);
deepEqual(tf.getValidRowsNb(), 0, 'Number of valid rows before filtering');
deepEqual(
tf.getCellData(tf.tbl.rows[3].cells[2]),
tf.getCellData(tf.dom().rows[3].cells[2]),
982,
'getCellData returns typed value'
);
@ -128,6 +137,21 @@ test('Activate filter for a specified column', function() {
deepEqual(tf.getActiveFilterId(), filterId, 'Filter active');
});
test('Activate filter not called if colIndex not a number', function() {
//set
var originalSetActiveFilterId = tf.setActiveFilterId;
var hit = 0;
tf.setActiveFilterId = function() { hit++; };
//act
tf.activateFilter(undefined);
//assert
deepEqual(hit, 0, 'setActiveFilterId never called');
tf.setActiveFilterId = originalSetActiveFilterId;
});
test('Clear filters', function() {
tf.clearFilters();
deepEqual(tf.getValidRowsNb(), 7, 'Filtered rows number');
@ -140,6 +164,27 @@ test('Can get feature', function() {
deepEqual(feature.feature, 'help', 'Feature name');
});
test('can iterate columns', function() {
// setup
var counter = [];
// act
tf.eachCol(
function(idx) {
counter.push(idx);
},
function(idx) {
return idx === 2;
},
function(idx) {
return idx === 4;
}
);
// assert
deepEqual(counter, [0, 1, 3], 'column iterator conditions met');
});
test('Get table data', function() {
deepEqual(tf.getColValues(0),
[
@ -204,7 +249,7 @@ test('Get table data', function() {
tf.setFilterValue(0, 'Adelaide');
tf.filter();
deepEqual(
tf.getFilteredData(),
tf.getFilteredValues(),
[
[6, ['Adelaide','Perth','2781','3.1','38']],
[7, ['Adelaide','Alice Springs','1533','2','20.25']],
@ -213,7 +258,7 @@ test('Get table data', function() {
'Get filtered table data'
);
deepEqual(
tf.getFilteredData(true),
tf.getFilteredValues(true),
[
[1, ['From','Destination','Road Distance (km)',
'By Air (hrs)','By Rail (hrs)']],
@ -221,10 +266,10 @@ test('Get table data', function() {
[7, ['Adelaide','Alice Springs','1533','2','20.25']],
[8, ['Adelaide','Brisbane','2045','2.15','40']]
],
'Get filtered table data including columns headers'
'Get filtered table values including columns headers'
);
deepEqual(
tf.getFilteredData(false, false, true),
tf.getFilteredData(),
[
[6, ['Adelaide','Perth',2781,3.1,38]],
[7, ['Adelaide','Alice Springs',1533,2,20.25]],
@ -247,6 +292,46 @@ test('Get table data', function() {
[2781,1533,2045],
'Get specified column filtered typed values'
);
deepEqual(
tf.getFilteredColumnData(2),
[2781,1533,2045],
'Get filtered column data'
);
deepEqual(
tf.getFilteredColumnData(2, true),
['Road Distance (km)',2781,1533,2045],
'Get filtered column data with headers'
);
deepEqual(
tf.getVisibleColumnData(2),
[2781,1533,2045],
'Get visible column data'
);
deepEqual(
tf.getVisibleColumnData(2, true),
['Road Distance (km)',2781,1533,2045],
'Get visible column data with headers'
);
deepEqual(
tf.getFilteredColumnValues(2),
['2781','1533','2045'],
'Get filtered column data'
);
deepEqual(
tf.getFilteredColumnValues(2, true),
['Road Distance (km)','2781','1533','2045'],
'Get filtered column data with headers'
);
deepEqual(
tf.getVisibleColumnValues(2),
['2781','1533','2045'],
'Get visible column data'
);
deepEqual(
tf.getVisibleColumnValues(2, true),
['Road Distance (km)','2781','1533','2045'],
'Get visible column data with headers'
);
tf.clearFilters();
tf.filter();
});
@ -264,7 +349,8 @@ test('Test filter types', function() {
base_path: '../dist/tablefilter/',
col_0: 'select',
col_1: 'multiple',
col_2: 'checklist'
col_2: 'checklist',
col_types: ['string', 'string', 'number', 'number', 'number']
});
tf.init();
@ -338,17 +424,28 @@ test('Can select checklist options with array', function() {
tf.setFilterValue(2, '');
tf.setFilterValue(2, ['1412', '982']);
deepEqual(tf.getFilterValue(2), ['1412', '982'],
deepEqual(tf.getFilterValue(2), ['982', '1412'],
'Column 2 filter values');
});
test('get and set filter value can handle out of range column index',
function() {
// act
tf.setFilterValue(11, '');
// assert
deepEqual(tf.getFilterValue(11), '',
'return empty string for inexistent filter');
});
module('TableFilter with pop-up filters');
test('Sanity checks', function() {
tf.destroy();
tf = null;
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
popup_filters: true
popup_filters: true,
col_types: ['string', 'string', 'number', 'number', 'number']
});
tf.init();
@ -396,7 +493,8 @@ test('Sanity checks', function() {
grid_layout: true,
col_0: 'select',
col_1: 'multiple',
col_2: 'checklist'
col_2: 'checklist',
col_types: ['string', 'string', 'number', 'number', 'number']
});
tf.init();
@ -456,6 +554,28 @@ test('Get table data', function() {
],
'Get specified column values including column header'
);
deepEqual(tf.getColumnValues(0),
[
'Sydney','Sydney','Sydney',
'Sydney','Adelaide','Adelaide','Adelaide'
],
'Get specified column values'
);
deepEqual(tf.getColumnValues(0, true),
[
'From','Sydney','Sydney','Sydney',
'Sydney','Adelaide','Adelaide','Adelaide'
],
'Get specified column values including column header'
);
deepEqual(tf.getColumnData(2),
[1412, 982, 286, 872, 2781, 1533, 2045],
'Get specified column data'
);
deepEqual(tf.getColumnData(2, true),
['Road Distance (km)', 1412, 982, 286, 872, 2781, 1533, 2045],
'Get specified column data including column header'
);
deepEqual(
tf.getTableData(),
[
@ -467,22 +587,49 @@ test('Get table data', function() {
[5, ['Adelaide','Alice Springs','1533','2','20.25']],
[6, ['Adelaide','Brisbane','2045','2.15','40']]
],
'Get table values with getTableData()'
);
deepEqual(
tf.getData(),
[
[0, ['Sydney','Adelaide',1412,1.4,25.3]],
[1, ['Sydney','Brisbane',982,1.5,16]],
[2, ['Sydney','Canberra',286,0.6,4.3]],
[3, ['Sydney','Melbourne',872,1.1,10.5]],
[4, ['Adelaide','Perth',2781,3.1,38]],
[5, ['Adelaide','Alice Springs',1533,2,20.25]],
[6, ['Adelaide','Brisbane',2045,2.15,40]]
],
'Get table data'
);
deepEqual(
tf.getValues(),
[
[0, ['Sydney','Adelaide','1412','1.4','25.3']],
[1, ['Sydney','Brisbane','982','1.5','16']],
[2, ['Sydney','Canberra','286','.6','4.3']],
[3, ['Sydney','Melbourne','872','1.1','10.5']],
[4, ['Adelaide','Perth','2781','3.1','38']],
[5, ['Adelaide','Alice Springs','1533','2','20.25']],
[6, ['Adelaide','Brisbane','2045','2.15','40']]
],
'Get table values'
);
tf.clearFilters();
tf.setFilterValue(0, 'Adelaide');
tf.filter();
deepEqual(
tf.getFilteredData(),
tf.getFilteredValues(),
[
[4, ['Adelaide','Perth','2781','3.1','38']],
[5, ['Adelaide','Alice Springs','1533','2','20.25']],
[6, ['Adelaide','Brisbane','2045','2.15','40']]
],
'Get filtered table data'
'Get filtered table values'
);
deepEqual(
tf.getFilteredData(true),
tf.getFilteredValues(true),
[
[0, ['From','Destination','Road Distance (km)',
'By Air (hrs)','By Rail (hrs)']],
@ -490,7 +637,7 @@ test('Get table data', function() {
[5, ['Adelaide','Alice Springs','1533','2','20.25']],
[6, ['Adelaide','Brisbane','2045','2.15','40']]
],
'Get filtered table data including columns headers'
'Get filtered table values including columns headers'
);
deepEqual(
tf.getFilteredDataCol(0),
@ -502,6 +649,46 @@ test('Get table data', function() {
['From','Adelaide','Adelaide','Adelaide'],
'Get specified column filtered values including header'
);
deepEqual(
tf.getFilteredColumnData(2),
[2781,1533,2045],
'Get filtered column data'
);
deepEqual(
tf.getFilteredColumnData(2, true),
['Road Distance (km)',2781,1533,2045],
'Get filtered column data with headers'
);
deepEqual(
tf.getVisibleColumnData(2),
[2781,1533,2045],
'Get visible column data'
);
deepEqual(
tf.getVisibleColumnData(2, true),
['Road Distance (km)',2781,1533,2045],
'Get visible column data with headers'
);
deepEqual(
tf.getFilteredColumnValues(2),
['2781','1533','2045'],
'Get filtered column data'
);
deepEqual(
tf.getFilteredColumnValues(2, true),
['Road Distance (km)','2781','1533','2045'],
'Get filtered column data with headers'
);
deepEqual(
tf.getVisibleColumnValues(2),
['2781','1533','2045'],
'Get visible column data'
);
deepEqual(
tf.getVisibleColumnValues(2, true),
['Road Distance (km)','2781','1533','2045'],
'Get visible column data with headers'
);
tf.clearFilters();
tf.filter();
});
@ -520,24 +707,24 @@ function colsVisibilityTests() { // issue 94
tf1.filter();
deepEqual(
tf1.getFilteredData(false, true),
tf1.getFilteredValues(false, true),
[
[6, ['Adelaide','3.1','38']],
[7, ['Adelaide','2','20.25']],
[8, ['Adelaide','2.15','40']]
],
'Get filtered table data with excluded columns'
'Get filtered table values with excluded columns'
);
deepEqual(
tf1.getFilteredData(true, true),
tf1.getFilteredValues(true, true),
[
[1, ['From','By Air (hrs)','By Rail (hrs)']],
[6, ['Adelaide','3.1','38']],
[7, ['Adelaide','2','20.25']],
[8, ['Adelaide','2.15','40']]
],
'Get filtered table data with headers and excluded columns'
'Get filtered table values with headers and excluded columns'
);
deepEqual(
@ -586,6 +773,20 @@ function colsVisibilityTests() { // issue 94
});
test('Extension Sanity checks', function() {
deepEqual(
tf1.hasExtension('colsVisibility'),
true,
'ColsVisibility in extensions registry'
);
deepEqual(
tf1.hasExtension('myExtension'),
true,
'myExtension in extensions registry'
);
});
test('Destroy', function() {
tf1.destroy();
deepEqual(tf1.isInitialized(), false, 'Filters removed');

View file

@ -2,8 +2,9 @@
var tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
auto_filter: true,
auto_filter_delay: 1000
auto_filter: {
delay: 1000
}
});
tf.init();
window.tf = tf;
@ -14,6 +15,18 @@
deepEqual(tf.autoFilter, true, 'Auto filtering enabled');
deepEqual(tf.autoFilterDelay, 1000, 'Expected filtering delay');
});
test('Blur input filter', function() {
// setup
var filter = tf.getFilterElement(0);
filter.focus();
// act
filter.blur();
// assert
deepEqual(tf.isUserTyping, false, 'User not typing');
deepEqual(tf.autoFilterTimer, null, 'Auto filter timer cleared');
});
module('Remove feature');
test('Auto filter feature disabled', function() {

109
test/test-cell-parser.html Normal file
View file

@ -0,0 +1,109 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TableFilter filter with cell parser</title>
<link rel="stylesheet" href="libs/qunit/qunit.css">
<script src="libs/qunit/qunit.js"></script>
<script src="libs/polyfill.js"></script>
</head>
<body>
<table id="demo">
<thead>
<tr>
<th></th>
<th>From</th>
<th>Destination</th>
<th>Road Distance (km)</th>
<th>By Air (hrs)</th>
<th>By Rail (hrs)</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox" disabled="disabled"
value="" checked="checked">
</td>
<td><strong>Sydney</strong></td>
<td>Adelaide</td>
<td>1412</td>
<td>1.4</td>
<td>25.3</td>
</tr>
<tr>
<td>
<input type="checkbox" disabled="disabled"
value="">
</td>
<td><strong>Sydney</strong></td>
<td>Brisbane</td>
<td>982</td>
<td>1.5</td>
<td>16</td>
</tr>
<tr>
<td>
<input type="checkbox" disabled="disabled"
value="" checked="checked">
</td>
<td><strong>Sydney</strong></td>
<td>Canberra</td>
<td>286</td>
<td>.6</td>
<td>4.3</td>
</tr>
<tr>
<td>
<input type="checkbox" disabled="disabled"
value="" checked="checked">
</td>
<td><strong>Sydney</strong></td>
<td>Melbourne</td>
<td>872</td>
<td>1.1</td>
<td>10.5</td>
</tr>
<tr>
<td>
<input type="checkbox" disabled="disabled"
value="">
</td>
<td><strong>Adelaide</strong></td>
<td>Perth</td>
<td>2781</td>
<td>3.1</td>
<td>38</td>
</tr>
<tr>
<td>
<input type="checkbox" disabled="disabled"
value="" checked="checked">
</td>
<td><strong>Adelaide</strong></td>
<td>Alice Springs</td>
<td>1533</td>
<td>2</td>
<td>20.25</td>
</tr>
<tr>
<td>
<input type="checkbox" disabled="disabled"
value="">
</td>
<td><strong>Adelaide</strong></td>
<td>Brisbane</td>
<td>2045</td>
<td>2.15</td>
<td>40</td>
</tr>
</tbody>
</table>
<script src="../dist/tablefilter/tablefilter.js"></script>
<script src="test-cell-parser.js"></script>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>

80
test/test-cell-parser.js Normal file
View file

@ -0,0 +1,80 @@
(function(win, TableFilter){
var tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
col_0: 'select',
cell_parser: {
cols: [0],
parse: function(tf, cell) {
var chk = cell.getElementsByTagName('input')[0];
if (chk.checked) {
return 'yes';
} else {
return 'no';
}
}
}
});
tf.init();
module('Sanity checks');
test('Sanity checks', function() {
deepEqual(tf instanceof TableFilter, true, 'TableFilter instanciated');
deepEqual(tf.cellParser.cols.length, 1,
'Columns implementing cell parser');
deepEqual(typeof tf.cellParser.parse, 'function', 'Parse function');
deepEqual(
tf.getFilterElement(0).nodeName, 'SELECT', 'Expected filter type');
});
module('Behaviour');
test('Can filter with parsed value', function() {
// setup
tf.setFilterValue(0, 'yes');
// act
tf.filter();
// assert
deepEqual(tf.getValidRows(), [2, 4, 5, 7], 'Number of parsed values');
});
test('Can parse with custom function', function() {
// setup
var cell = tf.dom().rows[3].cells[0];
// act
var value = tf.getCellValue(cell);
// assert
deepEqual(value, 'no', 'Value returned by custom cell parser');
});
test('Should not parse with custom function if no columns defined',
function() {
// setup
var initialCellParser = tf.cellParser;
var hit = 0;
var cell = tf.dom().rows[3].cells[0];
tf.cellParser.cols = [];
tf.cellParser.parse = function() {
hit++;
};
// act
tf.getCellValue(cell);
// assert
deepEqual(hit, 0, 'Cell parser not invoked');
tf.cellParser = initialCellParser;
}
);
module('Tear-down');
test('can destroy', function() {
tf.destroy();
deepEqual(tf.isInitialized(), false, 'Filters removed');
});
})(window, TableFilter);

View file

@ -41,7 +41,7 @@ test('Can refresh all drop-down filters', function() {
tf.clearFilters();
var build = checkList.build;
var hit = 0;
checkList.build = function() { hit++ };
checkList.build = function() { hit++; };
//act
checkList.refreshAll();
@ -100,18 +100,43 @@ test('Can sort options', function() {
tf.destroy();
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
col_0: 'checklist',
col_1: 'checklist',
col_2: 'checklist',
col_3: 'checklist',
col_4: 'checklist',
sort_num_asc: [2, 3],
sort_num_desc: [4]
col_types: ['string', 'string', 'number', 'number', 'number'],
sort_filter_options_asc: [0, 2, 3],
sort_filter_options_desc: [1, 4]
});
tf.init();
var flt0 = id(tf.fltIds[0]);
var flt1 = id(tf.fltIds[1]);
var flt2 = id(tf.fltIds[2]);
var flt3 = id(tf.fltIds[3]);
var flt4 = id(tf.fltIds[4]);
deepEqual(
flt0.getElementsByTagName('li')[1].firstChild.firstChild.value,
'Adelaide',
'First option value for column 0'
);
deepEqual(
flt0.getElementsByTagName('li')[2].firstChild.firstChild.value,
'Sydney',
'Last option value for column 0'
);
deepEqual(
flt1.getElementsByTagName('li')[1].firstChild.firstChild.value,
'Perth',
'First option value for column 1'
);
deepEqual(
flt1.getElementsByTagName('li')[6].firstChild.firstChild.value,
'Adelaide',
'Last option value for column 1'
);
deepEqual(
flt2.getElementsByTagName('li')[1].firstChild.firstChild.value,
'286',
@ -181,6 +206,55 @@ test('Can select empty and non-empty options', function() {
'Filter 3 options values attribute');
});
// issue 714, clear filter text
module('Clear filter text');
test('Can define clear filter text for each column', function() {
tf.clearFilters();
tf.destroy();
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
col_2: 'checklist',
col_3: 'checklist',
col_4: 'checklist',
clear_filter_text: [null, null, 'clear 2', 'clear 3', 'clear 4']
});
tf.init();
var flt2 = tf.getFilterElement(2).getElementsByTagName('li');
var flt3 = tf.getFilterElement(3).getElementsByTagName('li');
var flt4 = tf.getFilterElement(4).getElementsByTagName('li');
deepEqual(flt2[0].getElementsByTagName('label')[0].innerText,
'clear 2', 'clear text filter 2');
deepEqual(flt3[0].getElementsByTagName('label')[0].innerText,
'clear 3', 'clear text filter 3');
deepEqual(flt4[0].getElementsByTagName('label')[0].innerText,
'clear 4', 'clear text filter 4');
});
test('Can define clear filter text globally', function() {
tf.clearFilters();
tf.destroy();
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
col_2: 'checklist',
col_3: 'checklist',
col_4: 'checklist',
clear_filter_text: 'reset'
});
tf.init();
var flt2 = tf.getFilterElement(2).getElementsByTagName('li');
var flt3 = tf.getFilterElement(3).getElementsByTagName('li');
var flt4 = tf.getFilterElement(4).getElementsByTagName('li');
deepEqual(flt2[0].getElementsByTagName('label')[0].innerText,
'reset', 'clear text filter 2');
deepEqual(flt3[0].getElementsByTagName('label')[0].innerText,
'reset', 'clear text filter 3');
deepEqual(flt4[0].getElementsByTagName('label')[0].innerText,
'reset', 'clear text filter 4');
});
module('Tear down');
test('TableFilter removed', function() {
tf.destroy();

View file

@ -8,6 +8,7 @@
<script src="libs/polyfill.js"></script>
</head>
<body>
<div id="external-container"></div>
<table id="demo" cellpadding="0" cellspacing="0">
<tbody>
<tr>
@ -75,4 +76,4 @@
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>
</html>

View file

@ -6,6 +6,7 @@ var tf = new TableFilter('demo', {
tf.init();
var clearButton = tf.feature('clearButton');
module('Sanity checks');
test('Clear button component', function() {
deepEqual(typeof clearButton, 'object', 'ClearButton instanciated');
@ -58,6 +59,61 @@ test('Can check is enabled', function() {
deepEqual(clearButton.enabled, true, 'enabled');
});
module('Behaviour');
test('Cannot init if already initialised', function() {
// setup
clearButton.initialized = true;
var emit = clearButton.emitter.emit;
var hit = 0;
clearButton.emitter.emit = function() {
hit++;
};
// act
clearButton.init();
// assert
deepEqual(hit, 0, 'does not initialise');
clearButton.emitter.emit = emit;
});
test('onClick does nothing if not enabled', function() {
// setup
clearButton.disable();
var clearFilters = clearButton.tf.clearFilters;
var hit = 0;
clearButton.tf.clearFilters = function() {
hit++;
};
// act
clearButton.onClick();
// assert
deepEqual(hit, 0, 'onClick does nothing');
clearButton.tf.clearFilters = clearFilters;
});
test('onClick calls clearFilters if enabled', function() {
// setup
clearButton.enable();
var clearFilters = clearButton.tf.clearFilters;
var hit = 0;
clearButton.tf.clearFilters = function() {
hit++;
};
// act
clearButton.onClick();
// assert
deepEqual(hit, 1, 'onClick calls clearFilters');
clearButton.tf.clearFilters = clearFilters;
});
module('UI elements');
test('ClearButton UI elements', function() {
var container = clearButton.container;
@ -73,7 +129,7 @@ test('Remove UI', function() {
deepEqual(btnResetEl, null, 'Clear button is removed');
});
test('Re-set UI', function() {
test('Re-set UI with no icons and text button', function() {
clearButton.destroy();
tf.enableIcons = false;
clearButton.html = null;
@ -85,6 +141,40 @@ test('Re-set UI', function() {
deepEqual(btnResetEl.innerText, 'Clear', 'Clear button text');
});
test('Destroy and init with text button and icons enabled', function() {
tf.destroy();
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
btn_reset: {
text: 'Clear all'
}
});
tf.init();
clearButton = tf.feature('clearButton');
var btnResetEl = clearButton.element;
deepEqual(btnResetEl.nodeName, 'A', 'Clear button tag changed');
deepEqual(btnResetEl.innerText, 'Clear all', 'Clear button text');
});
test('Destroy and init in external container', function() {
tf.destroy();
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
btn_reset: {
target_id: 'external-container'
}
});
tf.init();
clearButton = tf.feature('clearButton');
deepEqual(clearButton.element.nodeName, 'INPUT', 'Clear button tag');
deepEqual(clearButton.container.parentNode.id, 'external-container',
'container id');
});
module('Tear-down');
test('can destroy TableFilter DOM elements', function() {
tf.destroy();

View file

@ -6,8 +6,9 @@ var totRowIndex = table.getElementsByTagName('tr').length;
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
col_types: ['string', 'string', 'number', 'number', 'number'],
paging: true,
paging_length: 4,
paging: {
length: 4
},
rows_always_visible: [
totRowIndex-6,
totRowIndex-5,

View file

@ -140,6 +140,61 @@ test('Can make column calculations', function() {
deepEqual(result2, 2781, 'columnCalc max');
});
test('Can make column calculations with formated results', function() {
// setup
var colOps = tf.extension('colOps');
colOps.formatResults[2] = { suffix: ' Km' };
colOps.formatResults[4] = { suffix: ' Km' };
colOps.formatResults[6] = { suffix: ' Km' };
tf.colTypes[2] = { type: 'formatted-number', decimal: '.', thousands: ',' };
// act
colOps.calcAll();
// assert
deepEqual(id('mean1').innerHTML, '1,416 Km', 'Formatted mean result');
deepEqual(id('min1').innerHTML, '286 Km', 'Formatted min result');
deepEqual(id('max1').innerHTML, '2,781 Km', 'Formatted max result');
colOps.formatResults[2] = undefined;
colOps.formatResults[4] = undefined;
colOps.formatResults[6] = undefined;
tf.colTypes[2] = undefined;
});
test('Can configure result format', function() {
// setup
var colOps = tf.extension('colOps');
var format = { prefix: '$', suffix: '/item' };
// act
var format = colOps.configureFormat(2, format);
// assert
deepEqual(format.prefix, '$', 'prefix');
deepEqual(format.suffix, '/item', 'suffix');
deepEqual(format.decimal, '', 'decimal separator');
deepEqual(format.integerSeparator, '', 'thousands separator');
});
test('Can configure result format for formatted number column', function() {
// setup
var colOps = tf.extension('colOps');
var format = { prefix: '$', suffix: '/item' };
tf.colTypes = [null, null, null, null, null];
tf.colTypes[3] = { type: 'formatted-number', decimal: ',', thousands: '.' };
// act
var format = colOps.configureFormat(3, format);
// assert
deepEqual(format.prefix, '$', 'prefix');
deepEqual(format.suffix, '/item', 'suffix');
deepEqual(format.decimal, ',', 'decimal separator');
deepEqual(format.integerSeparator, '.', 'thousands separator');
tf.colTypes[3] = undefined;
});
module('Tear-down');
test('can destroy', function() {
tf.destroy();

View file

@ -9,10 +9,12 @@
module('Sanity checks');
test('Column widths', function() {
var cols = tf.tbl.getElementsByTagName('col');
var cols = tf.dom().getElementsByTagName('col');
deepEqual(tf instanceof TableFilter, true, 'TableFilter instanciated');
deepEqual(cols[1].style.width, '100px', 'Expected column width');
deepEqual(cols[4].style.width, '', 'Expected column width');
deepEqual(tf.dom().style.width, '645px', 'Table width set');
deepEqual(tf.dom().style.tableLayout, 'fixed', 'Table layout fixed');
});
test('Grid layout column widths', function() {
@ -20,14 +22,19 @@
tf = null;
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
col_widths: ['150px', '100px', '175px', '120px', '200px'],
grid_layout: true,
sort: false
col_widths: ['150px', '100px', '175px', '120px', null],
grid_layout: true
});
tf.init();
var cols = tf.feature('gridLayout').headTbl.getElementsByTagName('col');
var gridLayout = tf.feature('gridLayout');
var cols = gridLayout.headTbl.getElementsByTagName('col');
deepEqual(cols[0].style.width, '150px', 'Expected column width');
deepEqual(cols[4].style.width, '200px', 'Expected column width');
deepEqual(cols[3].style.width, '120px', 'Expected column width');
deepEqual(
tf.dom().style.width === gridLayout.headTbl.style.width,
true,
'Content and headers table have same width'
);
});
})(window, TableFilter);

Some files were not shown because too many files have changed in this diff Show more