1
0
Fork 0
mirror of https://github.com/koalyptus/TableFilter.git synced 2024-05-23 00:32:21 +02:00

Merge branch 'master' into 358-increase-coverage

This commit is contained in:
Max Guglielmi 2017-01-19 13:04:48 +11:00
commit 8c9a033c67
37 changed files with 737 additions and 397 deletions

View file

@ -11,8 +11,8 @@
"array-bracket-spacing": 2,
"keyword-spacing": ["error", { "after": true, "before": true }],
"max-depth": [2, 7],
"max-statements": [2, 150],
"complexity": [2, 83],
"max-statements": [2, 144],
"complexity": [2, 78],
"no-unused-vars": 2,
"no-eval": 2,
"no-underscore-dangle": 0,

View file

@ -92,7 +92,7 @@ command to generate a production build.
The
```shell
npm run build-all
npm run dist
```
command will create a production build, run the tests and finally generate
the demos:
@ -118,7 +118,7 @@ to view the coverage report(s), open the `index.html` under the
Check out the online [examples](http://koalyptus.github.io/TableFilter/examples)
or generate the demos locally:
```shell
npm run build-demos
npm run build:demos
```
then run the local webserver:
```shell

4
dist/starter.html vendored
View file

@ -1,10 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>tablefilter v0.4.30 - Starter</title>
<title>tablefilter v0.4.35 - Starter</title>
</head>
<body>
<h1>tablefilter v0.4.30</h1>
<h1>tablefilter v0.4.35</h1>

View file

@ -1,6 +1,6 @@
/**
* tablefilter v0.4.30 by Max Guglielmi
* build date: 2017-01-03T03:02:08.570Z
* tablefilter v0.4.35 by Max Guglielmi
* build date: 2017-01-18T10:23:03.372Z
* 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}

View file

@ -1,6 +1,6 @@
/**
* tablefilter v0.4.30 by Max Guglielmi
* build date: 2017-01-03T03:02:08.570Z
* tablefilter v0.4.35 by Max Guglielmi
* build date: 2017-01-18T10:23:03.372Z
* 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}

View file

@ -1,14 +1,14 @@
/**
* tablefilter v0.4.30 by Max Guglielmi
* build date: 2017-01-03T03:02:08.570Z
* tablefilter v0.4.35 by Max Guglielmi
* build date: 2017-01-18T10:23:03.372Z
* MIT License
*/
.activeHeader{background-color:#66afe9 !important;color:#fff !important}
.even{background-color:#fff}.odd{background-color:#f9f9f9}
.ezActiveRow{background-color:#2852a8 !important;color:#fff}.ezSelectedRow{background-color:#316ac5 !important;color:#fff}.ezActiveCell{background-color:#d9e8fb !important;color:#000 !important;font-weight:bold}.ezETSelectedCell{background-color:#ffdc61 !important;font-weight:bold;color:#000 !important}.ezUnselectable{-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.ezInputEditor{width:95%;height:auto;font-size:inherit;border:1px solid #aaccf6}.ezTextareaEditor{width:95%;height:35px;font-size:inherit;border:1px solid #aaccf6}.ezSelectEditor{width:100%;font-size:inherit;border:1px solid #aaccf6}.ezModifiedCell{background:transparent url("themes/bg_mod_cell.png") 0 0 no-repeat}select[multiple="multiple"].ezSelectEditor{height:35px}.ezCommandEditor{margin:2px;}.ezCommandEditor button,.ezCommandEditor input[type="button"]{min-height:22px;margin:1px;padding:3px;border:1px solid #ccc;background:#fff;border-radius:4px 4px 4px 4px;-moz-border-radius:4px 4px 4px 4px;}.ezCommandEditor button:hover,.ezCommandEditor input[type="button"]:hover{border:1px solid #999}.ezCommandEditor img{border:0;vertical-align:middle;margin:2px}.ezOpacity{opacity:.6}.alignLeft{text-align:left}.alignCenter{text-align:center}.alignRight{text-align:right}
.div_checklist{width:100%;height:90px;border:1px solid #f4f4f4;overflow:auto;text-align:left;background-color:#fff;color:#444;}.div_checklist ul.flt_checklist{padding:0 !important;margin:0 !important;list-style:none !important}.div_checklist li.flt_checklist_item{padding:1px !important;margin:0 !important;font-size:10px !important;border-bottom:1px solid #f4f4f4 !important;}.div_checklist li.flt_checklist_item:hover{background-color:#335ea8 !important;color:#fff !important}.div_checklist label{display:block !important}.div_checklist input{vertical-align:middle !important;margin:2px 5px 2px 1px !important}.flt_checklist_item_disabled{background-color:#e5e5e5}.flt_checklist_slc_item{background-color:#335ea8 !important;color:#fff !important}
.fltrow{height:1em;background-color:#eaeaea;}.fltrow td{border-bottom:1px solid #ccc !important;border-top:1px solid #f4f4f4;border-left:1px solid #ccc;border-right:1px solid #f4f4f4;padding:.2em !important;}.fltrow td:last-child{border-right:1px solid #ccc}.btnflt{height:35px;font-family:inherit;font-size:inherit;vertical-align:middle;margin:0 2px 0 2px;padding:0 1px 0 1px}.btnflt_icon{font-family:inherit;font-size:inherit;width:35px;height:35px;cursor:pointer !important;border:0 !important;vertical-align:middle;background:transparent url("themes/btn_filter.png") center center no-repeat !important}.flt,.flt_s,.single_flt{font-family:inherit;display:block;color:#444;background-color:#fff;border:1px inset #f4f4f4;margin:0;padding:0 0 0 .2em;width:100%;height:35px;vertical-align:middle;border-radius:2px;box-sizing:border-box;}.flt:focus,.flt_s:focus,.single_flt:focus{border-color:#66afe9;outline:0 none;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.075) inset,0 0 8px rgba(102,175,233,0.6);-moz-box-shadow:0 1px 1px rgba(0,0,0,0.075) inset,0 0 8px rgba(102,175,233,0.6);box-shadow:0 1px 1px rgba(0,0,0,0.075) inset,0 0 8px rgba(102,175,233,0.6)}select.flt_multi{font-family:inherit;color:#444;background-color:#fff;border:1px solid #f4f4f4;margin:0;padding:.2em;width:100%;height:90px;vertical-align:middle;box-sizing:border-box}.flt_s{width:60%;box-sizing:initial;display:initial}.single_flt{width:70%;box-sizing:initial;display:initial}div.popUpFilter{position:relative;background:#fff;-webkit-box-shadow:3px 3px 2px #888;-moz-box-shadow:3px 3px 2px #888;box-shadow:3px 3px 2px #888;margin:30px auto 0 0;position:absolute;display:none;width:100px;background-color:#eaeaea;border:1px solid #eaeaea;padding:0}div.popUpFilter:after,div.popUpFilter:before{bottom:100%;left:50%;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}div.popUpFilter:after{border-color:rgba(255,255,255,0);border-bottom-color:#fff;border-width:10px;margin-left:-10px}div.popUpFilter:before{border-color:rgba(255,255,255,0);border-bottom-color:#eaeaea;border-width:12px;margin-left:-12px}
.div_checklist{width:100%;height:90px;line-height:24px;border:1px solid #f4f4f4;overflow:auto;text-align:left;background-color:#fff;color:#444;}.div_checklist ul.flt_checklist{padding:0 !important;margin:0 !important;list-style:none !important}.div_checklist li.flt_checklist_item{padding:1px !important;margin:0 !important;font-size:10px !important;border-bottom:1px solid #f4f4f4 !important;}.div_checklist li.flt_checklist_item:hover{background-color:#335ea8 !important;color:#fff !important}.div_checklist label{display:block !important}.div_checklist input{vertical-align:middle !important;margin:2px 5px 2px 1px !important}.flt_checklist_item_disabled{background-color:#e5e5e5}.flt_checklist_slc_item{background-color:#335ea8 !important;color:#fff !important}
.fltrow{height:1em;background-color:#eaeaea;}.fltrow td{border-bottom:1px solid #ccc !important;border-top:1px solid #f4f4f4;border-left:1px solid #ccc;border-right:1px solid #f4f4f4;padding:.2em !important;}.fltrow td:last-child{border-right:1px solid #ccc}.btnflt{height:35px;font-family:inherit;font-size:inherit;vertical-align:middle;margin:0 2px 0 2px;padding:0 1px 0 1px}.btnflt_icon{font-family:inherit;font-size:inherit;width:35px;height:35px;cursor:pointer !important;border:0 !important;vertical-align:middle;background:transparent url("themes/btn_filter.png") center center no-repeat !important}.flt,.flt_s,.single_flt{font-family:inherit;display:block;color:#444;background-color:#fff;border:1px inset #f4f4f4;margin:0;padding:0 0 0 .2em;width:100%;height:35px;vertical-align:middle;border-radius:2px;box-sizing:border-box;}.flt:focus,.flt_s:focus,.single_flt:focus{border-color:#66afe9;outline:0 none;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.075) inset,0 0 8px rgba(102,175,233,0.6);-moz-box-shadow:0 1px 1px rgba(0,0,0,0.075) inset,0 0 8px rgba(102,175,233,0.6);box-shadow:0 1px 1px rgba(0,0,0,0.075) inset,0 0 8px rgba(102,175,233,0.6)}select.flt_multi{font-family:inherit;color:#444;background-color:#fff;border:1px solid #f4f4f4;margin:0;padding:.2em;width:100%;height:90px;vertical-align:middle;box-sizing:border-box;}select.flt_multi option{padding-top:5px;padding-bottom:5px}.flt_s{width:60%;box-sizing:initial;display:initial}.single_flt{width:70%;box-sizing:initial;display:initial}div.popUpFilter{position:relative;background:#fff;-webkit-box-shadow:3px 3px 2px #888;-moz-box-shadow:3px 3px 2px #888;box-shadow:3px 3px 2px #888;margin:30px auto 0 0;position:absolute;display:none;width:100px;background-color:#eaeaea;border:1px solid #eaeaea;padding:0}div.popUpFilter:after,div.popUpFilter:before{bottom:100%;left:50%;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}div.popUpFilter:after{border-color:rgba(255,255,255,0);border-bottom-color:#fff;border-width:10px;margin-left:-10px}div.popUpFilter:before{border-color:rgba(255,255,255,0);border-bottom-color:#eaeaea;border-width:12px;margin-left:-12px}
div.grd_Cont{-webkit-box-shadow:4px 4px 10px 0 rgba(50,50,50,0.75);-moz-box-shadow:4px 4px 10px 0 rgba(50,50,50,0.75);box-shadow:4px 4px 10px 0 rgba(50,50,50,0.75);width:800px;height:auto;overflow:hidden;padding:3px 3px 3px 3px;background-color:#c8e0fb;border:1px solid #99bbe8;}div.grd_Cont .fltrow{background-color:transparent}div.grd_Cont .flt{border:1px solid #99bbe8;width:100%;}div.grd_Cont .flt :focus{border:1px solid #558dd9}div.grd_Cont .even{background-color:#fff}div.grd_Cont .odd{background-color:#dfe8f6}div.grd_Cont .no-results{background-color:transparent}div.grd_Cont .sort-arrow{position:initial}div.grd_tblCont{height:400px;width:800px;background:#fff;overflow-x:auto;overflow-y:scroll}div.grd_headTblCont{height:auto;width:800px;overflow:hidden;border-bottom:1px solid #99bbe8;background-color:#c8e0fb}div.grd_tblCont table,div.grd_headTblCont table{border-collapse:collapse;table-layout:fixed;box-sizing:initial}div.grd_tblCont table{border-right:1px solid #99bbe8;box-sizing:initial}div.grd_tblCont table th,div.grd_headTblCont table th,div.grd_headTblCont table td{height:35px;background-color:#c8e0fb;padding:.1em .5em;color:#333;border-right:1px solid #99bbe8 !important;overflow:hidden;text-overflow:ellipsis}div.grd_headTblCont table td{padding:.2em .2em}div.grd_tblCont table td{padding:.5em .7em;border-bottom:1px solid #99bbe8;overflow:hidden;text-overflow:ellipsis}.grd_inf{clear:both;width:auto;height:35px;background-color:#c8e0fb;margin:0;padding:1px 3px 1px 3px;border-top:1px solid #99bbe8;}.grd_inf a{color:#333;text-decoration:none;font-weight:bold;}.grd_inf a:hover{text-decoration:underline;background-color:transparent}.grd_inf input.reset:hover{background-color:transparent}.grd_inf .mdiv{width:40% !important}.grd_inf .ldiv div{border:0}.grd_inf .helpBtn{border:0 !important}.grd_inf div.status{position:absolute;float:none !important;height:auto !important;margin:19px 0 !important;font-size:12px;color:#333;border:0 !important}.grd_inf div.tot{border:0 !important}
.helpBtn{display:inline-block;height:27px;margin:0;padding:8px 15px 0 15px;vertical-align:top;}.helpBtn:hover{background-color:#f4f4f4}div.helpCont{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;width:300px;padding:10px;margin:45px 0 0 -150px;border:1px solid #ccc;line-height:20px;font-size:inherit;color:#333;background:#fff;text-align:left;}div.helpCont:after,div.helpCont:before{bottom:100%;left:50%;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}div.helpCont:after{border-color:rgba(255,255,255,0);border-bottom-color:#fff;border-width:10px;margin-left:-10px}div.helpCont:before{border-color:rgba(255,255,255,0);border-bottom-color:#ccc;border-width:12px;margin-left:-12px}div.helpCont a{color:#c00;text-decoration:underline;font-weight:normal}div.helpCont a.close{color:#333 !important;text-decoration:none !important;font-weight:bold;}div.helpCont a.close:hover{text-decoration:none}div.helpCont hr{border:1px solid #ccc}div.helpFooter{margin:10px 0 0 0;}div.helpFooter h4{margin:2px 2px 2px 2px;color:#333}
span.keyword{font-weight:700;font-style:italic;border-bottom:1px dotted #ccc}

View file

@ -1,6 +1,6 @@
/**
* tablefilter v0.4.30 by Max Guglielmi
* build date: 2017-01-03T03:02:08.570Z
* tablefilter v0.4.35 by Max Guglielmi
* build date: 2017-01-18T10:23:03.372Z
* 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,6 @@
/**
* tablefilter v0.4.30 by Max Guglielmi
* build date: 2017-01-03T03:02:08.570Z
* tablefilter v0.4.35 by Max Guglielmi
* build date: 2017-01-18T10:23:03.372Z
* 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,6 @@
/**
* tablefilter v0.4.30 by Max Guglielmi
* build date: 2017-01-03T03:02:08.570Z
* tablefilter v0.4.35 by Max Guglielmi
* build date: 2017-01-18T10:23:03.372Z
* 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,6 @@
/**
* tablefilter v0.4.30 by Max Guglielmi
* build date: 2017-01-03T03:02:08.570Z
* tablefilter v0.4.35 by Max Guglielmi
* build date: 2017-01-18T10:23:03.372Z
* 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

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
{
"name": "tablefilter",
"version": "0.4.30",
"version": "0.4.35",
"description": "A Javascript library making HTML tables filterable and a bit more",
"license": "MIT",
"author": {
@ -24,13 +24,13 @@
"scripts": {
"dev": "grunt dev",
"build": "grunt build",
"build-demos": "grunt build-demos",
"build:demos": "grunt build-demos",
"server": "grunt server",
"eslint": "grunt eslint",
"test": "grunt test",
"codecov": "./node_modules/.bin/codecov",
"esdoc": "grunt esdoc",
"build-all": "grunt",
"dist": "grunt",
"deploy": "grunt deploy",
"start": "npm run server"
},
@ -43,9 +43,9 @@
"babel-loader": "^6.2.9",
"babel-plugin-transform-es2015-classes": "^6.18.0",
"babel-preset-es2015": "^6.18.0",
"clean-webpack-plugin": "^0.1.14",
"clean-webpack-plugin": "^0.1.15",
"codecov": "1.0.1",
"diacritics": "1.2.3",
"diacritics": "1.3.0",
"grunt": "^1.0.1",
"grunt-babel": "^6.0.0",
"grunt-cli": "1.2.0",
@ -62,7 +62,7 @@
"grunt-webpack": "^1.0.18",
"isparta-loader": "2.0.0",
"script-loader": "^0.7.0",
"string-replace-webpack-plugin": "^0.0.4",
"string-replace-webpack-plugin": "^0.0.5",
"sugar-date": "2.0.4",
"webpack": "^1.14.0",
"webpack-dev-server": "^1.16.2"

View file

@ -1,6 +1,7 @@
import {Feature} from '../../feature';
import {createText, elm} from '../../dom';
import {isArray, isFn, isUndef, EMPTY_FN} from '../../types';
import {isArray, isFn, isUndef, isEmpty, EMPTY_FN} from '../../types';
import {numSortAsc} from '../../sort';
const EVENTS = [
'after-filtering',
@ -8,6 +9,14 @@ const EVENTS = [
'after-page-length-change'
];
const SUM = 'sum';
const MEAN = 'mean';
const MIN = 'min';
const MAX = 'max';
const MEDIAN = 'median';
const Q1 = 'q1';
const Q3 = 'q3';
/**
* Column calculations extension
*/
@ -42,6 +51,51 @@ export default class ColOps extends Feature {
*/
this.opts = opts;
/**
* List of DOM element IDs containing column's calculation result
* @type {Array}
*/
this.labelIds = opts.id || [];
/**
* List of columns' indexes for calculations
* @type {Array}
*/
this.colIndexes = opts.col || [];
/**
* List of operations - possible values: 'sum', 'mean', 'min', 'max',
* 'median', 'q1', 'q3'
* @type {Array}
*/
this.operations = opts.operation || [];
/**
* List of write methods used to write the result - possible values:
* 'innerHTML', 'setValue', 'createTextNode'
* @type {Array}
*/
this.outputTypes = opts.write_method || [];
/**
* List of row indexes displaying the results
* @type {Array}
*/
this.totRowIndexes = opts.tot_row_index || [];
/**
* List of row indexes excluded from calculations
* @type {Array}
*/
this.excludeRows = opts.exclude_row || [];
/**
* List of decimal precision for calculation results
* @type {Array}
*/
this.decimalPrecisions = isUndef(opts.decimal_precision) ?
2 : opts.decimal_precision;
this.enable();
}
@ -53,13 +107,11 @@ export default class ColOps extends Feature {
return;
}
// subscribe to events
this.emitter.on(EVENTS, () => this.calc());
this.emitter.on(EVENTS, () => this.calcAll());
this.calc();
this.calcAll();
/**
* @inherited
*/
/** @inherited */
this.initialized = true;
}
@ -79,7 +131,7 @@ export default class ColOps extends Feature {
* (1) optimized the routine (now it will only process each column once),
* (2) added calculations for the median, lower and upper quartile.
*/
calc() {
calcAll() {
let tf = this.tf;
if (!tf.isInitialized()) {
return;
@ -88,277 +140,303 @@ export default class ColOps extends Feature {
this.onBeforeOperation(tf, this);
this.emitter.emit('before-column-operation', tf, this);
let opts = this.opts,
labelId = opts.id,
colIndex = opts.col,
operation = opts.operation,
outputType = opts.write_method,
totRowIndex = opts.tot_row_index,
excludeRow = opts.exclude_row,
decimalPrecision = isUndef(opts.decimal_precision) ?
2 : opts.decimal_precision;
let colIndexes = this.colIndexes,
colOperations = this.operations,
outputTypes = this.outputTypes,
totRowIndexes = this.totRowIndexes,
excludeRows = this.excludeRows,
decimalPrecisions = isUndef(this.decimalPrecisions) ?
2 : this.decimalPrecisions;
//nuovella: determine unique list of columns to operate on
let ucolIndex = [],
ucolMax = 0;
ucolIndex[ucolMax] = colIndex[0];
let uIndexes = [];
colIndexes.forEach((val) => {
if (uIndexes.indexOf(val) === -1) {
uIndexes.push(val);
}
});
for (let ii = 1; ii < colIndex.length; ii++) {
let saved = 0;
//see if colIndex[ii] is already in the list of unique indexes
for (let jj = 0; jj <= ucolMax; jj++) {
if (ucolIndex[jj] === colIndex[ii]) {
saved = 1;
let nbCols = uIndexes.length - 1,
rows = tf.tbl.rows,
colValues = [];
for (let u = 0; u <= nbCols; u++) {
//this retrieves col values
//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)
);
let curValues = colValues[u];
//next: calculate all operations for this column
let result = 0,
operations = [],
precisions = [],
labels = [],
writeType,
idx = 0;
for (let k = 0; k < colIndexes.length; k++) {
if (colIndexes[k] !== uIndexes[u]) {
continue;
}
operations[idx] = colOperations[k].toLowerCase();
precisions[idx] = decimalPrecisions[k];
labels[idx] = this.labelIds[k];
writeType = isArray(outputTypes) ? outputTypes[k] : null;
idx++;
}
//if not saved then, save the index;
if (saved === 0) {
ucolMax++;
ucolIndex[ucolMax] = colIndex[ii];
}
}
if (isArray(labelId) && isArray(colIndex) && isArray(operation)) {
let rows = tf.tbl.rows,
colvalues = [],
ucol = 0;
for (; ucol <= ucolMax; ucol++) {
//this retrieves col values
//use ucolIndex because we only want to pass through this loop
//once for each column get the values in this unique column
colvalues.push(
tf.getColValues(ucolIndex[ucol], false, true, excludeRow)
for (let i = 0; i <= idx; i++) {
// emit values before column calculation
this.emitter.emit(
'before-column-calc',
tf,
this,
uIndexes[u],
curValues,
operations[i],
precisions[i]
);
//next: calculate all operations for this column
let result,
nbvalues = 0,
temp,
meanValue = 0,
sumValue = 0,
minValue = null,
maxValue = null,
q1Value = null,
medValue = null,
q3Value = null,
meanFlag = 0,
sumFlag = 0,
minFlag = 0,
maxFlag = 0,
q1Flag = 0,
medFlag = 0,
q3Flag = 0,
theList = [],
opsThisCol = [],
decThisCol = [],
labThisCol = [],
oTypeThisCol = [],
mThisCol = -1,
k = 0,
j = 0,
i = 0;
result = Number(this.calc(curValues, operations[i], null));
for (; k < colIndex.length; k++) {
if (colIndex[k] === ucolIndex[ucol]) {
mThisCol++;
opsThisCol[mThisCol] = operation[k].toLowerCase();
decThisCol[mThisCol] = decimalPrecision[k];
labThisCol[mThisCol] = labelId[k];
oTypeThisCol = isArray(outputType) ?
outputType[k] : null;
// emit column calculation result
this.emitter.emit(
'column-calc',
tf,
this,
uIndexes[u],
result,
operations[i],
precisions[i]
);
switch (opsThisCol[mThisCol]) {
case 'mean':
meanFlag = 1;
break;
case 'sum':
sumFlag = 1;
break;
case 'min':
minFlag = 1;
break;
case 'max':
maxFlag = 1;
break;
case 'median':
medFlag = 1;
break;
case 'q1':
q1Flag = 1;
break;
case 'q3':
q3Flag = 1;
break;
}
}
}
// write result in expected DOM element
this.writeResult(
result,
labels[i],
writeType,
precisions[i]
);
for (; j < colvalues[ucol].length; j++) {
//sort the list for calculation of median and quartiles
if ((q1Flag === 1) || (q3Flag === 1) || (medFlag === 1)) {
if (j < colvalues[ucol].length - 1) {
for (k = j + 1; k < colvalues[ucol].length; k++) {
/* eslint-disable */
if (eval(colvalues[ucol][k]) <
eval(colvalues[ucol][j])) {
/* eslint-enable */
temp = colvalues[ucol][j];
colvalues[ucol][j] = colvalues[ucol][k];
colvalues[ucol][k] = temp;
}
}
}
}
let cvalue = parseFloat(colvalues[ucol][j]);
theList[j] = parseFloat(cvalue);
}//for i
if (!isNaN(cvalue)) {
nbvalues++;
if (sumFlag === 1 || meanFlag === 1) {
sumValue += parseFloat(cvalue);
}
if (minFlag === 1) {
if (minValue === null) {
minValue = parseFloat(cvalue);
} else {
minValue = parseFloat(cvalue) < minValue ?
parseFloat(cvalue) : minValue;
}
}
if (maxFlag === 1) {
if (maxValue === null) {
maxValue = parseFloat(cvalue);
} else {
maxValue = parseFloat(cvalue) > maxValue ?
parseFloat(cvalue) : maxValue;
}
}
}
}//for j
if (meanFlag === 1) {
meanValue = sumValue / nbvalues;
}
if (medFlag === 1) {
let aux = 0;
if (nbvalues % 2 === 1) {
aux = Math.floor(nbvalues / 2);
medValue = theList[aux];
} else {
medValue = (theList[nbvalues / 2] +
theList[((nbvalues / 2) - 1)]) / 2;
}
}
let posa;
if (q1Flag === 1) {
posa = 0.0;
posa = Math.floor(nbvalues / 4);
if (4 * posa === nbvalues) {
q1Value = (theList[posa - 1] + theList[posa]) / 2;
} else {
q1Value = theList[posa];
}
}
if (q3Flag === 1) {
posa = 0.0;
let posb = 0.0;
posa = Math.floor(nbvalues / 4);
if (4 * posa === nbvalues) {
posb = 3 * posa;
q3Value = (theList[posb] + theList[posb - 1]) / 2;
} else {
q3Value = theList[nbvalues - posa - 1];
}
}
for (; i <= mThisCol; i++) {
switch (opsThisCol[i]) {
case 'mean':
result = meanValue;
break;
case 'sum':
result = sumValue;
break;
case 'min':
result = minValue;
break;
case 'max':
result = maxValue;
break;
case 'median':
result = medValue;
break;
case 'q1':
result = q1Value;
break;
case 'q3':
result = q3Value;
break;
}
let precision = !isNaN(decThisCol[i]) ? decThisCol[i] : 2;
//if outputType is defined
if (oTypeThisCol && result) {
result = result.toFixed(precision);
if (elm(labThisCol[i])) {
switch (oTypeThisCol.toLowerCase()) {
case 'innerhtml':
if (isNaN(result) || !isFinite(result) ||
nbvalues === 0) {
elm(labThisCol[i]).innerHTML = '.';
} else {
elm(labThisCol[i]).innerHTML = result;
}
break;
case 'setvalue':
elm(labThisCol[i]).value = result;
break;
case 'createtextnode':
let oldnode =
elm(labThisCol[i]).firstChild;
let txtnode = createText(result);
elm(labThisCol[i])
.replaceChild(txtnode, oldnode);
break;
}//switch
}
} else {
try {
if (isNaN(result) || !isFinite(result) ||
nbvalues === 0) {
elm(labThisCol[i]).innerHTML = '.';
} else {
elm(labThisCol[i]).innerHTML =
result.toFixed(precision);
}
} catch (e) { }//catch
}//else
}//for i
// row(s) with result are always visible
let totRow = totRowIndex && totRowIndex[ucol] ?
rows[totRowIndex[ucol]] : null;
if (totRow) {
totRow.style.display = '';
}
}//for ucol
}//if typeof
// row(s) with result are always visible
let totRow = totRowIndexes && totRowIndexes[u] ?
rows[totRowIndexes[u]] : null;
if (totRow) {
totRow.style.display = '';
}
}//for u
this.onAfterOperation(tf, this);
this.emitter.emit('after-column-operation', tf, this);
}
/**
* Remove extension
* Make desired calculation on specified column.
* @param {Number} colIndex Column index
* @param {String} [operation=SUM] Operation type
* @param {Number} precision Decimal precision
* @returns {Number}
*/
columnCalc(colIndex, operation = SUM, precision) {
let excludeRows = this.excludeRows || [];
let colValues =
this.tf.getFilteredDataCol(colIndex, false, true, excludeRows);
return this.calc(colValues, operation, precision);
}
/**
* Make calculation on passed values.
* @param {Array} values List of values
* @param {String} [operation=SUM] Optional operation type
* @param {Number} precision Optional result precision
* @returns {Number}
* @private
*/
calc(colValues, operation = SUM, precision) {
let result = 0;
if (operation === Q1 || operation === Q3 || operation === MEDIAN) {
colValues = this.sortColumnValues(colValues, numSortAsc);
}
switch (operation) {
case MEAN:
result = this.calcMean(colValues);
break;
case SUM:
result = this.calcSum(colValues);
break;
case MIN:
result = this.calcMin(colValues);
break;
case MAX:
result = this.calcMax(colValues);
break;
case MEDIAN:
result = this.calcMedian(colValues);
break;
case Q1:
result = this.calcQ1(colValues);
break;
case Q3:
result = this.calcQ3(colValues);
break;
}
return isEmpty(precision) ? result : result.toFixed(precision);
}
/**
* Calculate the sum of passed values.
* @param {Array} [values=[]] List of values
* @returns {Number}
*/
calcSum(values = []) {
if (isEmpty(values)) {
return 0;
}
let result = values.reduce((x, y) => Number(x) + Number(y));
return result;
}
/**
* Calculate the mean of passed values.
* @param {Array} [values=[]] List of values
* @returns {Number}
*/
calcMean(values = []) {
let result = this.calcSum(values) / values.length;
return Number(result);
}
/**
* Calculate the max value of passed values.
* @param {Array} [values=[]] List of values
* @returns {Number}
*/
calcMax(values = []) {
return Math.max.apply(null, values);
}
/**
* Calculate the min value of passed values.
* @param {Array} [values=[]] List of values
* @returns {Number}
*/
calcMin(values = []) {
return Math.min.apply(null, values);
}
/**
* Calculate the median of passed values.
* @param {Array} [values=[]] List of values
* @returns {Number}
*/
calcMedian(values = []) {
let nbValues = values.length;
let aux = 0;
if (nbValues % 2 === 1) {
aux = Math.floor(nbValues / 2);
return Number(values[aux]);
}
return (Number(values[nbValues / 2]) +
Number(values[((nbValues / 2) - 1)])) / 2;
}
/**
* Calculate the lower quartile of passed values.
* @param {Array} [values=[]] List of values
* @returns {Number}
*/
calcQ1(values = []) {
let nbValues = values.length;
let posa = 0.0;
posa = Math.floor(nbValues / 4);
if (4 * posa === nbValues) {
return (Number(values[posa - 1]) +
Number(values[posa])) / 2;
}
return Number(values[posa]);
}
/**
* Calculate the upper quartile of passed values.
* @param {Array} [values=[]] List of values
* @returns {Number}
*/
calcQ3(values = []) {
let nbValues = values.length;
let posa = 0.0;
let posb = 0.0;
posa = Math.floor(nbValues / 4);
if (4 * posa === nbValues) {
posb = 3 * posa;
return (Number(values[posb]) +
Number(values[posb - 1])) / 2;
}
return Number(values[nbValues - posa - 1]);
}
/**
* Sort passed values with supplied sorter function.
* @param {Array} [values=[]] List of values to be sorted
* @param {Function} sorter Sorter function
* @returns {Array}
*/
sortColumnValues(values = [], sorter) {
return values.sort(sorter);
}
/**
* Write calculation result in passed DOM element with supplied write method
* and decimal precision.
* @param {Number} [result=0] Calculation result
* @param {DOMElement} label DOM element
* @param {String} [writeType='innerhtml'] Write method
* @param {Number} [precision=2] Applied decimal precision
* @private
*/
writeResult(result = 0, label, writeType = 'innerhtml', precision = 2) {
let labelElm = elm(label);
if (!labelElm) {
return;
}
result = result.toFixed(precision);
if (isNaN(result) || !isFinite(result)) {
result = '';
}
switch (writeType.toLowerCase()) {
case 'innerhtml':
labelElm.innerHTML = result;
break;
case 'setvalue':
labelElm.value = result;
break;
case 'createtextnode':
let oldNode = labelElm.firstChild;
let txtNode = createText(result);
labelElm.replaceChild(txtNode, oldNode);
break;
}
}
/** Remove extension */
destroy() {
if (!this.initialized) {
return;
}
// unsubscribe to events
this.emitter.off(EVENTS, () => this.calc());
this.emitter.off(EVENTS, () => this.calcAll());
this.initialized = false;
}

View file

@ -4,7 +4,8 @@ import {
getText
} from '../../dom';
import {isFn, EMPTY_FN} from '../../types';
import {addEvt, targetEvt} from '../../event';
import {addEvt, targetEvt, removeEvt} from '../../event';
import {root} from '../../root';
/**
* Columns Visibility extension
@ -205,6 +206,12 @@ export default class ColsVisibility extends Feature {
*/
this.hiddenCols = [];
/**
* Bound mouseup wrapper
* @private
*/
this.boundMouseup = null;
/**
* Callback fired when the extension is initialized
* @type {Function}
@ -281,10 +288,32 @@ export default class ColsVisibility extends Feature {
this.enable();
}
/**
* Mouse-up event handler handling popup auto-close behaviour
* @private
*/
onMouseup(evt) {
let targetElm = targetEvt(evt);
while (targetElm && targetElm !== this.contEl
&& targetElm !== this.btnEl) {
targetElm = targetElm.parentNode;
}
if (targetElm !== this.contEl && targetElm !== this.btnEl) {
this.toggle();
}
return;
}
/**
* Toggle columns manager UI
*/
toggle() {
// ensure mouseup event handler is removed
removeEvt(root, 'mouseup', this.boundMouseup);
let contDisplay = this.contEl.style.display;
if (contDisplay !== 'inline') {
@ -299,6 +328,7 @@ export default class ColsVisibility extends Feature {
if (contDisplay !== 'inline') {
this.onAfterOpen(this);
addEvt(root, 'mouseup', this.boundMouseup);
}
if (contDisplay === 'inline') {
this.onAfterClose(this);
@ -345,11 +375,11 @@ export default class ColsVisibility extends Feature {
this.buildBtn();
this.buildManager();
/**
* @inherited
*/
/** @inherited */
this.initialized = true;
this.boundMouseup = this.onMouseup.bind(this);
this.emitter.emit('columns-visibility-initialized', this.tf, this);
// Hide columns at start at very end of initialization, do not move
@ -665,6 +695,8 @@ export default class ColsVisibility extends Feature {
this.emitter.off(['hide-column'],
(tf, colIndex) => this.hideCol(colIndex));
this.boundMouseup = null;
this.initialized = false;
}

View file

@ -271,12 +271,12 @@ export class CheckList extends Feature {
continue;
}
let cellData = tf.getCellData(cells[j]);
let cellValue = tf.getCellValue(cells[j]);
//Vary Peter's patch
let cellString = matchCase(cellData, caseSensitive);
let cellString = matchCase(cellValue, caseSensitive);
// checks if celldata is already in array
if (!has(this.opts, cellString, caseSensitive)) {
this.opts.push(cellData);
this.opts.push(cellValue);
}
let filteredCol = filteredDataCol[j];
if (isLinked && tf.disableExcludedOptions) {
@ -286,7 +286,7 @@ export class CheckList extends Feature {
if (!has(filteredCol, cellString, caseSensitive) &&
!has(this.excludedOpts, cellString,
caseSensitive)) {
this.excludedOpts.push(cellData);
this.excludedOpts.push(cellValue);
}
}
}

View file

@ -228,13 +228,13 @@ export class Dropdown extends Feature {
continue;
}
let cellData = tf.getCellData(cell[j]),
let cellValue = tf.getCellValue(cell[j]),
//Vary Peter's patch
cellString = matchCase(cellData, tf.caseSensitive);
cellString = matchCase(cellValue, tf.caseSensitive);
// checks if celldata is already in array
if (!has(this.opts, cellString, tf.caseSensitive)) {
this.opts.push(cellData);
this.opts.push(cellValue);
}
if (isLinked && tf.disableExcludedOptions) {
@ -244,7 +244,7 @@ export class Dropdown extends Feature {
}
if (!has(filteredCol, cellString, tf.caseSensitive) &&
!has(excludedOpts, cellString, tf.caseSensitive)) {
excludedOpts.push(cellData);
excludedOpts.push(cellValue);
}
}
}//for j

View file

@ -131,12 +131,16 @@ export class TableFilter {
}
});
if (!this.tbl || this.tbl.nodeName !== 'TABLE' ||
this.getRowsNb() === 0) {
if (!this.tbl || this.tbl.nodeName !== 'TABLE') {
throw new Error(`Could not instantiate TableFilter: HTML table
DOM element not found.`);
}
if (this.getRowsNb() === 0) {
throw new Error(`Could not instantiate TableFilter: HTML table
requires at least 1 row.`);
}
// configuration object
let f = this.cfg;
@ -148,7 +152,6 @@ export class TableFilter {
//Start row et cols nb
this.refRow = isUndef(startRow) ? 2 : (startRow + 1);
this.nbCells = this.getCellsNb(this.refRow);
/**
* Base path for static assets
@ -1009,6 +1012,7 @@ export class TableFilter {
return;
}
this.nbCells = this.getCellsNb(this.refRow);
let Mod = this.Mod;
let n = this.singleSearchFlt ? 1 : this.nbCells;
let inpclass;
@ -1748,7 +1752,7 @@ export class TableFilter {
continue;
}
let cellData = matchCase(this.getCellData(cells[j]),
let cellValue = matchCase(this.getCellValue(cells[j]),
this.caseSensitive);
//multiple search parameter operator ||
@ -1773,7 +1777,7 @@ export class TableFilter {
// isolate search term and check occurence in cell data
for (let w = 0, len = s.length; w < len; w++) {
cS = trim(s[w]);
occur = this._testTerm(cS, cellData, j);
occur = this._testTerm(cS, cellValue, j);
if (occur) {
this.emitter.emit('highlight-keyword', this,
@ -1792,7 +1796,7 @@ export class TableFilter {
}
//single search parameter
else {
occurence[j] = this._testTerm(trim(sA), cellData, j);
occurence[j] = this._testTerm(trim(sA), cellValue, j);
if (occurence[j]) {
this.emitter.emit('highlight-keyword', this, cells[j],
sA);
@ -1833,11 +1837,11 @@ export class TableFilter {
/**
* Test for a match of search term in cell data
* @param {String} term Search term
* @param {String} cellData Cell data
* @param {String} cellValue Cell data
* @param {Number} colIdx Column index
* @returns {Boolean}
*/
_testTerm(term, cellData, colIdx) {
_testTerm(term, cellValue, colIdx) {
let numData;
let decimal = this.decimalSeparator;
let reLe = new RegExp(this.leOperator),
@ -1897,7 +1901,7 @@ export class TableFilter {
let isEQDate = hasEQ &&
isValidDate(term.replace(reEq, ''), locale);
dte1 = parseDate(cellData, locale);
dte1 = parseDate(cellValue, locale);
// lower date
if (isLDate) {
@ -1931,7 +1935,7 @@ export class TableFilter {
}
// searched keyword with * operator doesn't have to be a date
else if (reLk.test(term)) {// like date
occurence = contains(term.replace(reLk, ''), cellData,
occurence = contains(term.replace(reLk, ''), cellValue,
false, this.caseSensitive);
}
else if (isValidDate(term)) {
@ -1940,13 +1944,13 @@ export class TableFilter {
}
//empty
else if (hasEM) {
occurence = isEmptyString(cellData);
occurence = isEmptyString(cellValue);
}
//non-empty
else if (hasNM) {
occurence = !isEmptyString(cellData);
occurence = !isEmptyString(cellValue);
} else {
occurence = contains(term, cellData,
occurence = contains(term, cellValue,
this.isExactMatch(colIdx), this.caseSensitive);
}
}
@ -1960,7 +1964,7 @@ export class TableFilter {
}
// Convert to number anyways to auto-resolve type in case not
// defined by configuration
numData = Number(cellData) || parseNb(cellData, decimal);
numData = Number(cellValue) || parseNb(cellValue, decimal);
// first checks if there is any operator (<,>,<=,>=,!,*,=,{,},
// rgx:)
@ -1994,40 +1998,40 @@ export class TableFilter {
}
//different
else if (hasDF) {
occurence = contains(term.replace(reD, ''), cellData,
occurence = contains(term.replace(reD, ''), cellValue,
false, this.caseSensitive) ? false : true;
}
//like
else if (hasLK) {
occurence = contains(term.replace(reLk, ''), cellData,
occurence = contains(term.replace(reLk, ''), cellValue,
false, this.caseSensitive);
}
//equal
else if (hasEQ) {
occurence = contains(term.replace(reEq, ''), cellData,
occurence = contains(term.replace(reEq, ''), cellValue,
true, this.caseSensitive);
}
//starts with
else if (hasST) {
occurence = cellData.indexOf(term.replace(reSt, '')) === 0 ?
occurence = cellValue.indexOf(term.replace(reSt, '')) === 0 ?
true : false;
}
//ends with
else if (hasEN) {
let searchArg = term.replace(reEn, '');
occurence =
cellData.lastIndexOf(searchArg, cellData.length - 1) ===
(cellData.length - 1) - (searchArg.length - 1) &&
cellData.lastIndexOf(searchArg, cellData.length - 1)
cellValue.lastIndexOf(searchArg, cellValue.length - 1) ===
(cellValue.length - 1) - (searchArg.length - 1) &&
cellValue.lastIndexOf(searchArg, cellValue.length - 1)
> -1 ? true : false;
}
//empty
else if (hasEM) {
occurence = isEmptyString(cellData);
occurence = isEmptyString(cellValue);
}
//non-empty
else if (hasNM) {
occurence = !isEmptyString(cellData);
occurence = !isEmptyString(cellValue);
}
//regexp
else if (hasRE) {
@ -2036,7 +2040,7 @@ export class TableFilter {
//operator is removed
let srchArg = term.replace(reRe, '');
let rgx = new RegExp(srchArg);
occurence = rgx.test(cellData);
occurence = rgx.test(cellValue);
} catch (ex) {
occurence = false;
}
@ -2057,7 +2061,7 @@ export class TableFilter {
// Finally test search term is contained in cell data
occurence = contains(
term,
cellData,
cellValue,
this.isExactMatch(colIdx),
this.caseSensitive,
this.ignoresDiacritics(colIdx)
@ -2073,18 +2077,25 @@ export class TableFilter {
/**
* Return the data of a specified column
* @param {Number} colIndex Column index
* @param {Boolean} includeHeaders Optional: include headers row
* @param {Boolean} num Optional: return unformatted number
* @param {Array} exclude Optional: list of row indexes to be excluded
* @param {Boolean} [includeHeaders=false] Include headers row
* @param {Boolean} [typed=true] Return a typed value
* @param {Array} [exclude=[]] List of row indexes to be excluded
* @return {Array} Flat list of data for a column
*/
getColValues(colIndex, includeHeaders = false, num = false, exclude = []) {
getColValues(
colIndex,
includeHeaders = false,
typed = false,
exclude = []
) {
if (!this.fltGrid) {
return;
}
let row = this.tbl.rows;
let nbRows = this.getRowsNb(true);
let colValues = [];
let getContent = typed ? this.getCellData.bind(this) :
this.getCellValue.bind(this);
if (includeHeaders) {
colValues.push(this.getHeadersText()[colIndex]);
@ -2103,20 +2114,10 @@ export class TableFilter {
if (nchilds === this.nbCells && !isExludedRow) {
// this loop retrieves cell data
for (let j = 0; j < nchilds; j++) {
if (j !== colIndex || row[i].style.display !== '') {
if (j !== colIndex) {
continue;
}
let cellData = this.getCellData(cell[j]);
let decimal = this.decimalSeparator;
if (this.hasType(colIndex, [FORMATTED_NUMBER])) {
let colType = this.colTypes[colIndex];
if (colType.hasOwnProperty('decimal')) {
decimal = colType.decimal;
}
}
let data = num ?
Number(cellData) || parseNb(cellData, decimal) :
cellData;
let data = getContent(cell[j]);
colValues.push(data);
}
}
@ -2234,7 +2235,7 @@ export class TableFilter {
*/
getCellsNb(rowIndex = 0) {
let tr = this.tbl.rows[rowIndex >= 0 ? rowIndex : 0];
return tr.cells.length;
return tr ? tr.cells.length : 0;
}
/**
@ -2252,14 +2253,10 @@ export class TableFilter {
return parseInt(ntrs - s, 10);
}
/**
* Return the data of a given cell
* @param {DOMElement} cell Cell's DOM object
* @return {String}
*/
getCellData(cell) {
getCellValue(cell) {
let idx = cell.cellIndex;
//Fire customCellData callback
//CallcustomCellData callback
if (this.customCellDataCols.indexOf(idx) !== -1) {
return this.customCellData(this, cell, idx);
} else {
@ -2267,22 +2264,59 @@ export class TableFilter {
}
}
/**
* Return the typed data of a given cell based on the column type definition
* @param {DOMElement} cell Cell's DOM object
* @return {String|Number|Date}
*/
getCellData(cell) {
let colIndex = cell.cellIndex;
let value = this.getCellValue(cell);
if (this.hasType(colIndex, [FORMATTED_NUMBER])) {
let decimal = this.decimalSeparator;
let colType = this.colTypes[colIndex];
if (colType.hasOwnProperty('decimal')) {
decimal = colType.decimal;
}
return parseNb(value, decimal);
}
else if (this.hasType(colIndex, [NUMBER])) {
return Number(value);
}
else if (this.hasType(colIndex, [DATE])){
let dateType = this.Mod.dateType;
let locale = dateType.getOptions(colIndex).locale || this.locale;
return dateType.parse(value, locale);
}
return value;
}
/**
* Return the table data with following format:
* [
* [rowIndex, [value0, value1...]],
* [rowIndex, [value0, value1...]]
* ]
* @param {Boolean} includeHeaders Optional: include headers row
* @param {Boolean} excludeHiddenCols Optional: exclude hidden columns
* @param {Boolean} [includeHeaders=false] Include headers row
* @param {Boolean} [excludeHiddenCols=false] Exclude hidden columns
* @param {Boolean} [typed=false] Return typed value
* @return {Array}
*
* TODO: provide an API returning data in JSON format
*/
getTableData(includeHeaders = false, excludeHiddenCols = false) {
getTableData(
includeHeaders = false,
excludeHiddenCols = false,
typed = false
) {
let rows = this.tbl.rows;
let nbRows = this.getRowsNb(true);
let tblData = [];
let getContent = typed ? this.getCellData.bind(this) :
this.getCellValue.bind(this);
if (includeHeaders) {
let headers = this.getHeadersText(excludeHiddenCols);
tblData.push([this.getHeadersRowIndex(), headers]);
@ -2296,8 +2330,8 @@ export class TableFilter {
continue;
}
}
let cellData = this.getCellData(cells[j]);
rowData[1].push(cellData);
let cellValue = getContent(cells[j]);
rowData[1].push(cellValue);
}
tblData.push(rowData);
}
@ -2310,18 +2344,26 @@ export class TableFilter {
* [rowIndex, [value0, value1...]],
* [rowIndex, [value0, value1...]]
* ]
* @param {Boolean} includeHeaders Optional: include headers row
* @param {Boolean} excludeHiddenCols Optional: exclude hidden columns
* @param {Boolean} [includeHeaders=false] Include headers row
* @param {Boolean} [excludeHiddenCols=false] Exclude hidden columns
* @param {Boolean} [typed=false] Return typed value
* @return {Array}
*
* TODO: provide an API returning data in JSON format
*/
getFilteredData(includeHeaders = false, excludeHiddenCols = false) {
getFilteredData(
includeHeaders = false,
excludeHiddenCols = false,
typed = false
) {
if (!this.validRowsIndex) {
return [];
}
let rows = this.tbl.rows,
filteredData = [];
let getContent = typed ? this.getCellData.bind(this) :
this.getCellValue.bind(this);
if (includeHeaders) {
let headers = this.getHeadersText(excludeHiddenCols);
filteredData.push([this.getHeadersRowIndex(), headers]);
@ -2337,8 +2379,8 @@ export class TableFilter {
continue;
}
}
let cellData = this.getCellData(cells[k]);
rData[1].push(cellData);
let cellValue = getContent(cells[k]);
rData[1].push(cellValue);
}
filteredData.push(rData);
}
@ -2348,29 +2390,49 @@ export class TableFilter {
/**
* Return the filtered data for a given column index
* @param {Number} colIndex Colmun's index
* @param {Boolean} includeHeaders Optional: include headers row
* @param {Boolean} [includeHeaders=false] Include headers row
* @param {Boolean} [typed=false] Return typed value
* @param {Array} [exclude=[]] List of row indexes to be excluded
* @param {Boolean} [visible=true] Return only filtered and visible data
* (relevant for paging)
* @return {Array} Flat list of values ['val0','val1','val2'...]
*
* TODO: provide an API returning data in JSON format
*/
getFilteredDataCol(colIndex, includeHeaders = false) {
getFilteredDataCol(
colIndex,
includeHeaders = false,
typed = false,
exclude = [],
visible = true
) {
if (isUndef(colIndex)) {
return [];
}
let data = this.getFilteredData(),
colData = [];
let rows = this.tbl.rows;
let getContent = typed ? this.getCellData.bind(this) :
this.getCellValue.bind(this);
// ensure valid rows index do not contain excluded rows and row is
// displayed
let validRows = this.getValidRows(true).filter((rowIdx) => {
return exclude.indexOf(rowIdx) === -1 &&
(visible ?
this.getRowDisplay(rows[rowIdx]) !== 'none' :
true);
});
// convert column value to expected type if necessary
let validColValues = validRows.map((rowIdx) => {
return getContent(rows[rowIdx].cells[colIndex]);
});
if (includeHeaders) {
colData.push(this.getHeadersText()[colIndex]);
validColValues.unshift(this.getHeadersText()[colIndex]);
}
for (let i = 0, len = data.length; i < len; i++) {
let r = data[i],
//cols values of current row
d = r[1],
//data of searched column
c = d[colIndex];
colData.push(c);
}
return colData;
return validColValues;
}
/**

View file

@ -63,7 +63,7 @@ export const isUndef = (obj) => obj === UNDEFINED;
* @param {Any} obj
* @return {Boolean}
*/
export const isNull = obj => obj === null;
export const isNull = (obj) => obj === null;
/**
* Check passed argument is empty (undefined, null or empty string)

View file

@ -350,4 +350,4 @@
<td>88.233.19.89</td>
</tr>
</tbody>
</table>
</table>

View file

@ -11,11 +11,12 @@ $item-font-color = #fff
.div_checklist
width 100%
height 90px
line-height 24px
border 1px solid $filter-border-color
overflow auto
text-align left
background-color $filter-bg-color
color: $filter-font-color
color $filter-font-color
ul.flt_checklist
padding 0 !important

View file

@ -74,6 +74,10 @@ select.flt_multi
vertical-align middle
box-sizing border-box
option
padding-top 5px
padding-bottom 5px
// tiny input type filter
.flt_s
@extend .flt

View file

@ -89,4 +89,4 @@
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>
</html>

View file

@ -138,4 +138,4 @@
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>
</html>

View file

@ -1,11 +1,13 @@
var tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/'
base_path: '../dist/tablefilter/',
col_types: ['string', 'string', 'number', 'number', 'number']
});
tf.init();
var tf1 = new TableFilter('demo1', {
base_path: '../dist/tablefilter/',
col_types: ['string', 'string', 'number', 'number', 'number'],
extensions: [{
name: 'colsVisibility',
at_start: [1, 2],
@ -34,11 +36,16 @@ test('TableFilter object', function() {
],
'Headers text');
deepEqual(
tf.getCellData(tf.getHeaderElement(1)),
tf.getCellValue(tf.getHeaderElement(1)),
'Destination',
'Column header text'
);
deepEqual(tf.getValidRowsNb(), 0, 'Number of valid rows before filtering');
deepEqual(
tf.getCellData(tf.tbl.rows[3].cells[2]),
982,
'getCellData returns typed value'
);
});
module('Public methods');
@ -148,6 +155,11 @@ test('Get table data', function() {
],
'Get specified column values including column header'
);
deepEqual(
tf.getColValues(2, false, true),
[1412,982,286,872,2781,1533,2045],
'Get specified column typed values'
);
deepEqual(
tf.getTableData(),
[
@ -176,6 +188,19 @@ test('Get table data', function() {
],
'Get table data including columns headers'
);
deepEqual(
tf.getTableData(false, false, true),
[
[2, ['Sydney','Adelaide',1412,1.4,25.3]],
[3, ['Sydney','Brisbane',982,1.5,16]],
[4, ['Sydney','Canberra',286,0.6,4.3]],
[5, ['Sydney','Melbourne',872,1.1,10.5]],
[6, ['Adelaide','Perth',2781,3.1,38]],
[7, ['Adelaide','Alice Springs',1533,2,20.25]],
[8, ['Adelaide','Brisbane',2045,2.15,40]]
],
'Get table typed data'
);
tf.setFilterValue(0, 'Adelaide');
tf.filter();
deepEqual(
@ -198,6 +223,15 @@ test('Get table data', function() {
],
'Get filtered table data including columns headers'
);
deepEqual(
tf.getFilteredData(false, false, true),
[
[6, ['Adelaide','Perth',2781,3.1,38]],
[7, ['Adelaide','Alice Springs',1533,2,20.25]],
[8, ['Adelaide','Brisbane',2045,2.15,40]]
],
'Get filtered typed data'
);
deepEqual(
tf.getFilteredDataCol(0),
['Adelaide','Adelaide','Adelaide'],
@ -208,6 +242,11 @@ test('Get table data', function() {
['From','Adelaide','Adelaide','Adelaide'],
'Get specified column filtered values including header'
);
deepEqual(
tf.getFilteredDataCol(2, false, true),
[2781,1533,2045],
'Get specified column filtered typed values'
);
tf.clearFilters();
tf.filter();
});
@ -329,13 +368,13 @@ test('Get filters values', function() {
});
// Test case for issue 165
test('Test getCellData with white spaces', function() {
test('Test getCellValue with white spaces', function() {
// setup
var cell = document.createElement('td');
cell.textContent ='\t\thello world\t\t\t';
// act
var result = tf.getCellData(cell);
var result = tf.getCellValue(cell);
//assert
deepEqual(result, 'hello world', 'Expected text with no white spaces');

View file

@ -101,6 +101,7 @@ test('Column operations', function() {
equal(id('q1-2').innerHTML, 1.10, 'Q1 result');
equal(id('q3-1').innerHTML, 2045, 'Q3 result');
equal(id('q3-2').innerHTML, 2.15, 'Q3 result');
tf.clearFilters();
});
module('Behaviour checks');
@ -129,6 +130,7 @@ test('Column operations', function() {
tf.destroy();
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
col_types: ['string', 'string', 'number', 'number', 'number'],
paging: true,
paging_length: 4,
rows_always_visible: [
@ -236,6 +238,7 @@ test('Column operations', function() {
totRowIndex = totRowIndex-2;
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
col_types: ['string', 'string', 'number', 'number', 'number'],
grid_layout: true,
rows_always_visible: [
totRowIndex-6,

View file

@ -60,6 +60,52 @@ test('Toggle column', function() {
ext.toggleCol(2);
deepEqual(ext.isColHidden(2), false, 'Expected column is displayed');
});
test('Popup container auto-closes when user clicks away', function() {
// setup
ext = tf.extension('colsVisibility');
ext.toggle();
// act
var evObj = document.createEvent('HTMLEvents');
evObj.initEvent('mouseup', true, true);
// mouseup fired from a table cell
tf.tbl.rows[3].cells[2].dispatchEvent(evObj);
// assert
deepEqual(ext.contEl.style.display, 'none',
'Popup container closed after user clicks away'
);
});
test('Close button closes popup', function() {
// setup
ext = tf.extension('colsVisibility');
ext.toggle();
// act
var evObj = document.createEvent('HTMLEvents');
evObj.initEvent('click', true, true);
ext.contEl.querySelector('.colVis').dispatchEvent(evObj);
// assert
deepEqual(ext.contEl.style.display, 'none',
'Close button closes popup'
);
});
test('Button closes popup when already open', function() {
// setup
ext = tf.extension('colsVisibility');
ext.toggle();
// act
var evObj = document.createEvent('HTMLEvents');
evObj.initEvent('click', true, true);
ext.btnEl.dispatchEvent(evObj);
// assert
deepEqual(ext.contEl.style.display, 'none',
'Close button closes popup'
);
});
test('Destroy extension', function() {
ext = tf.extension('colsVisibility');
ext.destroy();

19
test/test-no-rows.html Normal file
View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TableFilter no rows tests</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"></table>
<script src="../dist/tablefilter/tablefilter.js"></script>
<script src="test-no-rows.js"></script>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>

10
test/test-no-rows.js Normal file
View file

@ -0,0 +1,10 @@
module('TableFilter with no rows');
test('throws when no rows', function() {
throws(
function() { new TableFilter('demo') },
Error,
'Throws Error when DOM table does not contain rows'
);
});

27
test/test-one-row.html Normal file
View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TableFilter one row tests</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">
<tr>
<th>From</th>
<th>Destination</th>
<th>Road Distance (km)</th>
<th>By Air (hrs)</th>
<th>By Rail (hrs)</th>
</tr>
</table>
<script src="../dist/tablefilter/tablefilter.js"></script>
<script src="test-one-row.js"></script>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>

18
test/test-one-row.js Normal file
View file

@ -0,0 +1,18 @@
var tf = new TableFilter('demo', 0, {
base_path: '../dist/tablefilter/'
});
tf.init();
module('Sanity checks');
test('Only headers with no rows', function() {
deepEqual(tf instanceof TableFilter, true, 'TableFilter instanciated');
deepEqual(tf.nbCells, 0, 'Number of columns');
deepEqual(tf.refRow, 1, 'Reference row index');
});
module('Tear-down');
test('TableFilter removed', function() {
tf.clearFilters();
tf.destroy();
deepEqual(tf.isInitialized(), false, 'Filters removed');
});

View file

@ -75,4 +75,4 @@
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>
</html>

View file

@ -105,6 +105,7 @@
});
test('Can instantiate with wrong refRow', function() {
var tf2 = new TableFilter('demo', -9);
tf2.init();
deepEqual(tf2.nbCells, 5, 'Expected number of columns');
});