From 8b5400f9886113b39fc52d9297e1285745bde047 Mon Sep 17 00:00:00 2001
From: Eugen Neuber <eugen.neuber@tugraz.at>
Date: Wed, 15 Jan 2020 17:11:02 +0100
Subject: [PATCH] Add searching in one column only

TODO: sum works only in general search, not in one column only search
See issue #3
---
 packages/data-table-view/README.md            |  2 +
 .../src/vpu-data-table-view-demo.js           | 20 +++++--
 .../src/vpu-data-table-view.js                | 57 +++++++++++++++++--
 3 files changed, 71 insertions(+), 8 deletions(-)

diff --git a/packages/data-table-view/README.md b/packages/data-table-view/README.md
index d1621945..1bfc953e 100644
--- a/packages/data-table-view/README.md
+++ b/packages/data-table-view/README.md
@@ -19,6 +19,8 @@
     - example `<vpu-data-table-view exportable></pu-data-table-view>`
 - `export-name` (optional, default: 'Data Export'): add name for download file (without extension)
     - example `<vpu-data-table-view exportable export-name="All Items"></pu-data-table-view>`
+- `column-searching` (optional, default false): add search fields for every column
+    - example `<vpu-data-table-view column-searching></pu-data-table-view>`
 
 # Local development
 ```bash
diff --git a/packages/data-table-view/src/vpu-data-table-view-demo.js b/packages/data-table-view/src/vpu-data-table-view-demo.js
index 4e10bbfe..8cba2896 100644
--- a/packages/data-table-view/src/vpu-data-table-view-demo.js
+++ b/packages/data-table-view/src/vpu-data-table-view-demo.js
@@ -1,7 +1,7 @@
 import 'vpu-auth';
 import './vpu-data-table-view.js';
 import {i18n} from './i18n';
-import {html, css, LitElement} from 'lit-element';
+import {css, html, LitElement} from 'lit-element';
 import * as commonUtils from 'vpu-common/utils';
 import * as commonStyles from 'vpu-common/styles';
 
@@ -41,7 +41,8 @@ class DataTableViewDemo extends LitElement {
                 }
                 vdtv1.set_columns([{title:'Bezeichnung'}, {title:'Nummer'}, {title:'Datum'}, null, null])
                     .set_columnDefs(vdtv1_columnDefs)
-                    .set_datatable(tbl);
+                    .set_datatable(tbl)
+                    .on('draw', this.vdtv_preDraw.bind(this));
             }
 
             /*
@@ -55,7 +56,7 @@ class DataTableViewDemo extends LitElement {
                     { targets: [3, 4], searchable: false },
                     { targets: [4], sortable: false }
                 ];
-                vdtv2.set_columns([{title:'Bezeichnung'}, {title:'Nummer'}, {title:'Datum'}, null, null])
+                vdtv2.set_columns([{title:'Bezeichnung-2'}, {title:'Nummer-2'}, {title:'Datum-2'}, null, null])
                     .set_columnDefs(vdtv2_columnDefs)
                     .set_datatable([]);
             }
@@ -86,6 +87,15 @@ class DataTableViewDemo extends LitElement {
         ];
     }
 
+    vdtv_preDraw() {
+        const vdtv1 = this.shadowRoot.querySelector('#vdtv1');
+        const value = vdtv1.columnReduce(1, function (a, b) {
+            return a + b;
+        });
+        console.log('preDraw sum=' + value);
+        this.shadowRoot.querySelector('#id-sum').value = value;
+    }
+
     vdtv2_add_rows() {
         console.log('vdtv2_add_rows() clicked');
         const vdtv2 = this.shadowRoot.querySelector('#vdtv2');
@@ -163,7 +173,9 @@ class DataTableViewDemo extends LitElement {
                 <div class="content">
                     <h4>DataTable: with data, paging and searching AND exportable</h4>
                      <div class="box">
-                        <vpu-data-table-view paging searching exportable export-name="Demo Export"
+                        <label for="id-sum">Sum of Number</label>
+                        <input type="text" readonly value="" name="sum" id="id-sum">
+                        <vpu-data-table-view paging searching exportable export-name="Demo Export" column-searching
                                              lang="${this.lang}" id="vdtv1"></vpu-data-table-view>
                     </div>
                     <h4>DataTable: no data, no paging, no searching</h4>
diff --git a/packages/data-table-view/src/vpu-data-table-view.js b/packages/data-table-view/src/vpu-data-table-view.js
index 36f0ee35..d1a82b4c 100644
--- a/packages/data-table-view/src/vpu-data-table-view.js
+++ b/packages/data-table-view/src/vpu-data-table-view.js
@@ -38,6 +38,7 @@ class DataTableView extends LitElement {
         this.cssStyle = '';
         this.exportable = false;
         this.exportName = 'Data Export';
+        this.columnSearching = false;
     }
 
     setCSSStyle(style) {
@@ -55,7 +56,8 @@ class DataTableView extends LitElement {
             data: { type: Array, attribute: false },
             cssStyle: { type: String, attribute: false },
             exportable: { type: Boolean },
-            exportName: { type: String, attribute: 'export-name' }
+            exportName: { type: String, attribute: 'export-name' },
+            columnSearching: { type: Boolean, attribute: 'column-searching'},
         };
     }
 
@@ -76,14 +78,24 @@ class DataTableView extends LitElement {
         this.table.draw();
         return this;
     }
+    columnSearch(col, str) {
+        this.table.column(col).search(str).draw();
+    }
+    columnReduce(col, func, init=0) {
+        return this.table.column(col, { search: 'applied' }).data().reduce( func, init);
+    }
+    on(eventName, func) {
+        this.table.on(eventName, func);
+        return this;
+    }
 
     set_datatable(data) {
         const lang_obj = this.lang === 'de' ? de : en;
 
-        if (!this.columns.length) {
+        if (typeof this.columns === 'undefined' || !this.columns.length) {
             if (data.length)
                 throw new Error('columns not set-up');
-            return;
+            return this;
         }
 
         this.table = $(this.shadowRoot.querySelector('table')).DataTable({
@@ -136,11 +148,48 @@ class DataTableView extends LitElement {
 
         this.data = data;
 
-        this.table.clear().rows.add(this.data).draw();
+        this.table.clear();
+        if (this.data.length) { this.table.rows.add(this.data); }
+        this.table.draw();
 
         new $.fn.dataTable.Responsive(this.table, {
             details: true
         });
+
+        if (this.columnSearching) {
+            const existing_tfoot = this.shadowRoot.querySelector('table tfoot');
+            if (existing_tfoot === null || !existing_tfoot.hasChildNodes()) {
+                const thisTable = this.table;
+                const fragment = document.createDocumentFragment();
+                const tfoot = document.createElement('tfoot');
+                const tr = document.createElement('tr');
+                const that = this;
+                this.columns.forEach(function (element, index) {
+                    const th = document.createElement('th');
+                    if (element !== null
+                        && (typeof element.visible === 'undefined' || element.visible !== false)
+                        && (typeof element.searchable === 'undefined' || element.searchable !== false)) {
+                        const inp = document.createElement('input');
+                        inp.type = 'text';
+                        inp.placeholder = 'Search ' + element.title;
+                        inp.addEventListener('keyup', function () {
+                            thisTable.column(index).search(inp.value).draw();
+//                            console.log('on keyup: '+index+','+inp.value+' sum = '+that.columnReduce(index, function(a,b){return a+b;}));
+
+                        });
+                        th.appendChild(inp);
+                        console.log('inp for ' + element.title);
+                    }
+                    tr.appendChild(th);
+                    //fragment.appendChild(th);
+                });
+                tfoot.appendChild(tr);
+                fragment.appendChild(tfoot);
+                //this.shadowRoot.querySelector('tfoot').appendChild(fragment);
+                this.shadowRoot.querySelector('table').appendChild(fragment);
+            }
+        }
+        return this;
     }
 
     update(changedProperties) {
-- 
GitLab