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

Added highlight keyword feature + associated tests

This commit is contained in:
Max Guglielmi 2014-12-13 20:04:25 +11:00
parent 06ffffaada
commit 0f4d81b9a5
8 changed files with 161 additions and 151 deletions

2
dist/filtergrid.css vendored
View file

@ -1,6 +1,6 @@
/*------------------------------------------------------------------------ /*------------------------------------------------------------------------
- TableFilter stylesheet by Max Guglielmi - TableFilter stylesheet by Max Guglielmi
- (build date: Fri Dec 05 2014 11:24:29) - (build date: Sat Dec 13 2014 20:02:51)
- Edit below for your projects' needs - Edit below for your projects' needs
------------------------------------------------------------------------*/ ------------------------------------------------------------------------*/

View file

@ -0,0 +1,108 @@
import {Dom} from '../dom';
import {Str} from '../string';
export class HighlightKeyword{
/**
* HighlightKeyword, highlight matched keyword
* @param {Object} tf TableFilter instance
*/
constructor(tf) {
var f = tf.fObj;
//defines css class for highlighting
this.highlightCssClass = f.highlight_css_class || 'keyword';
this.highlightedNodes = [];
this.tf = tf;
}
/**
* highlight occurences of searched term in passed node
* @param {Node} node
* @param {String} word Searched term
* @param {String} cssClass Css class name
*/
highlight(node, word, cssClass){
// Iterate into this nodes childNodes
if(node.hasChildNodes){
var children = node.childNodes;
for(var i=0; i<children.length; i++){
this.highlight(children[i], word, cssClass);
}
}
if(node.nodeType === 3){
var tempNodeVal = Str.lower(node.nodeValue);
var tempWordVal = Str.lower(word);
if(tempNodeVal.indexOf(tempWordVal) != -1){
var pn = node.parentNode;
if(pn && pn.className != cssClass){
// word not highlighted yet
var nv = node.nodeValue,
ni = tempNodeVal.indexOf(tempWordVal),
// Create a load of replacement nodes
before = Dom.text(nv.substr(0, ni)),
docWordVal = nv.substr(ni,word.length),
after = Dom.text(nv.substr(ni+word.length)),
hiwordtext = Dom.text(docWordVal),
hiword = Dom.create('span');
hiword.className = cssClass;
hiword.appendChild(hiwordtext);
pn.insertBefore(before,node);
pn.insertBefore(hiword,node);
pn.insertBefore(after,node);
pn.removeChild(node);
this.highlightedNodes.push(hiword.firstChild);
}
}
}
}
/**
* Removes highlight to nodes matching passed string
* @param {String} word
* @param {String} cssClass Css class to remove
*/
unhighlight(word, cssClass){
var arrRemove = [];
var highlightedNodes = this.highlightedNodes;
for(var i=0; i<highlightedNodes.length; i++){
var n = highlightedNodes[i];
if(!n){
continue;
}
var tempNodeVal = Str.lower(n.nodeValue),
tempWordVal = Str.lower(word);
if(tempNodeVal.indexOf(tempWordVal) !== -1){
var pn = n.parentNode;
if(pn && pn.className === cssClass){
var prevSib = pn.previousSibling,
nextSib = pn.nextSibling;
if(!prevSib || !nextSib){ continue; }
nextSib.nodeValue = prevSib.nodeValue + n.nodeValue +
nextSib.nodeValue;
prevSib.nodeValue = '';
n.nodeValue = '';
arrRemove.push(i);
}
}
}
for(var k=0; k<arrRemove.length; k++){
highlightedNodes.splice(arrRemove[k], 1);
}
}
/**
* Clear all occurrences of highlighted nodes
*/
unhighlightAll(){
if(!this.tf.highlightKeywords || !this.tf.searchArgs){
return;
}
for(var y=0; y<this.tf.searchArgs.length; y++){
this.unhighlight(
this.tf.searchArgs[y], this.highlightCssClass);
}
this.highlightedNodes = [];
}
}

View file

@ -486,9 +486,9 @@ function TableFilter(id) {
/*** keyword highlighting ***/ /*** keyword highlighting ***/
//enables/disables keyword highlighting //enables/disables keyword highlighting
this.highlightKeywords = f.highlight_keywords===true ? true : false; this.highlightKeywords = f.highlight_keywords===true ? true : false;
//defines css class for highlighting // //defines css class for highlighting
this.highlightCssClass = f.highlight_css_class || 'keyword'; // this.highlightCssClass = f.highlight_css_class || 'keyword';
this.highlightedNodes = []; // this.highlightedNodes = [];
/*** data types ***/ /*** data types ***/
//defines default date type (european DMY) //defines default date type (european DMY)
@ -648,9 +648,6 @@ function TableFilter(id) {
true : false; true : false;
//cookie storing page length //cookie storing page length
this.pgLenCookie = this.prfxCookiePageLen + this.id; this.pgLenCookie = this.prfxCookiePageLen + this.id;
//cookie duration
// this.cookieDuration = !isNaN(f.set_cookie_duration) ?
// parseInt(f.set_cookie_duration, 10) :100000;
/*** extensions ***/ /*** extensions ***/
//imports external script //imports external script
@ -673,8 +670,9 @@ function TableFilter(id) {
alternateRows: null, alternateRows: null,
colOps: null, colOps: null,
rowsCounter: null, rowsCounter: null,
GridLayout: null, gridLayout: null,
Store: null store: null,
highlightKeywords: null
}; };
/*** TF events ***/ /*** TF events ***/
@ -947,7 +945,7 @@ TableFilter.prototype = {
if(this.rememberGridValues || this.rememberPageNb || if(this.rememberGridValues || this.rememberPageNb ||
this.rememberPageLen){ this.rememberPageLen){
var Store = require('modules/store').Store; var Store = require('modules/store').Store;
this.Cpt.Store = new Store(this); this.Cpt.store = new Store(this);
} }
if(this.gridLayout){ if(this.gridLayout){
@ -961,6 +959,12 @@ TableFilter.prototype = {
this.Cpt.loader = new Loader(this); this.Cpt.loader = new Loader(this);
} }
if(this.highlightKeywords){
var Highlight =
require('modules/highlightKeywords').HighlightKeyword;
this.Cpt.highlightKeyword = new Highlight(this);
}
if(this.popUpFilters){ if(this.popUpFilters){
if(!this.isFirstLoad && !this.gridLayout){ if(!this.isFirstLoad && !this.gridLayout){
this.headersRow--; this.headersRow--;
@ -1171,7 +1175,7 @@ TableFilter.prototype = {
inp.onblur = this.Evt._OnInpBlur; inp.onblur = this.Evt._OnInpBlur;
if(this.rememberGridValues){ if(this.rememberGridValues){
var flts_values = this.Cpt.Store.getFilterValues( var flts_values = this.Cpt.store.getFilterValues(
this.fltsValuesCookie); this.fltsValuesCookie);
if(flts_values[i]!=' '){ if(flts_values[i]!=' '){
this.SetFilterValue(i,flts_values[i],false); this.SetFilterValue(i,flts_values[i],false);
@ -1539,7 +1543,8 @@ TableFilter.prototype = {
this.RemoveTopDiv(); this.RemoveTopDiv();
} }
if(this.highlightKeywords){ if(this.highlightKeywords){
this.UnhighlightAll(); // this.UnhighlightAll();
this.Cpt.highlightKeyword.unhighlightAll();
} }
if(this.sort){ if(this.sort){
this.RemoveSort(); this.RemoveSort();
@ -2823,7 +2828,7 @@ TableFilter.prototype = {
} }
if(this.rememberPageNb){ if(this.rememberPageNb){
this.Cpt.Store.savePageNb(this.pgNbCookie); this.Cpt.store.savePageNb(this.pgNbCookie);
} }
this.startPagingRow = (this.pageSelectorType===this.fltTypeSlc) ? this.startPagingRow = (this.pageSelectorType===this.fltTypeSlc) ?
this.pagingSlc.value : (index*this.pagingLength); this.pagingSlc.value : (index*this.pagingLength);
@ -2865,7 +2870,7 @@ TableFilter.prototype = {
this.pagingSlc.options[slcIndex].selected = true; this.pagingSlc.options[slcIndex].selected = true;
} }
if(this.rememberPageLen){ if(this.rememberPageLen){
this.Cpt.Store.savePageLength(this.pgLenCookie); this.Cpt.store.savePageLength(this.pgLenCookie);
} }
} }
}, },
@ -2879,7 +2884,7 @@ TableFilter.prototype = {
- name: cookie name (string) - name: cookie name (string)
===============================================*/ ===============================================*/
_ResetPage: function(name){ _ResetPage: function(name){
var pgnb = this.Cpt.Store.getPageNb(name); var pgnb = this.Cpt.store.getPageNb(name);
if(pgnb!==''){ if(pgnb!==''){
this.ChangePage((pgnb-1)); this.ChangePage((pgnb-1));
} }
@ -2897,7 +2902,7 @@ TableFilter.prototype = {
if(!this.paging){ if(!this.paging){
return; return;
} }
var pglenIndex = this.Cpt.Store.getPageLength(name); var pglenIndex = this.Cpt.store.getPageLength(name);
if(pglenIndex!==''){ if(pglenIndex!==''){
this.resultsPerPageSlc.options[pglenIndex].selected = true; this.resultsPerPageSlc.options[pglenIndex].selected = true;
@ -2966,7 +2971,7 @@ TableFilter.prototype = {
if(this.rememberGridValues){ if(this.rememberGridValues){
// flts_values = cookie.valueToArray( // flts_values = cookie.valueToArray(
// this.fltsValuesCookie, this.separator); // this.fltsValuesCookie, this.separator);
flts_values = this.Cpt.Store.getFilterValues(this.fltsValuesCookie); flts_values = this.Cpt.store.getFilterValues(this.fltsValuesCookie);
if(flts_values && !str.isEmpty(flts_values.toString())){ if(flts_values && !str.isEmpty(flts_values.toString())){
if(isCustomSlc){ if(isCustomSlc){
fltArr.push(flts_values[colIndex]); fltArr.push(flts_values[colIndex]);
@ -4059,7 +4064,7 @@ TableFilter.prototype = {
if(!this.fillSlcOnDemand){ if(!this.fillSlcOnDemand){
return; return;
} }
var flts_values = this.Cpt.Store.getFilterValues(name), var flts_values = this.Cpt.store.getFilterValues(name),
slcFltsIndex = this.GetFiltersByType(this.fltTypeSlc, true), slcFltsIndex = this.GetFiltersByType(this.fltTypeSlc, true),
multiFltsIndex = this.GetFiltersByType(this.fltTypeMulti, true); multiFltsIndex = this.GetFiltersByType(this.fltTypeMulti, true);
@ -4282,7 +4287,8 @@ TableFilter.prototype = {
// removes keyword highlighting // removes keyword highlighting
if(this.highlightKeywords){ if(this.highlightKeywords){
this.UnhighlightAll(); // this.UnhighlightAll();
this.Cpt.highlightKeyword.unhighlightAll();
} }
//removes popup filters active icons //removes popup filters active icons
if(this.popUpFilters){ if(this.popUpFilters){
@ -4324,7 +4330,8 @@ TableFilter.prototype = {
w = dom.getText(cell); w = dom.getText(cell);
} }
if(w!==''){ if(w!==''){
o.HighlightWord(cell,w,o.highlightCssClass); o.Cpt.highlightKeyword.highlight(
cell, w, o.Cpt.highlightKeyword.highlightCssClass);
} }
} }
} }
@ -4624,7 +4631,7 @@ TableFilter.prototype = {
if(this.rememberGridValues){ if(this.rememberGridValues){
// this.RememberFiltersValue(this.fltsValuesCookie); // this.RememberFiltersValue(this.fltsValuesCookie);
this.Cpt.Store.saveFilterValues(this.fltsValuesCookie); this.Cpt.store.saveFilterValues(this.fltsValuesCookie);
} }
//applies filter props after filtering process //applies filter props after filtering process
if(!this.paging){ if(!this.paging){
@ -5242,98 +5249,6 @@ TableFilter.prototype = {
} }
}, },
/*====================================================
- removes keyword highlighting
=====================================================*/
UnhighlightAll: function(){
if( this.highlightKeywords && this.searchArgs){
for(var y=0; y<this.searchArgs.length; y++){
this.UnhighlightWord(
this.searchArgs[y], this.highlightCssClass);
}
this.highlightedNodes = [];
}
},
/*====================================================
- highlights keyword found in passed node
- accepts the following params:
- node
- word to search
- css class name for highlighting
=====================================================*/
HighlightWord: function(node, word, cssClass){
// Iterate into this nodes childNodes
if(node.hasChildNodes){
for(var i=0; i<node.childNodes.length; i++){
this.HighlightWord(node.childNodes[i], word, cssClass);
}
}
// And do this node itself
// text node
if(node.nodeType === 3){
var tempNodeVal = str.lower(node.nodeValue);
var tempWordVal = str.lower(word);
if(tempNodeVal.indexOf(tempWordVal) != -1){
var pn = node.parentNode;
if(pn && pn.className != cssClass){
// word has not already been highlighted!
var nv = node.nodeValue,
ni = tempNodeVal.indexOf(tempWordVal),
// Create a load of replacement nodes
before = dom.text(nv.substr(0,ni)),
docWordVal = nv.substr(ni,word.length),
after = dom.text(nv.substr(ni+word.length)),
hiwordtext = dom.text(docWordVal),
hiword = dom.create('span');
hiword.className = cssClass;
hiword.appendChild(hiwordtext);
pn.insertBefore(before,node);
pn.insertBefore(hiword,node);
pn.insertBefore(after,node);
pn.removeChild(node);
this.highlightedNodes.push(hiword.firstChild);
}
}
}
},
/*====================================================
- removes highlights found in passed node
- accepts the following params:
- node
- word to search
- css class name for highlighting
=====================================================*/
UnhighlightWord: function(word, cssClass){
var arrRemove = [];
for(var i=0; i<this.highlightedNodes.length; i++){
var n = this.highlightedNodes[i];
if(!n){
continue;
}
var tempNodeVal = str.lower(n.nodeValue),
tempWordVal = str.lower(word);
if(tempNodeVal.indexOf(tempWordVal) !== -1){
var pn = n.parentNode;
if(pn && pn.className === cssClass){
var prevSib = pn.previousSibling,
nextSib = pn.nextSibling;
if(!prevSib || !nextSib){ continue; }
nextSib.nodeValue = prevSib.nodeValue + n.nodeValue +
nextSib.nodeValue;
prevSib.nodeValue = '';
n.nodeValue = '';
arrRemove.push(i);
}
}
}
for(var k=0; k<arrRemove.length; k++){
this.highlightedNodes.splice(arrRemove[k], 1);
}
},
/*==================================================== /*====================================================
- Private methods - Private methods
=====================================================*/ =====================================================*/

View file

@ -1,4 +0,0 @@
return require('core');
});

View file

@ -77,12 +77,12 @@
loader: false, loader: false,
rows_counter: true, rows_counter: true,
enable_default_theme: true, enable_default_theme: true,
paging: true, // paging: true,
paging_length: 2, // paging_length: 2,
results_per_page: ['Results per page', [2,4,6]], // results_per_page: ['Results per page', [2,4,6]],
remember_grid_values: true, // remember_grid_values: true,
remember_page_number: true, // remember_page_number: true,
remember_page_length: true, // remember_page_length: true,
alternate_rows: true, alternate_rows: true,
highlight_keywords: true, highlight_keywords: true,
match_case: false, match_case: false,

View file

@ -1,10 +0,0 @@
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(factory);
} else if (typeof exports === 'object') {
module.exports = factory;
} else {
root.TableFilter = factory();
}
})(this, function() {

View file

@ -9,22 +9,23 @@ requirejs(['test-config', '../src/core'], function(config, TableFilter){
}); });
tf.init(); tf.init();
var gridLayout = tf.Cpt.gridLayout;
module('Sanity checks'); module('Sanity checks');
test('GridLayout component', function() { test('GridLayout component', function() {
deepEqual(tf.Cpt.gridLayout instanceof GridLayout, true, 'GridLayout type'); deepEqual(gridLayout instanceof GridLayout, true, 'GridLayout type');
notEqual(tf.Cpt.gridLayout, null, 'GridLayout instanciated'); notEqual(gridLayout, null, 'GridLayout instanciated');
notEqual(tf.Cpt.gridLayout.tblMainCont, null, 'GridLayout main container element'); notEqual(gridLayout.tblMainCont, null, 'GridLayout main container element');
notEqual(tf.Cpt.gridLayout.tblCont, null, 'GridLayout main HTML table container element'); notEqual(gridLayout.tblCont, null, 'GridLayout main HTML table container element');
notEqual(tf.Cpt.gridLayout.headTblCont, null, 'GridLayout headers container element'); notEqual(gridLayout.headTblCont, null, 'GridLayout headers container element');
notEqual(tf.Cpt.gridLayout.headTbl, null, 'GridLayout headers HTML table'); notEqual(gridLayout.headTbl, null, 'GridLayout headers HTML table');
}); });
test('Destroy GridLayout component', function() { test('Destroy GridLayout component', function() {
tf.Cpt.gridLayout.destroy(); gridLayout.destroy();
deepEqual(tf.Cpt.gridLayout.tblMainCont, null, 'Main container element removed'); deepEqual(gridLayout.tblMainCont, null, 'Main container element removed');
deepEqual(tf.Cpt.gridLayout.tblCont, null, 'Main HTML table container element removed'); deepEqual(gridLayout.tblCont, null, 'Main HTML table container element removed');
deepEqual(tf.Cpt.gridLayout.headTblCont, null, 'Headers container element removed'); deepEqual(gridLayout.headTblCont, null, 'Headers container element removed');
deepEqual(tf.Cpt.gridLayout.headTbl, null, 'Headers HTML table element removed'); deepEqual(gridLayout.headTbl, null, 'Headers HTML table element removed');
}); });
}); });

View file

@ -23,9 +23,9 @@ requirejs(['test-config', '../src/core'], function(config, TableFilter){
module('Sanity checks'); module('Sanity checks');
test('Store module', function() { test('Store module', function() {
deepEqual(tf.Cpt.Store instanceof Store, true, 'Store type'); deepEqual(tf.Cpt.store instanceof Store, true, 'Store type');
notEqual(tf.Cpt.Store, null, 'Store instanciated'); notEqual(tf.Cpt.store, null, 'Store instanciated');
deepEqual(tf.Cpt.Store.duration, 100000, 'Store duration'); deepEqual(tf.Cpt.store.duration, 100000, 'Store duration');
}); });
module('Check page number persistence'); module('Check page number persistence');
@ -34,7 +34,7 @@ requirejs(['test-config', '../src/core'], function(config, TableFilter){
tf._Filter(); tf._Filter();
tf._ChangePage(1); tf._ChangePage(1);
var cookieName = tf.pgNbCookie; var cookieName = tf.pgNbCookie;
deepEqual(tf.Cpt.Store.getPageNb(cookieName), '2', 'Page number value'); deepEqual(tf.Cpt.store.getPageNb(cookieName), '2', 'Page number value');
tf._ClearFilters(); tf._ClearFilters();
tf._Filter(); tf._Filter();
}); });
@ -44,7 +44,7 @@ requirejs(['test-config', '../src/core'], function(config, TableFilter){
tf.resultsPerPageSlc.options[2].selected = true; tf.resultsPerPageSlc.options[2].selected = true;
tf._ChangeResultsPerPage(); tf._ChangeResultsPerPage();
var cookieName = tf.pgLenCookie; var cookieName = tf.pgLenCookie;
deepEqual(tf.Cpt.Store.getPageLength(cookieName), '2', 'Page length value'); deepEqual(tf.Cpt.store.getPageLength(cookieName), '2', 'Page length value');
tf._ClearFilters(); tf._ClearFilters();
tf._Filter(); tf._Filter();
}); });
@ -55,8 +55,8 @@ requirejs(['test-config', '../src/core'], function(config, TableFilter){
tf.SetFilterValue(3, '1.5'); tf.SetFilterValue(3, '1.5');
tf._Filter(); tf._Filter();
var cookieName = tf.fltsValuesCookie; var cookieName = tf.fltsValuesCookie;
deepEqual(tf.Cpt.Store.getFilterValues(cookieName)[0], 'Sydney', 'Filter 0 value'); deepEqual(tf.Cpt.store.getFilterValues(cookieName)[0], 'Sydney', 'Filter 0 value');
deepEqual(tf.Cpt.Store.getFilterValues(cookieName)[3], '1.5', 'Filter 3 value'); deepEqual(tf.Cpt.store.getFilterValues(cookieName)[3], '1.5', 'Filter 3 value');
tf._ClearFilters(); tf._ClearFilters();
tf._Filter(); tf._Filter();
}); });