- |
- public
-
-
-
|
@@ -4732,7 +4706,7 @@ requires table or id arguments, row and <
- source
+ source
@@ -4774,7 +4748,7 @@ stops typing
- source
+ source
@@ -4926,47 +4900,6 @@ stops typing
-
-
-
- public
-
-
-
-
- btnResetCssClass: String
-
-
-
- source
-
-
-
-
-
-
- Css class for reset button
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -5061,7 +4994,7 @@ stops typing
- source
+ source
@@ -5104,7 +5037,7 @@ col_date_type : [null, 'DMY', 'MDY', 'YMD', null,
- source
+ source
@@ -5323,7 +5256,7 @@ custom_options: {
- source
+ source
@@ -5364,7 +5297,7 @@ custom_options: {
- source
+ source
@@ -5734,7 +5667,7 @@ linked filters filtering mode is on
- source
+ source
@@ -6637,7 +6570,7 @@ types
- source
+ source
@@ -6719,7 +6652,7 @@ types
- source
+ source
@@ -7211,7 +7144,7 @@ first usage
- source
+ source
@@ -7375,7 +7308,7 @@ first usage
- source
+ source
@@ -7498,7 +7431,7 @@ first usage
- source
+ source
@@ -7704,7 +7637,7 @@ on change event
- source
+ source
@@ -7869,7 +7802,7 @@ are generated
- source
+ source
@@ -8282,7 +8215,7 @@ alpha-numeric manner by default
- source
+ source
@@ -8487,7 +8420,7 @@ alpha-numeric manner by default
- source
+ source
@@ -8529,7 +8462,7 @@ themes: [{ name: 'skyblue' }]
- source
+ source
@@ -8572,7 +8505,7 @@ themes: [{ name: 'skyblue' }]
- source
+ source
@@ -8781,7 +8714,7 @@ filter if an array is supplied
- source
+ source
@@ -8839,7 +8772,7 @@ filter if an array is supplied
- source
+ source
@@ -8880,7 +8813,7 @@ filter if an array is supplied
- source
+ source
@@ -8921,7 +8854,7 @@ filter if an array is supplied
- source
+ source
@@ -8972,7 +8905,7 @@ filter if an array is supplied
- source
+ source
@@ -9013,7 +8946,7 @@ filter if an array is supplied
- source
+ source
@@ -9054,7 +8987,7 @@ filter if an array is supplied
- source
+ source
@@ -9111,7 +9044,7 @@ filter if an array is supplied
- source
+ source
@@ -9152,7 +9085,7 @@ filter if an array is supplied
- source
+ source
@@ -9221,7 +9154,7 @@ filter if an array is supplied
- source
+ source
@@ -9289,7 +9222,7 @@ filter if an array is supplied
- source
+ source
@@ -9332,7 +9265,7 @@ hidden when all the search terms are not found in inspected row.
- source
+ source
@@ -9383,7 +9316,7 @@ hidden when all the search terms are not found in inspected row.
- source
+ source
@@ -9451,7 +9384,7 @@ hidden when all the search terms are not found in inspected row.
- source
+ source
@@ -9520,7 +9453,7 @@ hidden when all the search terms are not found in inspected row.
- source
+ source
@@ -9610,7 +9543,7 @@ hidden when all the search terms are not found in inspected row.
- source
+ source
@@ -9680,7 +9613,7 @@ hidden when all the search terms are not found in inspected row.
- source
+ source
@@ -9749,7 +9682,7 @@ custom options values and texts
- source
+ source
@@ -9817,7 +9750,7 @@ custom options values and texts
- source
+ source
@@ -9886,7 +9819,7 @@ custom options values and texts
- source
+ source
@@ -9954,7 +9887,7 @@ custom options values and texts
- source
+ source
@@ -10023,7 +9956,7 @@ custom options values and texts
- source
+ source
@@ -10074,7 +10007,7 @@ custom options values and texts
- source
+ source
@@ -10154,7 +10087,7 @@ custom options values and texts
- source
+ source
@@ -10231,7 +10164,7 @@ custom options values and texts
- source
+ source
@@ -10309,7 +10242,7 @@ Note: hidden filters are also returned
- source
+ source
@@ -10361,7 +10294,7 @@ Note: hidden filters are also returned
- source
+ source
@@ -10412,7 +10345,7 @@ Note: hidden filters are also returned
- source
+ source
@@ -10464,7 +10397,7 @@ Note: hidden filters are also returned
- source
+ source
@@ -10532,7 +10465,7 @@ Note: hidden filters are also returned
- source
+ source
@@ -10583,7 +10516,7 @@ Note: hidden filters are also returned
- source
+ source
@@ -10652,7 +10585,7 @@ Note: hidden filters are also returned
- source
+ source
@@ -10703,7 +10636,7 @@ Note: hidden filters are also returned
- source
+ source
@@ -10772,7 +10705,7 @@ Note: hidden filters are also returned
- source
+ source
@@ -10842,7 +10775,7 @@ defined
- source
+ source
@@ -10894,7 +10827,7 @@ row)
- source
+ source
@@ -10963,7 +10896,7 @@ row)
- source
+ source
@@ -11043,7 +10976,7 @@ row)
- source
+ source
@@ -11112,7 +11045,7 @@ row)
- source
+ source
@@ -11181,7 +11114,7 @@ row)
- source
+ source
@@ -11249,7 +11182,7 @@ row)
- source
+ source
@@ -11328,7 +11261,7 @@ row)
- source
+ source
@@ -11369,7 +11302,7 @@ row)
- source
+ source
@@ -11410,7 +11343,7 @@ row)
- source
+ source
@@ -11478,7 +11411,7 @@ row)
- source
+ source
@@ -11547,7 +11480,7 @@ row)
- source
+ source
@@ -11622,7 +11555,7 @@ row)
- source
+ source
@@ -11673,7 +11606,7 @@ row)
- source
+ source
@@ -11715,7 +11648,7 @@ row)
- source
+ source
@@ -11773,7 +11706,7 @@ row)
- source
+ source
@@ -11814,7 +11747,7 @@ row)
- source
+ source
@@ -11872,7 +11805,7 @@ row)
- source
+ source
@@ -11913,7 +11846,7 @@ row)
- source
+ source
@@ -11970,7 +11903,7 @@ row)
- source
+ source
@@ -12011,7 +11944,7 @@ row)
- source
+ source
@@ -12069,7 +12002,7 @@ columns
- source
+ source
@@ -12110,7 +12043,7 @@ columns
- source
+ source
@@ -12151,7 +12084,7 @@ columns
- source
+ source
@@ -12209,7 +12142,7 @@ columns
- source
+ source
@@ -12267,7 +12200,7 @@ columns
- source
+ source
@@ -12332,7 +12265,7 @@ columns
- source
+ source
@@ -12373,7 +12306,7 @@ columns
- source
+ source
@@ -12414,7 +12347,7 @@ columns
- source
+ source
diff --git a/docs/coverage.json b/docs/coverage.json
index 21fbfdbc..cc1bb336 100644
--- a/docs/coverage.json
+++ b/docs/coverage.json
@@ -1,7 +1,7 @@
{
- "coverage": "82.05%",
+ "coverage": "83.12%",
"expectCount": 652,
- "actualCount": 535,
+ "actualCount": 542,
"files": {
"src/const.js": {
"expectCount": 13,
@@ -63,22 +63,14 @@
"undocumentLines": []
},
"src/modules/clearButton.js": {
- "expectCount": 9,
- "actualCount": 9,
+ "expectCount": 10,
+ "actualCount": 10,
"undocumentLines": []
},
"src/extensions/colOps/colOps.js": {
"expectCount": 9,
- "actualCount": 2,
- "undocumentLines": [
- 5,
- 320,
- 25,
- 33,
- 18,
- 15,
- 21
- ]
+ "actualCount": 9,
+ "undocumentLines": []
},
"src/extensions/colsVisibility/colsVisibility.js": {
"expectCount": 57,
@@ -247,8 +239,8 @@
"undocumentLines": []
},
"src/tablefilter.js": {
- "expectCount": 166,
- "actualCount": 166,
+ "expectCount": 165,
+ "actualCount": 165,
"undocumentLines": []
},
"src/dom.js": {
diff --git a/docs/dump.json b/docs/dump.json
index b1027f45..a784e1b8 100644
--- a/docs/dump.json
+++ b/docs/dump.json
@@ -2077,7 +2077,7 @@
"access": null,
"description": null,
"lineNumber": 1,
- "content": "import {Feature} from '../../feature';\nimport {createText, elm} from '../../dom';\nimport {isArray, isFn, isUndef} from '../../types';\n\nexport default class ColOps extends Feature {\n\n /**\n * Column calculations\n * @param {Object} tf TableFilter instance\n */\n constructor(tf, opts) {\n super(tf, opts.name);\n\n //calls function before col operation\n this.onBeforeOperation = isFn(opts.on_before_operation) ?\n opts.on_before_operation : null;\n //calls function after col operation\n this.onAfterOperation = isFn(opts.on_after_operation) ?\n opts.on_after_operation : null;\n\n this.opts = opts;\n this.enable();\n }\n\n init() {\n if (this.initialized) {\n return;\n }\n // subscribe to events\n this.tf.emitter.on(['after-filtering'], () => this.calc());\n\n this.calc();\n this.initialized = true;\n }\n\n /**\n * Calculates columns' values\n * Configuration options are stored in 'opts' property\n * - 'id' contains ids of elements showing result (array)\n * - 'col' contains the columns' indexes (array)\n * - 'operation' contains operation type (array, values: 'sum', 'mean',\n * 'min', 'max', 'median', 'q1', 'q3')\n * - 'write_method' array defines which method to use for displaying the\n * result (innerHTML, setValue, createTextNode) - default: 'innerHTML'\n * - 'tot_row_index' defines in which row results are displayed\n * (integers array)\n *\n * - changes made by Nuovella:\n * (1) optimized the routine (now it will only process each column once),\n * (2) added calculations for the median, lower and upper quartile.\n */\n calc() {\n var tf = this.tf;\n if (!tf.isInitialized()) {\n return;\n }\n\n if (this.onBeforeOperation) {\n this.onBeforeOperation.call(null, tf);\n }\n\n var opts = this.opts,\n labelId = opts.id,\n colIndex = opts.col,\n operation = opts.operation,\n outputType = opts.write_method,\n totRowIndex = opts.tot_row_index,\n excludeRow = opts.exclude_row,\n decimalPrecision = isUndef(opts.decimal_precision) ?\n 2 : opts.decimal_precision;\n\n //nuovella: determine unique list of columns to operate on\n var ucolIndex = [],\n ucolMax = 0;\n ucolIndex[ucolMax] = colIndex[0];\n\n for (var ii = 1; ii < colIndex.length; ii++) {\n var saved = 0;\n //see if colIndex[ii] is already in the list of unique indexes\n for (var jj = 0; jj <= ucolMax; jj++) {\n if (ucolIndex[jj] === colIndex[ii]) {\n saved = 1;\n }\n }\n //if not saved then, save the index;\n if (saved === 0) {\n ucolMax++;\n ucolIndex[ucolMax] = colIndex[ii];\n }\n }\n\n if (isArray(labelId) && isArray(colIndex) && isArray(operation)) {\n var rows = tf.tbl.rows,\n colvalues = [];\n\n for (var ucol = 0; ucol <= ucolMax; ucol++) {\n //this retrieves col values\n //use ucolIndex because we only want to pass through this loop\n //once for each column get the values in this unique column\n colvalues.push(\n tf.getColValues(ucolIndex[ucol], false, true, excludeRow));\n\n //next: calculate all operations for this column\n var result,\n nbvalues = 0,\n temp,\n meanValue = 0,\n sumValue = 0,\n minValue = null,\n maxValue = null,\n q1Value = null,\n medValue = null,\n q3Value = null,\n meanFlag = 0,\n sumFlag = 0,\n minFlag = 0,\n maxFlag = 0,\n q1Flag = 0,\n medFlag = 0,\n q3Flag = 0,\n theList = [],\n opsThisCol = [],\n decThisCol = [],\n labThisCol = [],\n oTypeThisCol = [],\n mThisCol = -1;\n\n for (var k = 0; k < colIndex.length; k++) {\n if (colIndex[k] === ucolIndex[ucol]) {\n mThisCol++;\n opsThisCol[mThisCol] = operation[k].toLowerCase();\n decThisCol[mThisCol] = decimalPrecision[k];\n labThisCol[mThisCol] = labelId[k];\n oTypeThisCol = isArray(outputType) ?\n outputType[k] : null;\n\n switch (opsThisCol[mThisCol]) {\n case 'mean':\n meanFlag = 1;\n break;\n case 'sum':\n sumFlag = 1;\n break;\n case 'min':\n minFlag = 1;\n break;\n case 'max':\n maxFlag = 1;\n break;\n case 'median':\n medFlag = 1;\n break;\n case 'q1':\n q1Flag = 1;\n break;\n case 'q3':\n q3Flag = 1;\n break;\n }\n }\n }\n\n for (var j = 0; j < colvalues[ucol].length; j++) {\n //sort the list for calculation of median and quartiles\n if ((q1Flag === 1) || (q3Flag === 1) || (medFlag === 1)) {\n if (j < colvalues[ucol].length - 1) {\n for (k = j + 1; k < colvalues[ucol].length; k++) {\n /* eslint-disable */\n if (eval(colvalues[ucol][k]) <\n eval(colvalues[ucol][j])) {\n /* eslint-enable */\n temp = colvalues[ucol][j];\n colvalues[ucol][j] = colvalues[ucol][k];\n colvalues[ucol][k] = temp;\n }\n }\n }\n }\n var cvalue = parseFloat(colvalues[ucol][j]);\n theList[j] = parseFloat(cvalue);\n\n if (!isNaN(cvalue)) {\n nbvalues++;\n if (sumFlag === 1 || meanFlag === 1) {\n sumValue += parseFloat(cvalue);\n }\n if (minFlag === 1) {\n if (minValue === null) {\n minValue = parseFloat(cvalue);\n } else {\n minValue = parseFloat(cvalue) < minValue ?\n parseFloat(cvalue) : minValue;\n }\n }\n if (maxFlag === 1) {\n if (maxValue === null) {\n maxValue = parseFloat(cvalue);\n } else {\n maxValue = parseFloat(cvalue) > maxValue ?\n parseFloat(cvalue) : maxValue;\n }\n }\n }\n }//for j\n if (meanFlag === 1) {\n meanValue = sumValue / nbvalues;\n }\n if (medFlag === 1) {\n var aux = 0;\n if (nbvalues % 2 === 1) {\n aux = Math.floor(nbvalues / 2);\n medValue = theList[aux];\n } else {\n medValue = (theList[nbvalues / 2] +\n theList[((nbvalues / 2) - 1)]) / 2;\n }\n }\n var posa;\n if (q1Flag === 1) {\n posa = 0.0;\n posa = Math.floor(nbvalues / 4);\n if (4 * posa === nbvalues) {\n q1Value = (theList[posa - 1] + theList[posa]) / 2;\n } else {\n q1Value = theList[posa];\n }\n }\n if (q3Flag === 1) {\n posa = 0.0;\n var posb = 0.0;\n posa = Math.floor(nbvalues / 4);\n if (4 * posa === nbvalues) {\n posb = 3 * posa;\n q3Value = (theList[posb] + theList[posb - 1]) / 2;\n } else {\n q3Value = theList[nbvalues - posa - 1];\n }\n }\n\n for (var i = 0; i <= mThisCol; i++) {\n switch (opsThisCol[i]) {\n case 'mean':\n result = meanValue;\n break;\n case 'sum':\n result = sumValue;\n break;\n case 'min':\n result = minValue;\n break;\n case 'max':\n result = maxValue;\n break;\n case 'median':\n result = medValue;\n break;\n case 'q1':\n result = q1Value;\n break;\n case 'q3':\n result = q3Value;\n break;\n }\n\n var precision = !isNaN(decThisCol[i]) ? decThisCol[i] : 2;\n\n //if outputType is defined\n if (oTypeThisCol && result) {\n result = result.toFixed(precision);\n\n if (elm(labThisCol[i])) {\n switch (oTypeThisCol.toLowerCase()) {\n case 'innerhtml':\n if (isNaN(result) || !isFinite(result) ||\n nbvalues === 0) {\n elm(labThisCol[i]).innerHTML = '.';\n } else {\n elm(labThisCol[i]).innerHTML = result;\n }\n break;\n case 'setvalue':\n elm(labThisCol[i]).value = result;\n break;\n case 'createtextnode':\n var oldnode =\n elm(labThisCol[i]).firstChild;\n var txtnode = createText(result);\n elm(labThisCol[i])\n .replaceChild(txtnode, oldnode);\n break;\n }//switch\n }\n } else {\n try {\n if (isNaN(result) || !isFinite(result) ||\n nbvalues === 0) {\n elm(labThisCol[i]).innerHTML = '.';\n } else {\n elm(labThisCol[i]).innerHTML =\n result.toFixed(precision);\n }\n } catch (e) { }//catch\n }//else\n }//for i\n\n // row(s) with result are always visible\n var totRow = totRowIndex && totRowIndex[ucol] ?\n rows[totRowIndex[ucol]] : null;\n if (totRow) {\n totRow.style.display = '';\n }\n }//for ucol\n }//if typeof\n\n if (this.onAfterOperation) {\n this.onAfterOperation.call(null, tf);\n }\n }\n\n destroy() {\n if (!this.initialized) {\n return;\n }\n // unsubscribe to events\n this.tf.emitter.off(['after-filtering'], () => this.calc());\n this.initialized = false;\n }\n\n}\n"
+ "content": "import {Feature} from '../../feature';\nimport {createText, elm} from '../../dom';\nimport {isArray, isFn, isUndef} from '../../types';\n\n/**\n * Column calculations extension\n */\nexport default class ColOps extends Feature {\n\n /**\n * Creates an instance of ColOps\n *\n * @param {TableFilter} tf TableFilter instance\n * @param {Object} opts Configuration object\n */\n constructor(tf, opts) {\n super(tf, opts.name);\n\n /**\n * Callback fired before columns operations start\n * @type {Function}\n */\n this.onBeforeOperation = isFn(opts.on_before_operation) ?\n opts.on_before_operation : null;\n\n /**\n * Callback fired after columns operations are completed\n * @type {Function}\n */\n this.onAfterOperation = isFn(opts.on_after_operation) ?\n opts.on_after_operation : null;\n\n /**\n * Configuration options\n * @type {Object}\n */\n this.opts = opts;\n\n this.enable();\n }\n\n /**\n * Initializes ColOps instance\n */\n init() {\n if (this.initialized) {\n return;\n }\n // subscribe to events\n this.emitter.on(['after-filtering'], () => this.calc());\n\n this.calc();\n\n /**\n * @inherited\n */\n this.initialized = true;\n }\n\n /**\n * Calculates columns' values\n * Configuration options are stored in 'opts' property\n * - 'id' contains ids of elements showing result (array)\n * - 'col' contains the columns' indexes (array)\n * - 'operation' contains operation type (array, values: 'sum', 'mean',\n * 'min', 'max', 'median', 'q1', 'q3')\n * - 'write_method' array defines which method to use for displaying the\n * result (innerHTML, setValue, createTextNode) - default: 'innerHTML'\n * - 'tot_row_index' defines in which row results are displayed\n * (integers array)\n *\n * - changes made by Nuovella:\n * (1) optimized the routine (now it will only process each column once),\n * (2) added calculations for the median, lower and upper quartile.\n */\n calc() {\n let tf = this.tf;\n if (!tf.isInitialized()) {\n return;\n }\n\n if (this.onBeforeOperation) {\n this.onBeforeOperation.call(null, tf, this);\n }\n this.emitter.emit('before-column-operation', tf, this);\n\n let opts = this.opts,\n labelId = opts.id,\n colIndex = opts.col,\n operation = opts.operation,\n outputType = opts.write_method,\n totRowIndex = opts.tot_row_index,\n excludeRow = opts.exclude_row,\n decimalPrecision = isUndef(opts.decimal_precision) ?\n 2 : opts.decimal_precision;\n\n //nuovella: determine unique list of columns to operate on\n let ucolIndex = [],\n ucolMax = 0;\n ucolIndex[ucolMax] = colIndex[0];\n\n for (let ii = 1; ii < colIndex.length; ii++) {\n let saved = 0;\n //see if colIndex[ii] is already in the list of unique indexes\n for (let jj = 0; jj <= ucolMax; jj++) {\n if (ucolIndex[jj] === colIndex[ii]) {\n saved = 1;\n }\n }\n //if not saved then, save the index;\n if (saved === 0) {\n ucolMax++;\n ucolIndex[ucolMax] = colIndex[ii];\n }\n }\n\n if (isArray(labelId) && isArray(colIndex) && isArray(operation)) {\n let rows = tf.tbl.rows,\n colvalues = [];\n\n for (let ucol = 0; ucol <= ucolMax; ucol++) {\n //this retrieves col values\n //use ucolIndex because we only want to pass through this loop\n //once for each column get the values in this unique column\n colvalues.push(\n tf.getColValues(ucolIndex[ucol], false, true, excludeRow));\n\n //next: calculate all operations for this column\n let result,\n nbvalues = 0,\n temp,\n meanValue = 0,\n sumValue = 0,\n minValue = null,\n maxValue = null,\n q1Value = null,\n medValue = null,\n q3Value = null,\n meanFlag = 0,\n sumFlag = 0,\n minFlag = 0,\n maxFlag = 0,\n q1Flag = 0,\n medFlag = 0,\n q3Flag = 0,\n theList = [],\n opsThisCol = [],\n decThisCol = [],\n labThisCol = [],\n oTypeThisCol = [],\n mThisCol = -1;\n\n for (let k = 0; k < colIndex.length; k++) {\n if (colIndex[k] === ucolIndex[ucol]) {\n mThisCol++;\n opsThisCol[mThisCol] = operation[k].toLowerCase();\n decThisCol[mThisCol] = decimalPrecision[k];\n labThisCol[mThisCol] = labelId[k];\n oTypeThisCol = isArray(outputType) ?\n outputType[k] : null;\n\n switch (opsThisCol[mThisCol]) {\n case 'mean':\n meanFlag = 1;\n break;\n case 'sum':\n sumFlag = 1;\n break;\n case 'min':\n minFlag = 1;\n break;\n case 'max':\n maxFlag = 1;\n break;\n case 'median':\n medFlag = 1;\n break;\n case 'q1':\n q1Flag = 1;\n break;\n case 'q3':\n q3Flag = 1;\n break;\n }\n }\n }\n\n for (let j = 0; j < colvalues[ucol].length; j++) {\n //sort the list for calculation of median and quartiles\n if ((q1Flag === 1) || (q3Flag === 1) || (medFlag === 1)) {\n if (j < colvalues[ucol].length - 1) {\n for (k = j + 1; k < colvalues[ucol].length; k++) {\n /* eslint-disable */\n if (eval(colvalues[ucol][k]) <\n eval(colvalues[ucol][j])) {\n /* eslint-enable */\n temp = colvalues[ucol][j];\n colvalues[ucol][j] = colvalues[ucol][k];\n colvalues[ucol][k] = temp;\n }\n }\n }\n }\n let cvalue = parseFloat(colvalues[ucol][j]);\n theList[j] = parseFloat(cvalue);\n\n if (!isNaN(cvalue)) {\n nbvalues++;\n if (sumFlag === 1 || meanFlag === 1) {\n sumValue += parseFloat(cvalue);\n }\n if (minFlag === 1) {\n if (minValue === null) {\n minValue = parseFloat(cvalue);\n } else {\n minValue = parseFloat(cvalue) < minValue ?\n parseFloat(cvalue) : minValue;\n }\n }\n if (maxFlag === 1) {\n if (maxValue === null) {\n maxValue = parseFloat(cvalue);\n } else {\n maxValue = parseFloat(cvalue) > maxValue ?\n parseFloat(cvalue) : maxValue;\n }\n }\n }\n }//for j\n if (meanFlag === 1) {\n meanValue = sumValue / nbvalues;\n }\n if (medFlag === 1) {\n let aux = 0;\n if (nbvalues % 2 === 1) {\n aux = Math.floor(nbvalues / 2);\n medValue = theList[aux];\n } else {\n medValue = (theList[nbvalues / 2] +\n theList[((nbvalues / 2) - 1)]) / 2;\n }\n }\n let posa;\n if (q1Flag === 1) {\n posa = 0.0;\n posa = Math.floor(nbvalues / 4);\n if (4 * posa === nbvalues) {\n q1Value = (theList[posa - 1] + theList[posa]) / 2;\n } else {\n q1Value = theList[posa];\n }\n }\n if (q3Flag === 1) {\n posa = 0.0;\n let posb = 0.0;\n posa = Math.floor(nbvalues / 4);\n if (4 * posa === nbvalues) {\n posb = 3 * posa;\n q3Value = (theList[posb] + theList[posb - 1]) / 2;\n } else {\n q3Value = theList[nbvalues - posa - 1];\n }\n }\n\n for (let i = 0; i <= mThisCol; i++) {\n switch (opsThisCol[i]) {\n case 'mean':\n result = meanValue;\n break;\n case 'sum':\n result = sumValue;\n break;\n case 'min':\n result = minValue;\n break;\n case 'max':\n result = maxValue;\n break;\n case 'median':\n result = medValue;\n break;\n case 'q1':\n result = q1Value;\n break;\n case 'q3':\n result = q3Value;\n break;\n }\n\n let precision = !isNaN(decThisCol[i]) ? decThisCol[i] : 2;\n\n //if outputType is defined\n if (oTypeThisCol && result) {\n result = result.toFixed(precision);\n\n if (elm(labThisCol[i])) {\n switch (oTypeThisCol.toLowerCase()) {\n case 'innerhtml':\n if (isNaN(result) || !isFinite(result) ||\n nbvalues === 0) {\n elm(labThisCol[i]).innerHTML = '.';\n } else {\n elm(labThisCol[i]).innerHTML = result;\n }\n break;\n case 'setvalue':\n elm(labThisCol[i]).value = result;\n break;\n case 'createtextnode':\n let oldnode =\n elm(labThisCol[i]).firstChild;\n let txtnode = createText(result);\n elm(labThisCol[i])\n .replaceChild(txtnode, oldnode);\n break;\n }//switch\n }\n } else {\n try {\n if (isNaN(result) || !isFinite(result) ||\n nbvalues === 0) {\n elm(labThisCol[i]).innerHTML = '.';\n } else {\n elm(labThisCol[i]).innerHTML =\n result.toFixed(precision);\n }\n } catch (e) { }//catch\n }//else\n }//for i\n\n // row(s) with result are always visible\n let totRow = totRowIndex && totRowIndex[ucol] ?\n rows[totRowIndex[ucol]] : null;\n if (totRow) {\n totRow.style.display = '';\n }\n }//for ucol\n }//if typeof\n\n if (this.onAfterOperation) {\n this.onAfterOperation.call(null, tf, this);\n }\n this.emitter.emit('after-column-operation', tf, this);\n }\n\n /**\n * Remove extension\n */\n destroy() {\n if (!this.initialized) {\n return;\n }\n // unsubscribe to events\n this.emitter.off(['after-filtering'], () => this.calc());\n this.initialized = false;\n }\n\n}\n"
},
{
"__docId__": 77,
@@ -2091,9 +2091,8 @@
"export": true,
"importPath": "tablefilter/src/extensions/colOps/colOps.js",
"importStyle": "ColOps",
- "description": null,
- "lineNumber": 5,
- "undocument": true,
+ "description": "Column calculations extension",
+ "lineNumber": 8,
"interface": false,
"extends": [
"src/feature.js~Feature"
@@ -2108,9 +2107,19 @@
"memberof": "src/extensions/colOps/colOps.js~ColOps",
"longname": "src/extensions/colOps/colOps.js~ColOps#constructor",
"access": null,
- "description": "Column calculations",
- "lineNumber": 11,
+ "description": "Creates an instance of ColOps",
+ "lineNumber": 16,
"params": [
+ {
+ "nullable": null,
+ "types": [
+ "TableFilter"
+ ],
+ "spread": false,
+ "optional": false,
+ "name": "tf",
+ "description": "TableFilter instance"
+ },
{
"nullable": null,
"types": [
@@ -2118,8 +2127,8 @@
],
"spread": false,
"optional": false,
- "name": "tf",
- "description": "TableFilter instance"
+ "name": "opts",
+ "description": "Configuration object"
}
],
"generator": false
@@ -2133,13 +2142,15 @@
"memberof": "src/extensions/colOps/colOps.js~ColOps",
"longname": "src/extensions/colOps/colOps.js~ColOps#onBeforeOperation",
"access": null,
- "description": null,
- "lineNumber": 15,
- "undocument": true,
+ "description": "Callback fired before columns operations start",
+ "lineNumber": 23,
"type": {
+ "nullable": null,
"types": [
- "*"
- ]
+ "Function"
+ ],
+ "spread": false,
+ "description": null
}
},
{
@@ -2151,13 +2162,15 @@
"memberof": "src/extensions/colOps/colOps.js~ColOps",
"longname": "src/extensions/colOps/colOps.js~ColOps#onAfterOperation",
"access": null,
- "description": null,
- "lineNumber": 18,
- "undocument": true,
+ "description": "Callback fired after columns operations are completed",
+ "lineNumber": 30,
"type": {
+ "nullable": null,
"types": [
- "*"
- ]
+ "Function"
+ ],
+ "spread": false,
+ "description": null
}
},
{
@@ -2169,13 +2182,15 @@
"memberof": "src/extensions/colOps/colOps.js~ColOps",
"longname": "src/extensions/colOps/colOps.js~ColOps#opts",
"access": null,
- "description": null,
- "lineNumber": 21,
- "undocument": true,
+ "description": "Configuration options",
+ "lineNumber": 37,
"type": {
+ "nullable": null,
"types": [
- "*"
- ]
+ "Object"
+ ],
+ "spread": false,
+ "description": null
}
},
{
@@ -2187,9 +2202,8 @@
"memberof": "src/extensions/colOps/colOps.js~ColOps",
"longname": "src/extensions/colOps/colOps.js~ColOps#init",
"access": null,
- "description": null,
- "lineNumber": 25,
- "undocument": true,
+ "description": "Initializes ColOps instance",
+ "lineNumber": 45,
"params": [],
"generator": false
},
@@ -2202,9 +2216,14 @@
"memberof": "src/extensions/colOps/colOps.js~ColOps",
"longname": "src/extensions/colOps/colOps.js~ColOps#initialized",
"access": null,
- "description": null,
- "lineNumber": 33,
- "undocument": true,
+ "description": "",
+ "lineNumber": 57,
+ "unknown": [
+ {
+ "tagName": "@inherited",
+ "tagValue": ""
+ }
+ ],
"type": {
"types": [
"boolean"
@@ -2221,7 +2240,7 @@
"longname": "src/extensions/colOps/colOps.js~ColOps#calc",
"access": null,
"description": "Calculates columns' values\nConfiguration options are stored in 'opts' property\n- 'id' contains ids of elements showing result (array)\n- 'col' contains the columns' indexes (array)\n- 'operation' contains operation type (array, values: 'sum', 'mean',\n 'min', 'max', 'median', 'q1', 'q3')\n- 'write_method' array defines which method to use for displaying the\n result (innerHTML, setValue, createTextNode) - default: 'innerHTML'\n- 'tot_row_index' defines in which row results are displayed\n (integers array)\n\n- changes made by Nuovella:\n(1) optimized the routine (now it will only process each column once),\n(2) added calculations for the median, lower and upper quartile.",
- "lineNumber": 52,
+ "lineNumber": 76,
"params": [],
"generator": false
},
@@ -2234,9 +2253,8 @@
"memberof": "src/extensions/colOps/colOps.js~ColOps",
"longname": "src/extensions/colOps/colOps.js~ColOps#destroy",
"access": null,
- "description": null,
- "lineNumber": 320,
- "undocument": true,
+ "description": "Remove extension",
+ "lineNumber": 349,
"params": [],
"generator": false
},
@@ -2250,7 +2268,7 @@
"longname": "src/extensions/colOps/colOps.js~ColOps#initialized",
"access": null,
"description": null,
- "lineNumber": 326,
+ "lineNumber": 355,
"undocument": true,
"type": {
"types": [
@@ -6618,7 +6636,7 @@
"access": null,
"description": null,
"lineNumber": 1,
- "content": "import {Feature} from '../feature';\nimport {createElm, createText, elm, removeElm} from '../dom';\nimport {addEvt} from '../event';\n\n/**\n * Clear button UI component\n */\nexport class ClearButton extends Feature {\n\n /**\n * Creates an instance of ClearButton\n * @param {TableFilter} tf TableFilter instance\n */\n constructor(tf) {\n super(tf, 'btnReset');\n\n let f = this.config;\n\n /**\n * Container element ID\n * @type {String}\n */\n this.targetId = f.btn_reset_target_id || null;\n\n /**\n * Clear button element\n * @type {DOMElement}\n * @private\n */\n this.element = null;\n\n /**\n * Text for the clear button\n * @type {String}\n */\n this.text = f.btn_reset_text || 'Reset';\n\n /**\n * Tooltip text for the clear button\n * @type {String}\n */\n this.tooltip = f.btn_reset_tooltip || 'Clear filters';\n\n /**\n * Custom Html string for the clear button\n * @type {String}\n */\n this.html = f.btn_reset_html ||\n (!tf.enableIcons ? null :\n ' ');\n\n /**\n * Prefix for container ID\n * @type {String}\n * @private\n */\n this.prfxCont = 'resetspan_';\n }\n\n /**\n * Click event handler for clear button\n * @private\n */\n onClick() {\n if (!this.isEnabled()) {\n return;\n }\n this.tf.clearFilters();\n }\n\n /**\n * Initialize clear button component\n */\n init() {\n let tf = this.tf;\n\n if (this.initialized) {\n return;\n }\n\n let resetspan = createElm('span', ['id', this.prfxCont + tf.id]);\n\n // reset button is added to defined element\n if (!this.targetId) {\n tf.setToolbar();\n }\n let targetEl = !this.targetId ? tf.rDiv : elm(this.targetId);\n targetEl.appendChild(resetspan);\n\n if (!this.html) {\n let fltreset = createElm('a', ['href', 'javascript:void(0);']);\n fltreset.className = tf.btnResetCssClass;\n fltreset.appendChild(createText(this.text));\n resetspan.appendChild(fltreset);\n addEvt(fltreset, 'click', () => this.onClick());\n } else {\n resetspan.innerHTML = this.html;\n let resetEl = resetspan.firstChild;\n addEvt(resetEl, 'click', () => this.onClick());\n }\n this.element = resetspan.firstChild;\n\n /**\n * @inherited\n */\n this.initialized = true;\n }\n\n /**\n * Destroy ClearButton instance\n */\n destroy() {\n let tf = this.tf;\n\n if (!this.initialized) {\n return;\n }\n\n let resetspan = elm(this.prfxCont + tf.id);\n if (resetspan) {\n removeElm(resetspan);\n }\n this.element = null;\n this.initialized = false;\n }\n}\n"
+ "content": "import {Feature} from '../feature';\nimport {createElm, createText, elm, removeElm} from '../dom';\nimport {addEvt} from '../event';\n\n/**\n * Clear button UI component\n */\nexport class ClearButton extends Feature {\n\n /**\n * Creates an instance of ClearButton\n * @param {TableFilter} tf TableFilter instance\n */\n constructor(tf) {\n super(tf, 'btnReset');\n\n let f = this.config;\n\n /**\n * Container element ID\n * @type {String}\n */\n this.targetId = f.btn_reset_target_id || null;\n\n /**\n * Clear button element\n * @type {DOMElement}\n * @private\n */\n this.element = null;\n\n /**\n * Text for the clear button\n * @type {String}\n */\n this.text = f.btn_reset_text || 'Reset';\n\n /**\n * Css class for reset button\n * @type {String}\n */\n this.cssClass = f.btn_reset_css_class || 'reset';\n\n /**\n * Tooltip text for the clear button\n * @type {String}\n */\n this.tooltip = f.btn_reset_tooltip || 'Clear filters';\n\n /**\n * Custom Html string for the clear button\n * @type {String}\n */\n this.html = f.btn_reset_html ||\n (!tf.enableIcons ? null :\n ' ');\n\n /**\n * Prefix for container ID\n * @type {String}\n * @private\n */\n this.prfxCont = 'resetspan_';\n }\n\n /**\n * Click event handler for clear button\n * @private\n */\n onClick() {\n if (!this.isEnabled()) {\n return;\n }\n this.tf.clearFilters();\n }\n\n /**\n * Initialize clear button component\n */\n init() {\n let tf = this.tf;\n\n if (this.initialized) {\n return;\n }\n\n let resetspan = createElm('span', ['id', this.prfxCont + tf.id]);\n\n // reset button is added to defined element\n if (!this.targetId) {\n tf.setToolbar();\n }\n let targetEl = !this.targetId ? tf.rDiv : elm(this.targetId);\n targetEl.appendChild(resetspan);\n\n if (!this.html) {\n let fltreset = createElm('a', ['href', 'javascript:void(0);']);\n fltreset.className = this.cssClass;\n fltreset.appendChild(createText(this.text));\n resetspan.appendChild(fltreset);\n addEvt(fltreset, 'click', () => this.onClick());\n } else {\n resetspan.innerHTML = this.html;\n let resetEl = resetspan.firstChild;\n addEvt(resetEl, 'click', () => this.onClick());\n }\n this.element = resetspan.firstChild;\n\n /**\n * @inherited\n */\n this.initialized = true;\n }\n\n /**\n * Destroy ClearButton instance\n */\n destroy() {\n let tf = this.tf;\n\n if (!this.initialized) {\n return;\n }\n\n let resetspan = elm(this.prfxCont + tf.id);\n if (resetspan) {\n removeElm(resetspan);\n }\n this.element = null;\n this.initialized = false;\n }\n}\n"
},
{
"__docId__": 304,
@@ -6729,11 +6747,11 @@
"kind": "member",
"static": false,
"variation": null,
- "name": "tooltip",
+ "name": "cssClass",
"memberof": "src/modules/clearButton.js~ClearButton",
- "longname": "src/modules/clearButton.js~ClearButton#tooltip",
+ "longname": "src/modules/clearButton.js~ClearButton#cssClass",
"access": null,
- "description": "Tooltip text for the clear button",
+ "description": "Css class for reset button",
"lineNumber": 42,
"type": {
"nullable": null,
@@ -6749,11 +6767,11 @@
"kind": "member",
"static": false,
"variation": null,
- "name": "html",
+ "name": "tooltip",
"memberof": "src/modules/clearButton.js~ClearButton",
- "longname": "src/modules/clearButton.js~ClearButton#html",
+ "longname": "src/modules/clearButton.js~ClearButton#tooltip",
"access": null,
- "description": "Custom Html string for the clear button",
+ "description": "Tooltip text for the clear button",
"lineNumber": 48,
"type": {
"nullable": null,
@@ -6769,12 +6787,12 @@
"kind": "member",
"static": false,
"variation": null,
- "name": "prfxCont",
+ "name": "html",
"memberof": "src/modules/clearButton.js~ClearButton",
- "longname": "src/modules/clearButton.js~ClearButton#prfxCont",
- "access": "private",
- "description": "Prefix for container ID",
- "lineNumber": 58,
+ "longname": "src/modules/clearButton.js~ClearButton#html",
+ "access": null,
+ "description": "Custom Html string for the clear button",
+ "lineNumber": 54,
"type": {
"nullable": null,
"types": [
@@ -6786,6 +6804,26 @@
},
{
"__docId__": 312,
+ "kind": "member",
+ "static": false,
+ "variation": null,
+ "name": "prfxCont",
+ "memberof": "src/modules/clearButton.js~ClearButton",
+ "longname": "src/modules/clearButton.js~ClearButton#prfxCont",
+ "access": "private",
+ "description": "Prefix for container ID",
+ "lineNumber": 64,
+ "type": {
+ "nullable": null,
+ "types": [
+ "String"
+ ],
+ "spread": false,
+ "description": null
+ }
+ },
+ {
+ "__docId__": 313,
"kind": "method",
"static": false,
"variation": null,
@@ -6794,12 +6832,12 @@
"longname": "src/modules/clearButton.js~ClearButton#onClick",
"access": "private",
"description": "Click event handler for clear button",
- "lineNumber": 65,
+ "lineNumber": 71,
"params": [],
"generator": false
},
{
- "__docId__": 313,
+ "__docId__": 314,
"kind": "method",
"static": false,
"variation": null,
@@ -6808,12 +6846,12 @@
"longname": "src/modules/clearButton.js~ClearButton#init",
"access": null,
"description": "Initialize clear button component",
- "lineNumber": 75,
+ "lineNumber": 81,
"params": [],
"generator": false
},
{
- "__docId__": 314,
+ "__docId__": 315,
"kind": "member",
"static": false,
"variation": null,
@@ -6822,7 +6860,7 @@
"longname": "src/modules/clearButton.js~ClearButton#element",
"access": null,
"description": null,
- "lineNumber": 102,
+ "lineNumber": 108,
"undocument": true,
"type": {
"types": [
@@ -6831,7 +6869,7 @@
}
},
{
- "__docId__": 315,
+ "__docId__": 316,
"kind": "member",
"static": false,
"variation": null,
@@ -6840,7 +6878,7 @@
"longname": "src/modules/clearButton.js~ClearButton#initialized",
"access": null,
"description": "",
- "lineNumber": 107,
+ "lineNumber": 113,
"unknown": [
{
"tagName": "@inherited",
@@ -6854,7 +6892,7 @@
}
},
{
- "__docId__": 316,
+ "__docId__": 317,
"kind": "method",
"static": false,
"variation": null,
@@ -6863,12 +6901,12 @@
"longname": "src/modules/clearButton.js~ClearButton#destroy",
"access": null,
"description": "Destroy ClearButton instance",
- "lineNumber": 113,
+ "lineNumber": 119,
"params": [],
"generator": false
},
{
- "__docId__": 317,
+ "__docId__": 318,
"kind": "member",
"static": false,
"variation": null,
@@ -6877,7 +6915,7 @@
"longname": "src/modules/clearButton.js~ClearButton#element",
"access": null,
"description": null,
- "lineNumber": 124,
+ "lineNumber": 130,
"undocument": true,
"type": {
"types": [
@@ -6886,7 +6924,7 @@
}
},
{
- "__docId__": 318,
+ "__docId__": 319,
"kind": "member",
"static": false,
"variation": null,
@@ -6895,7 +6933,7 @@
"longname": "src/modules/clearButton.js~ClearButton#initialized",
"access": null,
"description": null,
- "lineNumber": 125,
+ "lineNumber": 131,
"undocument": true,
"type": {
"types": [
@@ -6904,7 +6942,7 @@
}
},
{
- "__docId__": 319,
+ "__docId__": 320,
"kind": "file",
"static": true,
"variation": null,
@@ -6917,7 +6955,7 @@
"content": "import {Feature} from '../feature';\nimport {createElm, createOpt, elm} from '../dom';\nimport {has} from '../array';\nimport {matchCase} from '../string';\nimport {ignoreCase, numSortAsc, numSortDesc} from '../sort';\nimport {addEvt, targetEvt} from '../event';\nimport {SELECT, MULTIPLE, NONE} from '../const';\n\nconst SORT_ERROR = 'Filter options for column {0} cannot be sorted in ' +\n '{1} manner.';\n\n/**\n * Dropdown filter UI component\n */\nexport class Dropdown extends Feature {\n\n /**\n * Creates an instance of Dropdown\n * @param {TableFilter} tf TableFilter instance\n */\n constructor(tf) {\n super(tf, 'dropdown');\n\n // Configuration object\n let f = this.config;\n\n /**\n * Enable the reset filter option as first item\n * @type {Boolean}\n */\n this.enableSlcResetFilter = f.enable_slc_reset_filter === false ?\n false : true;\n\n /**\n * Non empty option text\n * @type {String}\n */\n this.nonEmptyText = f.non_empty_text || '(Non empty)';\n\n /**\n * Tooltip text appearing on multiple select\n * @type {String}\n */\n this.multipleSlcTooltip = f.multiple_slc_tooltip ||\n 'Use Ctrl/Cmd key for multiple selections';\n\n /**\n * Indicates drop-down has custom options\n * @private\n */\n this.isCustom = null;\n\n /**\n * List of options values\n * @type {Array}\n * @private\n */\n this.opts = null;\n\n /**\n * List of options texts for custom values\n * @type {Array}\n * @private\n */\n this.optsTxt = null;\n }\n\n\n /**\n * Drop-down filter focus event handler\n * @param {Event} e DOM Event\n * @private\n */\n onSlcFocus(e) {\n let elm = targetEvt(e);\n let tf = this.tf;\n // select is populated when element has focus\n if (tf.loadFltOnDemand && elm.getAttribute('filled') === '0') {\n let ct = elm.getAttribute('ct');\n this.build(ct);\n }\n this.emitter.emit('filter-focus', tf, elm);\n }\n\n /**\n * Drop-down filter change event handler\n * @private\n */\n onSlcChange() {\n if (this.tf.onSlcChange) {\n this.tf.filter();\n }\n }\n\n /**\n * Initialize drop-down filter\n * @param {Number} colIndex Column index\n * @param {Boolean} isExternal External filter flag\n * @param {DOMElement} container Dom element containing the filter\n */\n init(colIndex, isExternal, container) {\n let tf = this.tf;\n let col = tf.getFilterType(colIndex);\n let externalFltTgtId = isExternal ?\n tf.externalFltTgtIds[colIndex] : null;\n\n let slc = createElm(SELECT,\n ['id', tf.prfxFlt + colIndex + '_' + tf.id],\n ['ct', colIndex], ['filled', '0']\n );\n\n if (col === MULTIPLE) {\n slc.multiple = MULTIPLE;\n slc.title = this.multipleSlcTooltip;\n }\n slc.className = col.toLowerCase() === SELECT ?\n tf.fltCssClass : tf.fltMultiCssClass;\n\n //filter is appended in container element\n if (externalFltTgtId) {\n elm(externalFltTgtId).appendChild(slc);\n } else {\n container.appendChild(slc);\n }\n\n tf.fltIds.push(slc.id);\n\n if (!tf.loadFltOnDemand) {\n this.build(colIndex);\n } else {\n //1st option is created here since build isn't invoked\n let opt0 = createOpt(tf.displayAllText, '');\n slc.appendChild(opt0);\n }\n\n addEvt(slc, 'change', () => this.onSlcChange());\n addEvt(slc, 'focus', (e) => this.onSlcFocus(e));\n\n this.emitter.on(\n ['build-select-filter'],\n (tf, colIndex, isLinked, isExternal) =>\n this.build(colIndex, isLinked, isExternal)\n );\n this.emitter.on(\n ['select-options'],\n (tf, colIndex, values) => this.selectOptions(colIndex, values)\n );\n\n /**\n * @inherited\n */\n this.initialized = true;\n }\n\n /**\n * Build drop-down filter UI\n * @param {Number} colIndex Column index\n * @param {Boolean} isLinked Enable linked refresh behaviour\n */\n build(colIndex, isLinked = false) {\n let tf = this.tf;\n colIndex = parseInt(colIndex, 10);\n\n this.emitter.emit('before-populating-filter', tf, colIndex);\n\n this.opts = [];\n this.optsTxt = [];\n\n let slcId = tf.fltIds[colIndex];\n let slc = elm(slcId);\n let rows = tf.tbl.rows;\n let nbRows = tf.getRowsNb(true);\n\n //custom select test\n this.isCustom = tf.isCustomOptions(colIndex);\n\n //custom selects text\n let activeIdx;\n let activeFilterId = tf.getActiveFilterId();\n if (isLinked && activeFilterId) {\n activeIdx = tf.getColumnIndexFromFilterId(activeFilterId);\n }\n\n let excludedOpts = null,\n filteredDataCol = null;\n if (isLinked && tf.disableExcludedOptions) {\n excludedOpts = [];\n filteredDataCol = [];\n }\n\n for (let k = tf.refRow; k < nbRows; k++) {\n // always visible rows don't need to appear on selects as always\n // valid\n if (tf.hasVisibleRows && tf.visibleRows.indexOf(k) !== -1) {\n continue;\n }\n\n let cell = rows[k].cells,\n nchilds = cell.length;\n\n // checks if row has exact cell #\n if (nchilds !== tf.nbCells || this.isCustom) {\n continue;\n }\n\n // this loop retrieves cell data\n for (let j = 0; j < nchilds; j++) {\n // WTF: cyclomatic complexity hell\n // TODO: simplify hell below\n if ((colIndex === j &&\n (!isLinked ||\n (isLinked && tf.disableExcludedOptions))) ||\n (colIndex === j && isLinked &&\n ((rows[k].style.display === '' && !tf.paging) ||\n (tf.paging && (!tf.validRowsIndex ||\n (tf.validRowsIndex &&\n tf.validRowsIndex.indexOf(k) !== -1)) &&\n ((activeIdx === undefined ||\n activeIdx === colIndex) ||\n (activeIdx !== colIndex &&\n tf.validRowsIndex.indexOf(k) !== -1)))))) {\n let cellData = tf.getCellData(cell[j]),\n //Vary Peter's patch\n cellString = matchCase(cellData, tf.caseSensitive);\n\n // checks if celldata is already in array\n if (!has(this.opts, cellString, tf.caseSensitive)) {\n this.opts.push(cellData);\n }\n\n if (isLinked && tf.disableExcludedOptions) {\n let filteredCol = filteredDataCol[j];\n if (!filteredCol) {\n filteredCol = tf.getFilteredDataCol(j);\n }\n if (!has(filteredCol, cellString, tf.caseSensitive) &&\n !has(excludedOpts, cellString, tf.caseSensitive)) {\n excludedOpts.push(cellData);\n }\n }\n }//if colIndex==j\n }//for j\n }//for k\n\n //Retrieves custom values\n if (this.isCustom) {\n let customValues = tf.getCustomOptions(colIndex);\n this.opts = customValues[0];\n this.optsTxt = customValues[1];\n }\n\n if (tf.sortSlc && !this.isCustom) {\n if (!tf.caseSensitive) {\n this.opts.sort(ignoreCase);\n if (excludedOpts) {\n excludedOpts.sort(ignoreCase);\n }\n } else {\n this.opts.sort();\n if (excludedOpts) { excludedOpts.sort(); }\n }\n }\n\n //asc sort\n if (tf.sortNumAsc.indexOf(colIndex) !== -1) {\n try {\n this.opts.sort(numSortAsc);\n if (excludedOpts) {\n excludedOpts.sort(numSortAsc);\n }\n if (this.isCustom) {\n this.optsTxt.sort(numSortAsc);\n }\n } catch (e) {\n throw new Error(SORT_ERROR.replace('{0}', colIndex)\n .replace('{1}', 'ascending'));\n }//in case there are alphanumeric values\n }\n //desc sort\n if (tf.sortNumDesc.indexOf(colIndex) !== -1) {\n try {\n this.opts.sort(numSortDesc);\n if (excludedOpts) {\n excludedOpts.sort(numSortDesc);\n }\n if (this.isCustom) {\n this.optsTxt.sort(numSortDesc);\n }\n } catch (e) {\n throw new Error(SORT_ERROR.replace('{0}', colIndex)\n .replace('{1}', 'ascending'));\n }//in case there are alphanumeric values\n }\n\n //populates drop-down\n this.addOptions(colIndex, slc, isLinked, excludedOpts);\n\n this.emitter.emit('after-populating-filter', tf, colIndex, slc);\n }\n\n /**\n * Add drop-down options\n * @param {Number} colIndex Column index\n * @param {Object} slc Select Dom element\n * @param {Boolean} isLinked Enable linked refresh behaviour\n * @param {Array} excludedOpts Array of excluded options\n */\n addOptions(colIndex, slc, isLinked, excludedOpts) {\n let tf = this.tf,\n slcValue = slc.value;\n\n slc.innerHTML = '';\n slc = this.addFirstOption(slc);\n\n for (let y = 0; y < this.opts.length; y++) {\n if (this.opts[y] === '') {\n continue;\n }\n let val = this.opts[y]; //option value\n let lbl = this.isCustom ? this.optsTxt[y] : val; //option text\n let isDisabled = false;\n if (isLinked && tf.disableExcludedOptions &&\n has(excludedOpts, matchCase(val, tf.caseSensitive),\n tf.caseSensitive)) {\n isDisabled = true;\n }\n\n let opt;\n //fill select on demand\n if (tf.loadFltOnDemand && slcValue === this.opts[y] &&\n tf.getFilterType(colIndex) === SELECT) {\n opt = createOpt(lbl, val, true);\n } else {\n opt = createOpt(lbl, val, false);\n }\n if (isDisabled) {\n opt.disabled = true;\n }\n slc.appendChild(opt);\n }// for y\n\n slc.setAttribute('filled', '1');\n }\n\n /**\n * Add drop-down header option\n * @param {Object} slc Select DOM element\n */\n addFirstOption(slc) {\n let tf = this.tf;\n\n let opt0 = createOpt(\n (!this.enableSlcResetFilter ? '' : tf.displayAllText), '');\n if (!this.enableSlcResetFilter) {\n opt0.style.display = NONE;\n }\n slc.appendChild(opt0);\n if (tf.enableEmptyOption) {\n let opt1 = createOpt(tf.emptyText, tf.emOperator);\n slc.appendChild(opt1);\n }\n if (tf.enableNonEmptyOption) {\n let opt2 = createOpt(tf.nonEmptyText, tf.nmOperator);\n slc.appendChild(opt2);\n }\n return slc;\n }\n\n /**\n * Select filter options programmatically\n * @param {Number} colIndex Column index\n * @param {Array} values Array of option values to select\n */\n selectOptions(colIndex, values = []) {\n let tf = this.tf;\n if (tf.getFilterType(colIndex) !== MULTIPLE || values.length === 0) {\n return;\n }\n let slc = tf.getFilterElement(colIndex);\n [].forEach.call(slc.options, (option) => {\n // Empty value means clear all selections and first option is the\n // clear all option\n if (values[0] === '' || option.value === '') {\n option.selected = false;\n }\n\n if (option.value !== '' && has(values, option.value, true)) {\n option.selected = true;\n }//if\n });\n }\n\n /**\n * Get filter values for a given column index\n * @param {Number} colIndex Column index\n * @returns {Array} values Array of selected values\n */\n getValues(colIndex) {\n let tf = this.tf;\n let slc = tf.getFilterElement(colIndex);\n let values = [];\n\n // IE >= 9 does not support the selectedOptions property :(\n if (slc.selectedOptions) {\n [].forEach.call(slc.selectedOptions,\n option => values.push(option.value));\n } else {\n [].forEach.call(slc.options, (option) => {\n if (option.selected) {\n values.push(option.value);\n }\n });\n }\n\n return values;\n }\n\n /**\n * Destroy Dropdown instance\n */\n destroy() {\n this.emitter.off(\n ['build-select-filter'],\n (colIndex, isLinked, isExternal) =>\n this.build(colIndex, isLinked, isExternal)\n );\n this.emitter.off(\n ['select-options'],\n (tf, colIndex, values) => this.selectOptions(colIndex, values)\n );\n }\n}\n"
},
{
- "__docId__": 320,
+ "__docId__": 321,
"kind": "variable",
"static": true,
"variation": null,
@@ -6938,7 +6976,7 @@
}
},
{
- "__docId__": 321,
+ "__docId__": 322,
"kind": "class",
"static": true,
"variation": null,
@@ -6957,7 +6995,7 @@
]
},
{
- "__docId__": 322,
+ "__docId__": 323,
"kind": "constructor",
"static": false,
"variation": null,
@@ -6982,7 +7020,7 @@
"generator": false
},
{
- "__docId__": 323,
+ "__docId__": 324,
"kind": "member",
"static": false,
"variation": null,
@@ -7002,7 +7040,7 @@
}
},
{
- "__docId__": 324,
+ "__docId__": 325,
"kind": "member",
"static": false,
"variation": null,
@@ -7022,7 +7060,7 @@
}
},
{
- "__docId__": 325,
+ "__docId__": 326,
"kind": "member",
"static": false,
"variation": null,
@@ -7042,7 +7080,7 @@
}
},
{
- "__docId__": 326,
+ "__docId__": 327,
"kind": "member",
"static": false,
"variation": null,
@@ -7059,7 +7097,7 @@
}
},
{
- "__docId__": 327,
+ "__docId__": 328,
"kind": "member",
"static": false,
"variation": null,
@@ -7079,7 +7117,7 @@
}
},
{
- "__docId__": 328,
+ "__docId__": 329,
"kind": "member",
"static": false,
"variation": null,
@@ -7099,7 +7137,7 @@
}
},
{
- "__docId__": 329,
+ "__docId__": 330,
"kind": "method",
"static": false,
"variation": null,
@@ -7124,7 +7162,7 @@
"generator": false
},
{
- "__docId__": 330,
+ "__docId__": 331,
"kind": "method",
"static": false,
"variation": null,
@@ -7138,7 +7176,7 @@
"generator": false
},
{
- "__docId__": 331,
+ "__docId__": 332,
"kind": "method",
"static": false,
"variation": null,
@@ -7183,7 +7221,7 @@
"generator": false
},
{
- "__docId__": 332,
+ "__docId__": 333,
"kind": "member",
"static": false,
"variation": null,
@@ -7206,7 +7244,7 @@
}
},
{
- "__docId__": 333,
+ "__docId__": 334,
"kind": "method",
"static": false,
"variation": null,
@@ -7241,7 +7279,7 @@
"generator": false
},
{
- "__docId__": 334,
+ "__docId__": 335,
"kind": "member",
"static": false,
"variation": null,
@@ -7259,7 +7297,7 @@
}
},
{
- "__docId__": 335,
+ "__docId__": 336,
"kind": "member",
"static": false,
"variation": null,
@@ -7277,7 +7315,7 @@
}
},
{
- "__docId__": 336,
+ "__docId__": 337,
"kind": "member",
"static": false,
"variation": null,
@@ -7295,7 +7333,7 @@
}
},
{
- "__docId__": 337,
+ "__docId__": 338,
"kind": "member",
"static": false,
"variation": null,
@@ -7313,7 +7351,7 @@
}
},
{
- "__docId__": 338,
+ "__docId__": 339,
"kind": "member",
"static": false,
"variation": null,
@@ -7331,7 +7369,7 @@
}
},
{
- "__docId__": 339,
+ "__docId__": 340,
"kind": "method",
"static": false,
"variation": null,
@@ -7386,7 +7424,7 @@
"generator": false
},
{
- "__docId__": 340,
+ "__docId__": 341,
"kind": "method",
"static": false,
"variation": null,
@@ -7416,7 +7454,7 @@
"generator": false
},
{
- "__docId__": 341,
+ "__docId__": 342,
"kind": "method",
"static": false,
"variation": null,
@@ -7451,7 +7489,7 @@
"generator": false
},
{
- "__docId__": 342,
+ "__docId__": 343,
"kind": "method",
"static": false,
"variation": null,
@@ -7490,7 +7528,7 @@
"generator": false
},
{
- "__docId__": 343,
+ "__docId__": 344,
"kind": "method",
"static": false,
"variation": null,
@@ -7504,7 +7542,7 @@
"generator": false
},
{
- "__docId__": 344,
+ "__docId__": 345,
"kind": "file",
"static": true,
"variation": null,
@@ -7517,7 +7555,7 @@
"content": "import {Feature} from '../feature';\nimport {createElm, removeElm, elm, tag} from '../dom';\nimport {addEvt, targetEvt} from '../event';\nimport {contains} from '../string';\nimport {NONE} from '../const';\n\n/**\n * Grid layout, table with fixed headers\n */\nexport class GridLayout extends Feature {\n\n /**\n * Creates an instance of GridLayout\n * @param {TableFilter} tf TableFilter instance\n */\n constructor(tf) {\n super(tf, 'gridLayout');\n\n let f = this.config;\n\n /**\n * Grid-layout container width as CSS string\n * @type {String}\n */\n this.width = f.grid_width || null;\n\n /**\n * Grid-layout container height as CSS string\n * @type {String}\n */\n this.height = f.grid_height || null;\n\n /**\n * Css class for main container element\n * @type {String}\n */\n this.mainContCssClass = f.grid_cont_css_class || 'grd_Cont';\n\n /**\n * Css class for body table container element\n * @type {String}\n */\n this.contCssClass = f.grid_tbl_cont_css_class || 'grd_tblCont';\n\n /**\n * Css class for headers table container element\n * @type {String}\n */\n this.headContCssClass = f.grid_tblHead_cont_css_class ||\n 'grd_headTblCont';\n\n /**\n * Css class for toolbar container element (rows counter, paging etc.)\n * @type {String}\n */\n this.infDivCssClass = f.grid_inf_grid_css_class || 'grd_inf';\n\n /**\n * Index of the headers row, default: 0\n * @type {Number}\n */\n this.headRowIndex = f.grid_headers_row_index || 0;\n\n /**\n * Collection of the header row indexes to be moved into headers table\n * @type {Array}\n */\n this.headRows = f.grid_headers_rows || [0];\n\n /**\n * Enable or disable column filters generation, default: true\n * @type {Boolean}\n */\n this.enableFilters = f.grid_enable_default_filters === false ?\n false : true;\n\n /**\n * Enable or disable column headers, default: false\n * @type {Boolean}\n */\n this.noHeaders = Boolean(f.grid_no_headers);\n\n /**\n * Grid-layout default column widht as CSS string\n * @type {String}\n */\n this.defaultColWidth = f.grid_default_col_width || '100px';\n\n /**\n * List of column elements\n * @type {Array}\n * @private\n */\n this.colElms = [];\n\n /**\n * Prefix for grid-layout main container ID\n * @type {String}\n * @private\n */\n this.prfxMainTblCont = 'gridCont_';\n\n /**\n * Prefix for grid-layout body table container ID\n * @type {String}\n * @private\n */\n this.prfxTblCont = 'tblCont_';\n\n /**\n * Prefix for grid-layout headers table container ID\n * @type {String}\n * @private\n */\n this.prfxHeadTblCont = 'tblHeadCont_';\n\n /**\n * Prefix for grid-layout headers table ID\n * @type {String}\n * @private\n */\n this.prfxHeadTbl = 'tblHead_';\n\n /**\n * Prefix for grid-layout filter's cell ID\n * @type {String}\n * @private\n */\n this.prfxGridFltTd = '_td_';\n\n /**\n * Prefix for grid-layout header's cell ID\n * @type {String}\n * @private\n */\n this.prfxGridTh = 'tblHeadTh_';\n\n /**\n * Mark-up of original HTML table\n * @type {String}\n * @private\n */\n this.sourceTblHtml = tf.tbl.outerHTML;\n\n /**\n * Indicates if working table has column elements\n * @type {Boolean}\n * @private\n */\n this.tblHasColTag = tag(tf.tbl, 'col').length > 0 ? true : false;\n\n // filters flag at TF level\n tf.fltGrid = this.enableFilters;\n }\n\n /**\n * Generates a grid with fixed headers\n * TODO: reduce size of init by extracting single purposed methods\n */\n init() {\n let tf = this.tf;\n let tbl = tf.tbl;\n\n if (this.initialized) {\n return;\n }\n\n // Override relevant TableFilter properties\n this.setOverrides();\n\n // Assign default column widths\n this.setDefaultColWidths();\n\n // Initial table width\n let tblW = this.initialTableWidth();\n\n //Main container: it will contain all the elements\n this.tblMainCont = this.createContainer(this.prfxMainTblCont + tf.id,\n 'div', this.mainContCssClass);\n if (this.width) {\n this.tblMainCont.style.width = this.width;\n }\n tbl.parentNode.insertBefore(this.tblMainCont, tbl);\n\n //Table container: div wrapping content table\n this.tblCont = this.createContainer(this.prfxTblCont + tf.id, 'div',\n this.contCssClass);\n this.setConfigWidth(this.tblCont);\n if (this.height) {\n this.tblCont.style.height = this.height;\n }\n tbl.parentNode.insertBefore(this.tblCont, tbl);\n let t = removeElm(tbl);\n this.tblCont.appendChild(t);\n\n //In case table width is expressed in %\n if (tbl.style.width === '') {\n tbl.style.width = (contains('%', tblW) ?\n tbl.clientWidth : tblW) + 'px';\n }\n\n let d = removeElm(this.tblCont);\n this.tblMainCont.appendChild(d);\n\n //Headers table container: div wrapping headers table\n this.headTblCont = this.createContainer(this.prfxHeadTblCont + tf.id,\n 'div', this.headContCssClass);\n this.setConfigWidth(this.headTblCont);\n\n //Headers table\n this.headTbl = createElm('table', ['id', this.prfxHeadTbl + tf.id]);\n let tH = createElm('tHead');\n\n //1st row should be headers row, ids are added if not set\n //Those ids are used by the sort feature\n let hRow = tbl.rows[this.headRowIndex];\n let sortTriggers = this.getSortTriggerIds(hRow);\n\n //Filters row is created\n let filtersRow = this.createFiltersRow();\n\n //Headers row are moved from content table to headers table\n this.setHeadersRow(tH);\n\n this.headTbl.appendChild(tH);\n if (tf.filtersRowIndex === 0) {\n tH.insertBefore(filtersRow, hRow);\n } else {\n tH.appendChild(filtersRow);\n }\n\n this.headTblCont.appendChild(this.headTbl);\n this.tblCont.parentNode.insertBefore(this.headTblCont, this.tblCont);\n\n //THead needs to be removed in content table for sort feature\n let thead = tag(tbl, 'thead');\n if (thead.length > 0) {\n tbl.removeChild(thead[0]);\n }\n\n //Headers table style\n this.headTbl.style.tableLayout = 'fixed';\n tbl.style.tableLayout = 'fixed';\n this.headTbl.cellPadding = tbl.cellPadding;\n this.headTbl.cellSpacing = tbl.cellSpacing;\n // this.headTbl.style.width = tbl.style.width;\n\n //content table without headers needs col widths to be reset\n tf.setColWidths(this.headTbl);\n\n //Headers container width\n // this.headTblCont.style.width = this.tblCont.clientWidth+'px';\n\n tbl.style.width = '';\n //\n this.headTbl.style.width = tbl.clientWidth + 'px';\n //\n\n //scroll synchronisation\n addEvt(this.tblCont, 'scroll', (evt) => {\n let elm = targetEvt(evt);\n let scrollLeft = elm.scrollLeft;\n this.headTblCont.scrollLeft = scrollLeft;\n //New pointerX calc taking into account scrollLeft\n // if(!o.isPointerXOverwritten){\n // try{\n // o.Evt.pointerX = function(evt){\n // let e = evt || global.event;\n // let bdScrollLeft = tf_StandardBody().scrollLeft +\n // scrollLeft;\n // return (e.pageX + scrollLeft) ||\n // (e.clientX + bdScrollLeft);\n // };\n // o.isPointerXOverwritten = true;\n // } catch(err) {\n // o.isPointerXOverwritten = false;\n // }\n // }\n });\n\n // TODO: Trigger a custom event handled by sort extension\n let sort = tf.extension('sort');\n if (sort) {\n sort.asyncSort = true;\n sort.triggerIds = sortTriggers;\n }\n\n //Col elements are enough to keep column widths after sorting and\n //filtering\n this.setColumnElements();\n\n if (tf.popupFilters) {\n filtersRow.style.display = NONE;\n }\n\n if (tbl.clientWidth !== this.headTbl.clientWidth) {\n tbl.style.width = this.headTbl.clientWidth + 'px';\n }\n\n /**\n * @inherited\n */\n this.initialized = true;\n }\n\n /**\n * Overrides TableFilter instance properties to adjust to grid layout mode\n * @private\n */\n setOverrides() {\n let tf = this.tf;\n tf.refRow = 0;\n tf.headersRow = 0;\n tf.filtersRowIndex = 1;\n tf.isExternalFlt = true;\n }\n\n /**\n * Set grid-layout default column widths if column widths are not defined\n * @private\n */\n setDefaultColWidths() {\n let tf = this.tf;\n if (tf.hasColWidths) {\n return;\n }\n for (let k = 0, len = tf.getCellsNb(); k < len; k++) {\n let colW;\n let cell = tf.tbl.rows[tf.getHeadersRowIndex()].cells[k];\n if (cell.width !== '') {\n colW = cell.width;\n } else if (cell.style.width !== '') {\n colW = parseInt(cell.style.width, 10);\n } else {\n colW = this.defaultColWidth;\n }\n tf.colWidths[k] = colW;\n }\n tf.hasColWidths = true;\n tf.setColWidths();\n }\n\n /**\n * Initial table width\n * @returns {Number}\n * @private\n */\n initialTableWidth() {\n let tbl = this.tf.tbl;\n let width; //initial table width\n\n if (tbl.width !== '') {\n width = tbl.width;\n }\n else if (tbl.style.width !== '') {\n width = tbl.style.width;\n } else {\n width = tbl.clientWidth;\n }\n return parseInt(width, 10);\n }\n\n /**\n * Creates container element\n * @param {String} id Element ID\n * @param {String} tag Tag name\n * @param {String} className Css class to assign to element\n * @returns {DOMElement}\n * @private\n */\n createContainer(id, tag, className) {\n let element = createElm(tag, ['id', id]);\n element.className = className;\n return element;\n }\n\n /**\n * Creates filters row with cells\n * @returns {HTMLTableRowElement}\n * @private\n */\n createFiltersRow() {\n let tf = this.tf;\n let filtersRow = createElm('tr');\n if (this.enableFilters && tf.fltGrid) {\n tf.externalFltTgtIds = [];\n for (let j = 0; j < tf.getCellsNb(); j++) {\n let fltTdId = tf.prfxFlt + j + this.prfxGridFltTd + tf.id;\n let cl = createElm(tf.fltCellTag, ['id', fltTdId]);\n filtersRow.appendChild(cl);\n tf.externalFltTgtIds[j] = fltTdId;\n }\n }\n return filtersRow;\n }\n\n /**\n * Generates column elements if necessary and assigns their widths\n * @private\n */\n setColumnElements() {\n let tf = this.tf;\n let cols = tag(tf.tbl, 'col');\n this.tblHasColTag = cols.length > 0;\n\n for (let k = (tf.nbCells - 1); k >= 0; k--) {\n let col;\n let id = `${tf.id}_col_${k}`;\n\n if (!this.tblHasColTag) {\n col = createElm('col', ['id', id]);\n tf.tbl.insertBefore(col, tf.tbl.firstChild);\n } else {\n col = cols[k];\n col.setAttribute('id', id);\n }\n col.style.width = tf.colWidths[k];\n this.colElms[k] = col;\n }\n this.tblHasColTag = true;\n }\n\n /**\n * Sets headers row in headers table\n * @param {HTMLHeadElement} tableHead Table head element\n * @private\n */\n setHeadersRow(tableHead) {\n if (this.noHeaders) {\n // Handle table with no headers, assuming here headers do not\n // exist\n tableHead.appendChild(createElm('tr'));\n } else {\n // Headers row are moved from content table to headers table\n for (let i = 0; i < this.headRows.length; i++) {\n let row = this.tf.tbl.rows[this.headRows[i]];\n tableHead.appendChild(row);\n }\n }\n }\n\n /**\n * Sets width defined in configuration to passed element\n * @param {DOMElement} element DOM element\n * @private\n */\n setConfigWidth(element) {\n if (!this.width) {\n return;\n }\n if (this.width.indexOf('%') !== -1) {\n element.style.width = '100%';\n } else {\n element.style.width = this.width;\n }\n }\n\n /**\n * Returns a list of header IDs used for specifing external sort triggers\n * @param {HTMLTableRowElement} row DOM row element\n * @returns {Array} List of IDs\n * @private\n */\n getSortTriggerIds(row) {\n let tf = this.tf;\n let sortTriggers = [];\n for (let n = 0; n < tf.getCellsNb(); n++) {\n let c = row.cells[n];\n let thId = c.getAttribute('id');\n if (!thId || thId === '') {\n thId = this.prfxGridTh + n + '_' + tf.id;\n c.setAttribute('id', thId);\n }\n sortTriggers.push(thId);\n }\n return sortTriggers;\n }\n\n /**\n * Removes the grid layout\n */\n destroy() {\n let tf = this.tf;\n let tbl = tf.tbl;\n\n if (!this.initialized) {\n return;\n }\n let t = removeElm(tbl);\n this.tblMainCont.parentNode.insertBefore(t, this.tblMainCont);\n removeElm(this.tblMainCont);\n\n this.tblMainCont = null;\n this.headTblCont = null;\n this.headTbl = null;\n this.tblCont = null;\n\n tbl.outerHTML = this.sourceTblHtml;\n //needed to keep reference of table element for future usage\n this.tf.tbl = elm(tf.id);\n\n this.initialized = false;\n }\n}\n"
},
{
- "__docId__": 345,
+ "__docId__": 346,
"kind": "class",
"static": true,
"variation": null,
@@ -7536,7 +7574,7 @@
]
},
{
- "__docId__": 346,
+ "__docId__": 347,
"kind": "constructor",
"static": false,
"variation": null,
@@ -7561,7 +7599,7 @@
"generator": false
},
{
- "__docId__": 347,
+ "__docId__": 348,
"kind": "member",
"static": false,
"variation": null,
@@ -7581,7 +7619,7 @@
}
},
{
- "__docId__": 348,
+ "__docId__": 349,
"kind": "member",
"static": false,
"variation": null,
@@ -7601,7 +7639,7 @@
}
},
{
- "__docId__": 349,
+ "__docId__": 350,
"kind": "member",
"static": false,
"variation": null,
@@ -7621,7 +7659,7 @@
}
},
{
- "__docId__": 350,
+ "__docId__": 351,
"kind": "member",
"static": false,
"variation": null,
@@ -7641,7 +7679,7 @@
}
},
{
- "__docId__": 351,
+ "__docId__": 352,
"kind": "member",
"static": false,
"variation": null,
@@ -7661,7 +7699,7 @@
}
},
{
- "__docId__": 352,
+ "__docId__": 353,
"kind": "member",
"static": false,
"variation": null,
@@ -7681,7 +7719,7 @@
}
},
{
- "__docId__": 353,
+ "__docId__": 354,
"kind": "member",
"static": false,
"variation": null,
@@ -7701,7 +7739,7 @@
}
},
{
- "__docId__": 354,
+ "__docId__": 355,
"kind": "member",
"static": false,
"variation": null,
@@ -7721,7 +7759,7 @@
}
},
{
- "__docId__": 355,
+ "__docId__": 356,
"kind": "member",
"static": false,
"variation": null,
@@ -7741,7 +7779,7 @@
}
},
{
- "__docId__": 356,
+ "__docId__": 357,
"kind": "member",
"static": false,
"variation": null,
@@ -7761,7 +7799,7 @@
}
},
{
- "__docId__": 357,
+ "__docId__": 358,
"kind": "member",
"static": false,
"variation": null,
@@ -7781,7 +7819,7 @@
}
},
{
- "__docId__": 358,
+ "__docId__": 359,
"kind": "member",
"static": false,
"variation": null,
@@ -7801,7 +7839,7 @@
}
},
{
- "__docId__": 359,
+ "__docId__": 360,
"kind": "member",
"static": false,
"variation": null,
@@ -7821,7 +7859,7 @@
}
},
{
- "__docId__": 360,
+ "__docId__": 361,
"kind": "member",
"static": false,
"variation": null,
@@ -7841,7 +7879,7 @@
}
},
{
- "__docId__": 361,
+ "__docId__": 362,
"kind": "member",
"static": false,
"variation": null,
@@ -7861,7 +7899,7 @@
}
},
{
- "__docId__": 362,
+ "__docId__": 363,
"kind": "member",
"static": false,
"variation": null,
@@ -7881,7 +7919,7 @@
}
},
{
- "__docId__": 363,
+ "__docId__": 364,
"kind": "member",
"static": false,
"variation": null,
@@ -7901,7 +7939,7 @@
}
},
{
- "__docId__": 364,
+ "__docId__": 365,
"kind": "member",
"static": false,
"variation": null,
@@ -7921,7 +7959,7 @@
}
},
{
- "__docId__": 365,
+ "__docId__": 366,
"kind": "member",
"static": false,
"variation": null,
@@ -7941,7 +7979,7 @@
}
},
{
- "__docId__": 366,
+ "__docId__": 367,
"kind": "member",
"static": false,
"variation": null,
@@ -7961,7 +7999,7 @@
}
},
{
- "__docId__": 367,
+ "__docId__": 368,
"kind": "method",
"static": false,
"variation": null,
@@ -7975,7 +8013,7 @@
"generator": false
},
{
- "__docId__": 368,
+ "__docId__": 369,
"kind": "member",
"static": false,
"variation": null,
@@ -7993,7 +8031,7 @@
}
},
{
- "__docId__": 369,
+ "__docId__": 370,
"kind": "member",
"static": false,
"variation": null,
@@ -8011,7 +8049,7 @@
}
},
{
- "__docId__": 370,
+ "__docId__": 371,
"kind": "member",
"static": false,
"variation": null,
@@ -8029,7 +8067,7 @@
}
},
{
- "__docId__": 371,
+ "__docId__": 372,
"kind": "member",
"static": false,
"variation": null,
@@ -8047,7 +8085,7 @@
}
},
{
- "__docId__": 372,
+ "__docId__": 373,
"kind": "member",
"static": false,
"variation": null,
@@ -8070,7 +8108,7 @@
}
},
{
- "__docId__": 373,
+ "__docId__": 374,
"kind": "method",
"static": false,
"variation": null,
@@ -8084,7 +8122,7 @@
"generator": false
},
{
- "__docId__": 374,
+ "__docId__": 375,
"kind": "method",
"static": false,
"variation": null,
@@ -8098,7 +8136,7 @@
"generator": false
},
{
- "__docId__": 375,
+ "__docId__": 376,
"kind": "method",
"static": false,
"variation": null,
@@ -8126,7 +8164,7 @@
"generator": false
},
{
- "__docId__": 376,
+ "__docId__": 377,
"kind": "method",
"static": false,
"variation": null,
@@ -8185,7 +8223,7 @@
"generator": false
},
{
- "__docId__": 377,
+ "__docId__": 378,
"kind": "method",
"static": false,
"variation": null,
@@ -8213,7 +8251,7 @@
"generator": false
},
{
- "__docId__": 378,
+ "__docId__": 379,
"kind": "method",
"static": false,
"variation": null,
@@ -8227,7 +8265,7 @@
"generator": false
},
{
- "__docId__": 379,
+ "__docId__": 380,
"kind": "member",
"static": false,
"variation": null,
@@ -8245,7 +8283,7 @@
}
},
{
- "__docId__": 380,
+ "__docId__": 381,
"kind": "member",
"static": false,
"variation": null,
@@ -8263,7 +8301,7 @@
}
},
{
- "__docId__": 381,
+ "__docId__": 382,
"kind": "method",
"static": false,
"variation": null,
@@ -8288,7 +8326,7 @@
"generator": false
},
{
- "__docId__": 382,
+ "__docId__": 383,
"kind": "method",
"static": false,
"variation": null,
@@ -8313,7 +8351,7 @@
"generator": false
},
{
- "__docId__": 383,
+ "__docId__": 384,
"kind": "method",
"static": false,
"variation": null,
@@ -8352,7 +8390,7 @@
"generator": false
},
{
- "__docId__": 384,
+ "__docId__": 385,
"kind": "method",
"static": false,
"variation": null,
@@ -8366,7 +8404,7 @@
"generator": false
},
{
- "__docId__": 385,
+ "__docId__": 386,
"kind": "member",
"static": false,
"variation": null,
@@ -8384,7 +8422,7 @@
}
},
{
- "__docId__": 386,
+ "__docId__": 387,
"kind": "member",
"static": false,
"variation": null,
@@ -8402,7 +8440,7 @@
}
},
{
- "__docId__": 387,
+ "__docId__": 388,
"kind": "member",
"static": false,
"variation": null,
@@ -8420,7 +8458,7 @@
}
},
{
- "__docId__": 388,
+ "__docId__": 389,
"kind": "member",
"static": false,
"variation": null,
@@ -8438,7 +8476,7 @@
}
},
{
- "__docId__": 389,
+ "__docId__": 390,
"kind": "member",
"static": false,
"variation": null,
@@ -8456,7 +8494,7 @@
}
},
{
- "__docId__": 390,
+ "__docId__": 391,
"kind": "file",
"static": true,
"variation": null,
@@ -8469,7 +8507,7 @@
"content": "import {addEvt, removeEvt} from '../event';\nimport {root} from '../root';\n\nconst JSON = root.JSON;\nconst location = root.location;\nconst decodeURIComponent = root.decodeURIComponent;\nconst encodeURIComponent = root.encodeURIComponent;\n\n/**\n * Checks if browser has onhashchange event\n */\nexport const hasHashChange = () => {\n let docMode = root.documentMode;\n return ('onhashchange' in root) && (docMode === undefined || docMode > 7);\n};\n\n/**\n * Manages state via URL hash changes\n *\n * @export\n * @class Hash\n */\nexport class Hash {\n\n /**\n * Creates an instance of Hash\n *\n * @param {State} state Instance of State\n */\n constructor(state) {\n /**\n * State object\n * @type {State}\n */\n this.state = state;\n\n /**\n * Cached URL hash\n * @type {String} Hash string\n * @private\n */\n this.lastHash = null;\n\n /**\n * Application event emitter instance\n * @type {Emitter}\n */\n this.emitter = state.emitter;\n\n /**\n * Bound sync wrapper for future use\n * @private\n */\n this.boundSync = null;\n }\n\n /**\n * Initializes the Hash object\n */\n init() {\n if (!hasHashChange()) {\n return;\n }\n\n this.lastHash = location.hash;\n //Store a bound sync wrapper\n this.boundSync = this.sync.bind(this);\n this.emitter.on(['state-changed'], (tf, state) => this.update(state));\n this.emitter.on(['initialized'], this.boundSync);\n addEvt(root, 'hashchange', this.boundSync);\n }\n\n /**\n * Updates the URL hash based on a state change\n *\n * @param {State} state Instance of State\n */\n update(state) {\n let hash = `#${encodeURIComponent(JSON.stringify(state))}`;\n if (this.lastHash === hash) {\n return;\n }\n\n location.hash = hash;\n this.lastHash = hash;\n }\n\n /**\n * Converts a URL hash into a state JSON object\n *\n * @param {String} hash URL hash fragment\n * @returns {Object} JSON object\n */\n parse(hash) {\n if (hash.indexOf('#') === -1) {\n return null;\n }\n hash = hash.substr(1);\n return JSON.parse(decodeURIComponent(hash));\n }\n\n /**\n * Applies current hash state to features\n */\n sync() {\n let state = this.parse(location.hash);\n if (!state) {\n return;\n }\n // override current state with persisted one and sync features\n this.state.overrideAndSync(state);\n }\n\n /**\n * Release Hash event subscriptions and clear fields\n */\n destroy() {\n this.emitter.off(['state-changed'], (tf, state) => this.update(state));\n this.emitter.off(['initialized'], this.boundSync);\n removeEvt(root, 'hashchange', this.boundSync);\n\n this.state = null;\n this.lastHash = null;\n this.emitter = null;\n }\n}\n"
},
{
- "__docId__": 391,
+ "__docId__": 392,
"kind": "variable",
"static": true,
"variation": null,
@@ -8490,7 +8528,7 @@
}
},
{
- "__docId__": 392,
+ "__docId__": 393,
"kind": "variable",
"static": true,
"variation": null,
@@ -8511,7 +8549,7 @@
}
},
{
- "__docId__": 393,
+ "__docId__": 394,
"kind": "variable",
"static": true,
"variation": null,
@@ -8532,7 +8570,7 @@
}
},
{
- "__docId__": 394,
+ "__docId__": 395,
"kind": "variable",
"static": true,
"variation": null,
@@ -8553,7 +8591,7 @@
}
},
{
- "__docId__": 395,
+ "__docId__": 396,
"kind": "variable",
"static": true,
"variation": null,
@@ -8573,7 +8611,7 @@
}
},
{
- "__docId__": 396,
+ "__docId__": 397,
"kind": "class",
"static": true,
"variation": null,
@@ -8599,7 +8637,7 @@
"interface": false
},
{
- "__docId__": 397,
+ "__docId__": 398,
"kind": "constructor",
"static": false,
"variation": null,
@@ -8624,7 +8662,7 @@
"generator": false
},
{
- "__docId__": 398,
+ "__docId__": 399,
"kind": "member",
"static": false,
"variation": null,
@@ -8644,7 +8682,7 @@
}
},
{
- "__docId__": 399,
+ "__docId__": 400,
"kind": "member",
"static": false,
"variation": null,
@@ -8664,7 +8702,7 @@
}
},
{
- "__docId__": 400,
+ "__docId__": 401,
"kind": "member",
"static": false,
"variation": null,
@@ -8684,7 +8722,7 @@
}
},
{
- "__docId__": 401,
+ "__docId__": 402,
"kind": "member",
"static": false,
"variation": null,
@@ -8701,7 +8739,7 @@
}
},
{
- "__docId__": 402,
+ "__docId__": 403,
"kind": "method",
"static": false,
"variation": null,
@@ -8715,7 +8753,7 @@
"generator": false
},
{
- "__docId__": 403,
+ "__docId__": 404,
"kind": "member",
"static": false,
"variation": null,
@@ -8733,7 +8771,7 @@
}
},
{
- "__docId__": 404,
+ "__docId__": 405,
"kind": "member",
"static": false,
"variation": null,
@@ -8751,7 +8789,7 @@
}
},
{
- "__docId__": 405,
+ "__docId__": 406,
"kind": "method",
"static": false,
"variation": null,
@@ -8776,7 +8814,7 @@
"generator": false
},
{
- "__docId__": 406,
+ "__docId__": 407,
"kind": "member",
"static": false,
"variation": null,
@@ -8794,7 +8832,7 @@
}
},
{
- "__docId__": 407,
+ "__docId__": 408,
"kind": "method",
"static": false,
"variation": null,
@@ -8833,7 +8871,7 @@
"generator": false
},
{
- "__docId__": 408,
+ "__docId__": 409,
"kind": "method",
"static": false,
"variation": null,
@@ -8847,7 +8885,7 @@
"generator": false
},
{
- "__docId__": 409,
+ "__docId__": 410,
"kind": "method",
"static": false,
"variation": null,
@@ -8861,7 +8899,7 @@
"generator": false
},
{
- "__docId__": 410,
+ "__docId__": 411,
"kind": "member",
"static": false,
"variation": null,
@@ -8879,7 +8917,7 @@
}
},
{
- "__docId__": 411,
+ "__docId__": 412,
"kind": "member",
"static": false,
"variation": null,
@@ -8897,7 +8935,7 @@
}
},
{
- "__docId__": 412,
+ "__docId__": 413,
"kind": "member",
"static": false,
"variation": null,
@@ -8915,7 +8953,7 @@
}
},
{
- "__docId__": 413,
+ "__docId__": 414,
"kind": "file",
"static": true,
"variation": null,
@@ -8928,7 +8966,7 @@
"content": "import {Feature} from '../feature';\nimport {createElm, createText, elm, removeElm} from '../dom';\nimport {addEvt} from '../event';\nimport {NONE} from '../const';\n\nconst WIKI_URL = 'https://github.com/koalyptus/TableFilter/wiki/' +\n '4.-Filter-operators';\nconst WEBSITE_URL = 'http://koalyptus.github.io/TableFilter/';\n\n/**\n * Help UI component\n */\nexport class Help extends Feature {\n\n /**\n * Creates an instance of Help.\n * @param {TableFilter} tf TableFilter instance\n */\n constructor(tf) {\n super(tf, 'help');\n\n var f = this.config;\n\n /**\n * ID of main custom container element\n * @type {String}\n */\n this.tgtId = f.help_instructions_target_id || null;\n\n /**\n * ID of custom container element for instructions\n * @type {String}\n */\n this.contTgtId = f.help_instructions_container_target_id ||\n null;\n\n /**\n * Instructions text (accepts HTML)\n * @type {String}\n */\n this.instrText = f.help_instructions_text ?\n f.help_instructions_text :\n 'Use the filters above each column to filter and limit table ' +\n 'data. Advanced searches can be performed by using the following ' +\n 'operators: <, <=, >, ' +\n ' >=, =, *, !, {, }, ' +\n ' ||, &&, [empty], [nonempty], ' +\n ' rgx:' +\n 'Learn more
';\n\n /**\n * Instructions HTML\n * @type {String}\n */\n this.instrHtml = f.help_instructions_html || null;\n\n /**\n * Help button text ('?')\n * @type {String}\n */\n this.btnText = f.help_instructions_btn_text || '?';\n\n /**\n * Custom help button HTML\n * @type {String}\n */\n this.btnHtml = f.help_instructions_btn_html || null;\n\n /**\n * Css class for help button\n * @type {String}\n */\n this.btnCssClass = f.help_instructions_btn_css_class || 'helpBtn';\n\n /**\n * Css class for help container element\n * @type {String}\n */\n this.contCssClass = f.help_instructions_container_css_class ||\n 'helpCont';\n\n /**\n * Stores button DOM element\n * @type {DOMElement}\n */\n this.btn = null;\n\n /**\n * Stores help container DOM element\n * @type {DOMElement}\n */\n this.cont = null;\n\n /**\n * Default HTML appended to instructions text\n * @type {String}\n */\n this.defaultHtml = '';\n\n /**\n * Prefix for help main container ID\n * @type {String}\n * @private\n */\n this.prfxHelpSpan = 'helpSpan_';\n\n /**\n * Prefix for help instructions container ID\n * @type {String}\n * @private\n */\n this.prfxHelpDiv = 'helpDiv_';\n\n this.emitter.on(['init-help'], () => this.init());\n }\n\n /**\n * Initialise Help instance\n */\n init() {\n if (this.initialized) {\n return;\n }\n\n var tf = this.tf;\n\n var helpspan = createElm('span', ['id', this.prfxHelpSpan + tf.id]);\n var helpdiv = createElm('div', ['id', this.prfxHelpDiv + tf.id]);\n\n //help button is added to defined element\n if (!this.tgtId) {\n tf.setToolbar();\n }\n var targetEl = !this.tgtId ? tf.rDiv : elm(this.tgtId);\n targetEl.appendChild(helpspan);\n\n var divContainer = !this.contTgtId ? helpspan : elm(this.contTgtId);\n\n if (!this.btnHtml) {\n divContainer.appendChild(helpdiv);\n var helplink = createElm('a', ['href', 'javascript:void(0);']);\n helplink.className = this.btnCssClass;\n helplink.appendChild(createText(this.btnText));\n helpspan.appendChild(helplink);\n addEvt(helplink, 'click', () => this.toggle());\n } else {\n helpspan.innerHTML = this.btnHtml;\n var helpEl = helpspan.firstChild;\n addEvt(helpEl, 'click', () => this.toggle());\n divContainer.appendChild(helpdiv);\n }\n\n if (!this.instrHtml) {\n helpdiv.innerHTML = this.instrText;\n helpdiv.className = this.contCssClass;\n addEvt(helpdiv, 'dblclick', () => this.toggle());\n } else {\n if (this.contTgtId) {\n divContainer.appendChild(helpdiv);\n }\n helpdiv.innerHTML = this.instrHtml;\n if (!this.contTgtId) {\n helpdiv.className = this.contCssClass;\n addEvt(helpdiv, 'dblclick', () => this.toggle());\n }\n }\n helpdiv.innerHTML += this.defaultHtml;\n addEvt(helpdiv, 'click', () => this.toggle());\n\n this.cont = helpdiv;\n this.btn = helpspan;\n /**\n * @inherited\n */\n this.initialized = true;\n }\n\n /**\n * Toggle help pop-up\n */\n toggle() {\n // check only if explicitily set to false as in this case undefined\n // signifies the help feature is enabled by default\n if (this.enabled === false) {\n return;\n }\n var divDisplay = this.cont.style.display;\n if (divDisplay === '' || divDisplay === NONE) {\n this.cont.style.display = 'inline';\n } else {\n this.cont.style.display = NONE;\n }\n }\n\n /**\n * Remove help UI\n */\n destroy() {\n if (!this.initialized) {\n return;\n }\n removeElm(this.btn);\n this.btn = null;\n if (!this.cont) {\n return;\n }\n removeElm(this.cont);\n this.cont = null;\n this.initialized = false;\n }\n\n}\n"
},
{
- "__docId__": 414,
+ "__docId__": 415,
"kind": "variable",
"static": true,
"variation": null,
@@ -8949,7 +8987,7 @@
}
},
{
- "__docId__": 415,
+ "__docId__": 416,
"kind": "variable",
"static": true,
"variation": null,
@@ -8970,7 +9008,7 @@
}
},
{
- "__docId__": 416,
+ "__docId__": 417,
"kind": "class",
"static": true,
"variation": null,
@@ -8989,7 +9027,7 @@
]
},
{
- "__docId__": 417,
+ "__docId__": 418,
"kind": "constructor",
"static": false,
"variation": null,
@@ -9014,7 +9052,7 @@
"generator": false
},
{
- "__docId__": 418,
+ "__docId__": 419,
"kind": "member",
"static": false,
"variation": null,
@@ -9034,7 +9072,7 @@
}
},
{
- "__docId__": 419,
+ "__docId__": 420,
"kind": "member",
"static": false,
"variation": null,
@@ -9054,7 +9092,7 @@
}
},
{
- "__docId__": 420,
+ "__docId__": 421,
"kind": "member",
"static": false,
"variation": null,
@@ -9074,7 +9112,7 @@
}
},
{
- "__docId__": 421,
+ "__docId__": 422,
"kind": "member",
"static": false,
"variation": null,
@@ -9094,7 +9132,7 @@
}
},
{
- "__docId__": 422,
+ "__docId__": 423,
"kind": "member",
"static": false,
"variation": null,
@@ -9114,7 +9152,7 @@
}
},
{
- "__docId__": 423,
+ "__docId__": 424,
"kind": "member",
"static": false,
"variation": null,
@@ -9134,7 +9172,7 @@
}
},
{
- "__docId__": 424,
+ "__docId__": 425,
"kind": "member",
"static": false,
"variation": null,
@@ -9154,7 +9192,7 @@
}
},
{
- "__docId__": 425,
+ "__docId__": 426,
"kind": "member",
"static": false,
"variation": null,
@@ -9174,7 +9212,7 @@
}
},
{
- "__docId__": 426,
+ "__docId__": 427,
"kind": "member",
"static": false,
"variation": null,
@@ -9194,7 +9232,7 @@
}
},
{
- "__docId__": 427,
+ "__docId__": 428,
"kind": "member",
"static": false,
"variation": null,
@@ -9214,7 +9252,7 @@
}
},
{
- "__docId__": 428,
+ "__docId__": 429,
"kind": "member",
"static": false,
"variation": null,
@@ -9234,7 +9272,7 @@
}
},
{
- "__docId__": 429,
+ "__docId__": 430,
"kind": "member",
"static": false,
"variation": null,
@@ -9254,7 +9292,7 @@
}
},
{
- "__docId__": 430,
+ "__docId__": 431,
"kind": "member",
"static": false,
"variation": null,
@@ -9274,7 +9312,7 @@
}
},
{
- "__docId__": 431,
+ "__docId__": 432,
"kind": "method",
"static": false,
"variation": null,
@@ -9288,7 +9326,7 @@
"generator": false
},
{
- "__docId__": 432,
+ "__docId__": 433,
"kind": "member",
"static": false,
"variation": null,
@@ -9306,7 +9344,7 @@
}
},
{
- "__docId__": 433,
+ "__docId__": 434,
"kind": "member",
"static": false,
"variation": null,
@@ -9324,7 +9362,7 @@
}
},
{
- "__docId__": 434,
+ "__docId__": 435,
"kind": "member",
"static": false,
"variation": null,
@@ -9347,7 +9385,7 @@
}
},
{
- "__docId__": 435,
+ "__docId__": 436,
"kind": "method",
"static": false,
"variation": null,
@@ -9361,7 +9399,7 @@
"generator": false
},
{
- "__docId__": 436,
+ "__docId__": 437,
"kind": "method",
"static": false,
"variation": null,
@@ -9375,7 +9413,7 @@
"generator": false
},
{
- "__docId__": 437,
+ "__docId__": 438,
"kind": "member",
"static": false,
"variation": null,
@@ -9393,7 +9431,7 @@
}
},
{
- "__docId__": 438,
+ "__docId__": 439,
"kind": "member",
"static": false,
"variation": null,
@@ -9411,7 +9449,7 @@
}
},
{
- "__docId__": 439,
+ "__docId__": 440,
"kind": "member",
"static": false,
"variation": null,
@@ -9429,7 +9467,7 @@
}
},
{
- "__docId__": 440,
+ "__docId__": 441,
"kind": "file",
"static": true,
"variation": null,
@@ -9442,7 +9480,7 @@
"content": "import {createText, createElm, getText} from '../dom';\nimport {isArray} from '../types';\n\n/**\n * Highlight matched keywords upon filtering\n *\n * @export\n * @class HighlightKeyword\n */\nexport class HighlightKeyword {\n\n /**\n * Creates an instance of HighlightKeyword\n * @param {TableFilter} tf TableFilter instance\n */\n constructor(tf) {\n let f = tf.config();\n\n /**\n * Css class for highlighted term\n * @type {String}\n */\n this.highlightCssClass = f.highlight_css_class || 'keyword';\n\n /**\n * TableFilter instance\n * @type {TableFilter}\n */\n this.tf = tf;\n\n /**\n * TableFilter's emitter instance\n * @type {Emitter}\n */\n this.emitter = tf.emitter;\n }\n\n /**\n * Initializes HighlightKeyword instance\n */\n init() {\n this.emitter.on(\n ['before-filtering', 'destroy'],\n () => this.unhighlightAll()\n );\n this.emitter.on(\n ['highlight-keyword'],\n (tf, cell, word) =>\n this.highlight(cell, word, this.highlightCssClass)\n );\n }\n\n /**\n * Highlight occurences of searched term in passed node\n * @param {Node} node\n * @param {String} word Searched term\n * @param {String} cssClass Css class name\n *\n * TODO: refactor this method\n */\n highlight(node, word, cssClass) {\n // Iterate into this nodes childNodes\n if (node.hasChildNodes) {\n let children = node.childNodes;\n for (let i = 0; i < children.length; i++) {\n this.highlight(children[i], word, cssClass);\n }\n }\n\n if (node.nodeType === 3) {\n let tempNodeVal = node.nodeValue.toLowerCase();\n let tempWordVal = word.toLowerCase();\n if (tempNodeVal.indexOf(tempWordVal) !== -1) {\n let pn = node.parentNode;\n if (pn && pn.className !== cssClass) {\n // word not highlighted yet\n let nv = node.nodeValue,\n ni = tempNodeVal.indexOf(tempWordVal),\n // Create a load of replacement nodes\n before = createText(nv.substr(0, ni)),\n docWordVal = nv.substr(ni, word.length),\n after = createText(nv.substr(ni + word.length)),\n hiwordtext = createText(docWordVal),\n hiword = createElm('span');\n hiword.className = cssClass;\n hiword.appendChild(hiwordtext);\n pn.insertBefore(before, node);\n pn.insertBefore(hiword, node);\n pn.insertBefore(after, node);\n pn.removeChild(node);\n }\n }\n }\n }\n\n /**\n * Removes highlight to nodes matching passed string\n * @param {String} word\n * @param {String} cssClass Css class to remove\n */\n unhighlight(word, cssClass) {\n let highlightedNodes = this.tf.tbl.querySelectorAll(`.${cssClass}`);\n for (let i = 0; i < highlightedNodes.length; i++) {\n let n = highlightedNodes[i];\n let nodeVal = getText(n),\n tempNodeVal = nodeVal.toLowerCase(),\n tempWordVal = word.toLowerCase();\n\n if (tempNodeVal.indexOf(tempWordVal) !== -1) {\n n.parentNode.replaceChild(createText(nodeVal), n);\n }\n }\n }\n\n /**\n * Clear all occurrences of highlighted nodes\n */\n unhighlightAll() {\n if (!this.tf.highlightKeywords) {\n return;\n }\n // iterate filters values to unhighlight all values\n this.tf.getFiltersValue().forEach((val) => {\n if (isArray(val)) {\n val.forEach((item) =>\n this.unhighlight(item, this.highlightCssClass));\n } else {\n this.unhighlight(val, this.highlightCssClass);\n }\n });\n }\n\n /**\n * Remove feature\n */\n destroy() {\n this.emitter.off(\n ['before-filtering', 'destroy'],\n () => this.unhighlightAll()\n );\n this.emitter.off(\n ['highlight-keyword'],\n (tf, cell, word) =>\n this.highlight(cell, word, this.highlightCssClass)\n );\n }\n}\n"
},
{
- "__docId__": 441,
+ "__docId__": 442,
"kind": "class",
"static": true,
"variation": null,
@@ -9468,7 +9506,7 @@
"interface": false
},
{
- "__docId__": 442,
+ "__docId__": 443,
"kind": "constructor",
"static": false,
"variation": null,
@@ -9493,7 +9531,7 @@
"generator": false
},
{
- "__docId__": 443,
+ "__docId__": 444,
"kind": "member",
"static": false,
"variation": null,
@@ -9513,7 +9551,7 @@
}
},
{
- "__docId__": 444,
+ "__docId__": 445,
"kind": "member",
"static": false,
"variation": null,
@@ -9533,7 +9571,7 @@
}
},
{
- "__docId__": 445,
+ "__docId__": 446,
"kind": "member",
"static": false,
"variation": null,
@@ -9553,7 +9591,7 @@
}
},
{
- "__docId__": 446,
+ "__docId__": 447,
"kind": "method",
"static": false,
"variation": null,
@@ -9567,7 +9605,7 @@
"generator": false
},
{
- "__docId__": 447,
+ "__docId__": 448,
"kind": "method",
"static": false,
"variation": null,
@@ -9612,7 +9650,7 @@
"generator": false
},
{
- "__docId__": 448,
+ "__docId__": 449,
"kind": "method",
"static": false,
"variation": null,
@@ -9647,7 +9685,7 @@
"generator": false
},
{
- "__docId__": 449,
+ "__docId__": 450,
"kind": "method",
"static": false,
"variation": null,
@@ -9661,7 +9699,7 @@
"generator": false
},
{
- "__docId__": 450,
+ "__docId__": 451,
"kind": "method",
"static": false,
"variation": null,
@@ -9675,7 +9713,7 @@
"generator": false
},
{
- "__docId__": 451,
+ "__docId__": 452,
"kind": "file",
"static": true,
"variation": null,
@@ -9688,7 +9726,7 @@
"content": "import {Feature} from '../feature';\nimport {createElm, createText, elm, removeElm} from '../dom';\nimport {isFn} from '../types';\nimport {root} from '../root';\nimport {NONE} from '../const';\n\n/**\n * Activity indicator\n *\n * @export\n * @class Loader\n * @extends {Feature}\n */\nexport class Loader extends Feature {\n\n /**\n * Creates an instance of Loader.\n *\n * @param {TableFilter} tf TableFilter instance\n */\n constructor(tf) {\n super(tf, 'loader');\n\n let f = this.config;\n\n /**\n * ID of custom container element\n * @type {String}\n */\n this.targetId = f.loader_target_id || null;\n\n /**\n * Loader container DOM element\n * @type {DOMElement}\n */\n this.cont = null;\n\n /**\n * Text displayed when indicator is visible\n * @type {String}\n */\n this.text = f.loader_text || 'Loading...';\n\n /**\n * Custom HTML injected in Loader's container element\n * @type {String}\n */\n this.html = f.loader_html || null;\n\n /**\n * Css class for Loader's container element\n * @type {String}\n */\n this.cssClass = f.loader_css_class || 'loader';\n\n /**\n * Close delay in milliseconds\n * @type {Number}\n */\n this.closeDelay = 250;\n\n /**\n * Callback fired when loader is displayed\n * @type {Function}\n */\n this.onShow = isFn(f.on_show_loader) ? f.on_show_loader : null;\n\n /**\n * Callback fired when loader is closed\n * @type {Function}\n */\n this.onHide = isFn(f.on_hide_loader) ? f.on_hide_loader : null;\n\n /**\n * Prefix for container ID\n * @type {String}\n * @private\n */\n this.prfx = 'load_';\n }\n\n /**\n * Initializes Loader instance\n */\n init() {\n if (this.initialized) {\n return;\n }\n\n let tf = this.tf;\n let emitter = this.emitter;\n\n let containerDiv = createElm('div', ['id', this.prfx + tf.id]);\n containerDiv.className = this.cssClass;\n\n let targetEl = !this.targetId ?\n tf.tbl.parentNode : elm(this.targetId);\n if (!this.targetId) {\n targetEl.insertBefore(containerDiv, tf.tbl);\n } else {\n targetEl.appendChild(containerDiv);\n }\n this.cont = containerDiv;\n if (!this.html) {\n this.cont.appendChild(createText(this.text));\n } else {\n this.cont.innerHTML = this.html;\n }\n\n this.show(NONE);\n\n // Subscribe to events\n emitter.on([\n 'before-filtering',\n 'before-populating-filter',\n 'before-page-change',\n 'before-clearing-filters',\n 'before-page-length-change',\n 'before-reset-page',\n 'before-reset-page-length',\n 'before-loading-extensions',\n 'before-loading-themes'],\n () => this.show('')\n );\n emitter.on([\n 'after-filtering',\n 'after-populating-filter',\n 'after-page-change',\n 'after-clearing-filters',\n 'after-page-length-change',\n 'after-reset-page',\n 'after-reset-page-length',\n 'after-loading-extensions',\n 'after-loading-themes'],\n () => this.show(NONE)\n );\n\n /**\n * @inherited\n */\n this.initialized = true;\n }\n\n /**\n * Shows or hides activity indicator\n * @param {String} Two possible values: '' or 'none'\n */\n show(p) {\n if (!this.isEnabled()) {\n return;\n }\n\n let displayLoader = () => {\n if (!this.cont) {\n return;\n }\n if (this.onShow && p !== NONE) {\n this.onShow.call(null, this);\n }\n this.cont.style.display = p;\n if (this.onHide && p === NONE) {\n this.onHide.call(null, this);\n }\n };\n\n let t = p === NONE ? this.closeDelay : 1;\n root.setTimeout(displayLoader, t);\n }\n\n /**\n * Removes feature\n */\n destroy() {\n if (!this.initialized) {\n return;\n }\n\n let emitter = this.emitter;\n\n removeElm(this.cont);\n this.cont = null;\n\n // Unsubscribe to events\n emitter.off([\n 'before-filtering',\n 'before-populating-filter',\n 'before-page-change',\n 'before-clearing-filters',\n 'before-page-length-change',\n 'before-reset-page',\n 'before-reset-page-length',\n 'before-loading-extensions',\n 'before-loading-themes'],\n () => this.show('')\n );\n emitter.off([\n 'after-filtering',\n 'after-populating-filter',\n 'after-page-change',\n 'after-clearing-filters',\n 'after-page-length-change',\n 'after-reset-page',\n 'after-reset-page-length',\n 'after-loading-extensions',\n 'after-loading-themes'],\n () => this.show(NONE)\n );\n\n this.initialized = false;\n }\n}\n"
},
{
- "__docId__": 452,
+ "__docId__": 453,
"kind": "class",
"static": true,
"variation": null,
@@ -9717,7 +9755,7 @@
]
},
{
- "__docId__": 453,
+ "__docId__": 454,
"kind": "constructor",
"static": false,
"variation": null,
@@ -9742,7 +9780,7 @@
"generator": false
},
{
- "__docId__": 454,
+ "__docId__": 455,
"kind": "member",
"static": false,
"variation": null,
@@ -9762,7 +9800,7 @@
}
},
{
- "__docId__": 455,
+ "__docId__": 456,
"kind": "member",
"static": false,
"variation": null,
@@ -9782,7 +9820,7 @@
}
},
{
- "__docId__": 456,
+ "__docId__": 457,
"kind": "member",
"static": false,
"variation": null,
@@ -9802,7 +9840,7 @@
}
},
{
- "__docId__": 457,
+ "__docId__": 458,
"kind": "member",
"static": false,
"variation": null,
@@ -9822,7 +9860,7 @@
}
},
{
- "__docId__": 458,
+ "__docId__": 459,
"kind": "member",
"static": false,
"variation": null,
@@ -9842,7 +9880,7 @@
}
},
{
- "__docId__": 459,
+ "__docId__": 460,
"kind": "member",
"static": false,
"variation": null,
@@ -9862,7 +9900,7 @@
}
},
{
- "__docId__": 460,
+ "__docId__": 461,
"kind": "member",
"static": false,
"variation": null,
@@ -9882,7 +9920,7 @@
}
},
{
- "__docId__": 461,
+ "__docId__": 462,
"kind": "member",
"static": false,
"variation": null,
@@ -9902,7 +9940,7 @@
}
},
{
- "__docId__": 462,
+ "__docId__": 463,
"kind": "member",
"static": false,
"variation": null,
@@ -9922,7 +9960,7 @@
}
},
{
- "__docId__": 463,
+ "__docId__": 464,
"kind": "method",
"static": false,
"variation": null,
@@ -9936,7 +9974,7 @@
"generator": false
},
{
- "__docId__": 464,
+ "__docId__": 465,
"kind": "member",
"static": false,
"variation": null,
@@ -9954,7 +9992,7 @@
}
},
{
- "__docId__": 465,
+ "__docId__": 466,
"kind": "member",
"static": false,
"variation": null,
@@ -9977,7 +10015,7 @@
}
},
{
- "__docId__": 466,
+ "__docId__": 467,
"kind": "method",
"static": false,
"variation": null,
@@ -10002,7 +10040,7 @@
"generator": false
},
{
- "__docId__": 467,
+ "__docId__": 468,
"kind": "method",
"static": false,
"variation": null,
@@ -10016,7 +10054,7 @@
"generator": false
},
{
- "__docId__": 468,
+ "__docId__": 469,
"kind": "member",
"static": false,
"variation": null,
@@ -10034,7 +10072,7 @@
}
},
{
- "__docId__": 469,
+ "__docId__": 470,
"kind": "member",
"static": false,
"variation": null,
@@ -10052,7 +10090,7 @@
}
},
{
- "__docId__": 470,
+ "__docId__": 471,
"kind": "file",
"static": true,
"variation": null,
@@ -10065,7 +10103,7 @@
"content": "import {Feature} from '../feature';\nimport {createElm, elm, removeElm} from '../dom';\nimport {isEmpty, isFn} from '../types';\nimport {NONE} from '../const';\n\n/**\n * UI when filtering yields no matches\n * @export\n * @class NoResults\n * @extends {Feature}\n */\nexport class NoResults extends Feature {\n\n /**\n * Creates an instance of NoResults\n * @param {TableFilter} tf TableFilter instance\n */\n constructor(tf) {\n super(tf, 'noResults');\n\n //configuration object\n let f = this.config.no_results_message;\n\n /**\n * Text (accepts HTML)\n * @type {String}\n */\n this.content = f.content || 'No results';\n\n /**\n * Custom container DOM element\n * @type {DOMElement}\n */\n this.customContainer = f.custom_container || null;\n\n /**\n * ID of custom container element\n * @type {String}\n */\n this.customContainerId = f.custom_container_id || null;\n\n /**\n * Indicates if UI is contained in a external element\n * @type {Boolean}\n * @private\n */\n this.isExternal = !isEmpty(this.customContainer) ||\n !isEmpty(this.customContainerId);\n\n /**\n * Css class assigned to container element\n * @type {String}\n */\n this.cssClass = f.css_class || 'no-results';\n\n /**\n * Stores container DOM element\n * @type {DOMElement}\n */\n this.cont = null;\n\n /**\n * Callback fired before the message is displayed\n * @type {Function}\n */\n this.onBeforeShow = isFn(f.on_before_show_msg) ?\n f.on_before_show_msg : null;\n\n /**\n * Callback fired after the message is displayed\n * @type {Function}\n */\n this.onAfterShow = isFn(f.on_after_show_msg) ?\n f.on_after_show_msg : null;\n\n /**\n * Callback fired before the message is hidden\n * @type {Function}\n */\n this.onBeforeHide = isFn(f.on_before_hide_msg) ?\n f.on_before_hide_msg : null;\n\n /**\n * Callback fired after the message is hidden\n * @type {Function}\n */\n this.onAfterHide = isFn(f.on_after_hide_msg) ?\n f.on_after_hide_msg : null;\n\n /**\n * Prefix for container ID\n * @type {String}\n * @private\n */\n this.prfx = 'nores_';\n }\n\n /**\n * Initializes NoResults instance\n */\n init() {\n if (this.initialized) {\n return;\n }\n let tf = this.tf;\n let target = this.customContainer || elm(this.customContainerId) ||\n tf.tbl;\n\n //container\n let cont = createElm('div', ['id', this.prfx + tf.id]);\n cont.className = this.cssClass;\n cont.innerHTML = this.content;\n\n if (this.isExternal) {\n target.appendChild(cont);\n } else {\n target.parentNode.insertBefore(cont, target.nextSibling);\n }\n\n this.cont = cont;\n\n // subscribe to after-filtering event\n this.emitter.on(['after-filtering'], () => this.toggle());\n\n /**\n * @inherited\n */\n this.initialized = true;\n\n this.hide();\n }\n\n /**\n * Toggle no results message\n */\n toggle() {\n if (this.tf.getValidRowsNb() > 0) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n /**\n * Show no results message\n */\n show() {\n if (!this.initialized || !this.isEnabled()) {\n return;\n }\n\n if (this.onBeforeShow) {\n this.onBeforeShow.call(null, this.tf, this);\n }\n\n this.setWidth();\n this.cont.style.display = 'block';\n\n if (this.onAfterShow) {\n this.onAfterShow.call(null, this.tf, this);\n }\n }\n\n /**\n * Hide no results message\n */\n hide() {\n if (!this.initialized || !this.isEnabled()) {\n return;\n }\n\n if (this.onBeforeHide) {\n this.onBeforeHide.call(null, this.tf, this);\n }\n\n this.cont.style.display = NONE;\n\n if (this.onAfterHide) {\n this.onAfterHide.call(null, this.tf, this);\n }\n }\n\n /**\n * Sets no results container width\n * @private\n */\n setWidth() {\n if (!this.initialized || this.isExternal || !this.isEnabled()) {\n return;\n }\n let tf = this.tf;\n if (tf.gridLayout) {\n let gridLayout = tf.feature('gridLayout');\n this.cont.style.width = gridLayout.tblCont.clientWidth + 'px';\n } else {\n this.cont.style.width = (tf.tbl.tHead ? tf.tbl.tHead.clientWidth :\n tf.tbl.tBodies[0].clientWidth) + 'px';\n }\n }\n\n /**\n * Remove feature\n */\n destroy() {\n if (!this.initialized) {\n return;\n }\n removeElm(this.cont);\n this.cont = null;\n // unsubscribe to after-filtering event\n this.emitter.off(['after-filtering'], () => this.toggle());\n\n this.initialized = false;\n }\n}\n"
},
{
- "__docId__": 471,
+ "__docId__": 472,
"kind": "class",
"static": true,
"variation": null,
@@ -10094,7 +10132,7 @@
]
},
{
- "__docId__": 472,
+ "__docId__": 473,
"kind": "constructor",
"static": false,
"variation": null,
@@ -10119,7 +10157,7 @@
"generator": false
},
{
- "__docId__": 473,
+ "__docId__": 474,
"kind": "member",
"static": false,
"variation": null,
@@ -10139,7 +10177,7 @@
}
},
{
- "__docId__": 474,
+ "__docId__": 475,
"kind": "member",
"static": false,
"variation": null,
@@ -10159,7 +10197,7 @@
}
},
{
- "__docId__": 475,
+ "__docId__": 476,
"kind": "member",
"static": false,
"variation": null,
@@ -10179,7 +10217,7 @@
}
},
{
- "__docId__": 476,
+ "__docId__": 477,
"kind": "member",
"static": false,
"variation": null,
@@ -10199,7 +10237,7 @@
}
},
{
- "__docId__": 477,
+ "__docId__": 478,
"kind": "member",
"static": false,
"variation": null,
@@ -10219,7 +10257,7 @@
}
},
{
- "__docId__": 478,
+ "__docId__": 479,
"kind": "member",
"static": false,
"variation": null,
@@ -10239,7 +10277,7 @@
}
},
{
- "__docId__": 479,
+ "__docId__": 480,
"kind": "member",
"static": false,
"variation": null,
@@ -10259,7 +10297,7 @@
}
},
{
- "__docId__": 480,
+ "__docId__": 481,
"kind": "member",
"static": false,
"variation": null,
@@ -10279,7 +10317,7 @@
}
},
{
- "__docId__": 481,
+ "__docId__": 482,
"kind": "member",
"static": false,
"variation": null,
@@ -10299,7 +10337,7 @@
}
},
{
- "__docId__": 482,
+ "__docId__": 483,
"kind": "member",
"static": false,
"variation": null,
@@ -10319,7 +10357,7 @@
}
},
{
- "__docId__": 483,
+ "__docId__": 484,
"kind": "member",
"static": false,
"variation": null,
@@ -10339,7 +10377,7 @@
}
},
{
- "__docId__": 484,
+ "__docId__": 485,
"kind": "method",
"static": false,
"variation": null,
@@ -10353,7 +10391,7 @@
"generator": false
},
{
- "__docId__": 485,
+ "__docId__": 486,
"kind": "member",
"static": false,
"variation": null,
@@ -10371,7 +10409,7 @@
}
},
{
- "__docId__": 486,
+ "__docId__": 487,
"kind": "member",
"static": false,
"variation": null,
@@ -10394,7 +10432,7 @@
}
},
{
- "__docId__": 487,
+ "__docId__": 488,
"kind": "method",
"static": false,
"variation": null,
@@ -10408,7 +10446,7 @@
"generator": false
},
{
- "__docId__": 488,
+ "__docId__": 489,
"kind": "method",
"static": false,
"variation": null,
@@ -10422,7 +10460,7 @@
"generator": false
},
{
- "__docId__": 489,
+ "__docId__": 490,
"kind": "method",
"static": false,
"variation": null,
@@ -10436,7 +10474,7 @@
"generator": false
},
{
- "__docId__": 490,
+ "__docId__": 491,
"kind": "method",
"static": false,
"variation": null,
@@ -10450,7 +10488,7 @@
"generator": false
},
{
- "__docId__": 491,
+ "__docId__": 492,
"kind": "method",
"static": false,
"variation": null,
@@ -10464,7 +10502,7 @@
"generator": false
},
{
- "__docId__": 492,
+ "__docId__": 493,
"kind": "member",
"static": false,
"variation": null,
@@ -10482,7 +10520,7 @@
}
},
{
- "__docId__": 493,
+ "__docId__": 494,
"kind": "member",
"static": false,
"variation": null,
@@ -10500,7 +10538,7 @@
}
},
{
- "__docId__": 494,
+ "__docId__": 495,
"kind": "file",
"static": true,
"variation": null,
@@ -10513,7 +10551,7 @@
"content": "import {Feature} from '../feature';\nimport {createElm, createOpt, createText, elm, removeElm} from '../dom';\nimport {isArray, isFn, isNull} from '../types';\nimport {addEvt, keyCode, removeEvt} from '../event';\nimport {INPUT, SELECT, NONE, ENTER_KEY} from '../const';\n\n/**\n * Paging UI component\n * @export\n * @class Paging\n * @extends {Feature}\n */\nexport class Paging extends Feature {\n\n /**\n * Creates an instance of Paging\n * @param {TableFilter} tf TableFilter instance\n */\n constructor(tf) {\n super(tf, 'paging');\n\n // Configuration object\n var f = this.config;\n\n /**\n * Css class for the paging buttons (previous, next, etc.)\n * @type {String}\n */\n this.btnPageCssClass = f.paging_btn_css_class || 'pgInp';\n\n /**\n * Main select DOM element\n * @type {DOMElement}\n */\n this.pagingSlc = null;\n\n /**\n * Results per page select DOM element\n * @type {DOMElement}\n */\n this.resultsPerPageSlc = null;\n\n /**\n * ID of custom container element\n * @type {String}\n */\n this.pagingTgtId = f.paging_target_id || null;\n\n /**\n * Number of rows contained in a page\n * @type {Number}\n */\n this.pagingLength = !isNaN(f.paging_length) ? f.paging_length : 10;\n\n /**\n * ID of custom container element for the results per page selector\n * @type {String}\n */\n this.resultsPerPageTgtId = f.results_per_page_target_id || null;\n\n /**\n * Css class for the paging select element\n * @type {String}\n */\n this.pgSlcCssClass = f.paging_slc_css_class || 'pgSlc';\n\n /**\n * Css class for the paging input element\n * @type {String}\n */\n this.pgInpCssClass = f.paging_inp_css_class || 'pgNbInp';\n\n /**\n * Label and values for the results per page select, example of usage:\n * ['Records: ', [10,25,50,100]]\n * @type {Array}\n */\n this.resultsPerPage = f.results_per_page || null;\n\n /**\n * Determines if results per page is configured\n * @type {Boolean}\n */\n this.hasResultsPerPage = isArray(this.resultsPerPage);\n\n /**\n * Css class for the results per page select\n * @type {String}\n */\n this.resultsSlcCssClass = f.results_slc_css_class || 'rspg';\n\n /**\n * Css class for the label preceding results per page select\n * @type {String}\n */\n this.resultsSpanCssClass = f.results_span_css_class || 'rspgSpan';\n\n /**\n * Index of the first row of current page\n * @type {Number}\n * @private\n */\n this.startPagingRow = 0;\n\n /**\n * Total number of pages\n * @type {Number}\n * @private\n */\n this.nbPages = 0;\n\n /**\n * Current page number\n * @type {Number}\n * @private\n */\n this.currentPageNb = 1;\n\n /**\n * Next page button text\n * @type {String}\n */\n this.btnNextPageText = f.btn_next_page_text || '>';\n\n /**\n * Previous page button text\n * @type {String}\n */\n this.btnPrevPageText = f.btn_prev_page_text || '<';\n\n /**\n * Last page button text\n * @type {String}\n */\n this.btnLastPageText = f.btn_last_page_text || '>|';\n\n /**\n * First page button text\n * @type {String}\n */\n this.btnFirstPageText = f.btn_first_page_text || '|<';\n\n /**\n * Next page button HTML\n * @type {String}\n */\n this.btnNextPageHtml = f.btn_next_page_html ||\n (!tf.enableIcons ? null :\n ' ');\n\n /**\n * Previous page button HTML\n * @type {String}\n */\n this.btnPrevPageHtml = f.btn_prev_page_html ||\n (!tf.enableIcons ? null :\n ' ');\n\n /**\n * First page button HTML\n * @type {String}\n */\n this.btnFirstPageHtml = f.btn_first_page_html ||\n (!tf.enableIcons ? null :\n ' ');\n\n /**\n * Last page button HTML\n * @type {String}\n */\n this.btnLastPageHtml = f.btn_last_page_html ||\n (!tf.enableIcons ? null :\n ' ');\n\n /**\n * Text preceeding page selector drop-down\n * @type {String}\n */\n this.pageText = f.page_text || ' Page ';\n\n /**\n * Text after page selector drop-down\n * @type {String}\n */\n this.ofText = f.of_text || ' of ';\n\n /**\n * Css class for the span containing total number of pages\n * @type {String}\n */\n this.nbPgSpanCssClass = f.nb_pages_css_class || 'nbpg';\n\n /**\n * Determines if paging buttons are enabled (default: true)\n * @type {Boolean}\n */\n this.hasPagingBtns = f.paging_btns === false ? false : true;\n\n /**\n * Defines page selector type, two possible values: 'select', 'input'\n * @type {String}\n */\n this.pageSelectorType = f.page_selector_type || SELECT;\n\n /**\n * Callback fired before the page is changed\n * @type {Function}\n */\n this.onBeforeChangePage = isFn(f.on_before_change_page) ?\n f.on_before_change_page : null;\n\n /**\n * Callback fired after the page is changed\n * @type {Function}\n */\n this.onAfterChangePage = isFn(f.on_after_change_page) ?\n f.on_after_change_page : null;\n\n /**\n * Element IDs prefixes\n */\n /**\n * Page select\n * @type {String}\n * @private\n */\n this.prfxSlcPages = 'slcPages_';\n /**\n * Results per page select\n * @type {String}\n * @private\n */\n this.prfxSlcResults = 'slcResults_';\n /**\n * Label preciding results per page select\n * @type {String}\n * @private\n */\n this.prfxSlcResultsTxt = 'slcResultsTxt_';\n /**\n * Span containing next page button\n * @type {String}\n * @private\n */\n this.prfxBtnNextSpan = 'btnNextSpan_';\n /**\n * Span containing previous page button\n * @type {String}\n * @private\n */\n this.prfxBtnPrevSpan = 'btnPrevSpan_';\n /**\n * Span containing last page button\n * @type {String}\n * @private\n */\n this.prfxBtnLastSpan = 'btnLastSpan_';\n /**\n * Span containing first page button\n * @type {String}\n * @private\n */\n this.prfxBtnFirstSpan = 'btnFirstSpan_';\n /**\n * Next button\n * @type {String}\n * @private\n */\n this.prfxBtnNext = 'btnNext_';\n /**\n * Previous button\n * @type {String}\n * @private\n */\n this.prfxBtnPrev = 'btnPrev_';\n /**\n * Last button\n * @type {String}\n * @private\n */\n this.prfxBtnLast = 'btnLast_';\n /**\n * First button\n * @type {String}\n * @private\n */\n this.prfxBtnFirst = 'btnFirst_';\n /**\n * Span for tot nb pages\n * @type {String}\n * @private\n */\n this.prfxPgSpan = 'pgspan_';\n /**\n * Span preceding pages select (contains 'Page')\n * @type {String}\n * @private\n */\n this.prfxPgBeforeSpan = 'pgbeforespan_';\n /**\n * Span following pages select (contains ' of ')\n * @type {String}\n * @private\n */\n this.prfxPgAfterSpan = 'pgafterspan_';\n\n var start_row = tf.refRow;\n var nrows = tf.getRowsNb(true);\n //calculates page nb\n this.nbPages = Math.ceil((nrows - start_row) / this.pagingLength);\n\n var o = this;\n /**\n * Paging DOM events handlers\n * @type {String}\n * @private\n */\n this.evt = {\n slcIndex() {\n return (o.pageSelectorType === SELECT) ?\n o.pagingSlc.options.selectedIndex :\n parseInt(o.pagingSlc.value, 10) - 1;\n },\n nbOpts() {\n return (o.pageSelectorType === SELECT) ?\n parseInt(o.pagingSlc.options.length, 10) - 1 :\n (o.nbPages - 1);\n },\n next() {\n var nextIndex = o.evt.slcIndex() < o.evt.nbOpts() ?\n o.evt.slcIndex() + 1 : 0;\n o.changePage(nextIndex);\n },\n prev() {\n var prevIndex = o.evt.slcIndex() > 0 ?\n o.evt.slcIndex() - 1 : o.evt.nbOpts();\n o.changePage(prevIndex);\n },\n last() {\n o.changePage(o.evt.nbOpts());\n },\n first() {\n o.changePage(0);\n },\n _detectKey(e) {\n var key = keyCode(e);\n if (key === ENTER_KEY) {\n if (tf.sorted) {\n tf.filter();\n o.changePage(o.evt.slcIndex());\n } else {\n o.changePage();\n }\n this.blur();\n }\n },\n slcPagesChange: null,\n nextEvt: null,\n prevEvt: null,\n lastEvt: null,\n firstEvt: null\n };\n }\n\n /**\n * Initialize DOM elements\n */\n init() {\n var slcPages;\n var tf = this.tf;\n var evt = this.evt;\n\n if (this.initialized) {\n return;\n }\n\n // Check resultsPerPage is in expected format and initialise the\n // results per page component\n if (this.hasResultsPerPage) {\n if (this.resultsPerPage.length < 2) {\n this.hasResultsPerPage = false;\n } else {\n this.pagingLength = this.resultsPerPage[1][0];\n this.setResultsPerPage();\n }\n }\n\n evt.slcPagesChange = (event) => {\n var slc = event.target;\n this.changePage(slc.selectedIndex);\n };\n\n // Paging drop-down list selector\n if (this.pageSelectorType === SELECT) {\n slcPages = createElm(SELECT, ['id', this.prfxSlcPages + tf.id]);\n slcPages.className = this.pgSlcCssClass;\n addEvt(slcPages, 'change', evt.slcPagesChange);\n }\n\n // Paging input selector\n if (this.pageSelectorType === INPUT) {\n slcPages = createElm(INPUT,\n ['id', this.prfxSlcPages + tf.id],\n ['value', this.currentPageNb]\n );\n slcPages.className = this.pgInpCssClass;\n addEvt(slcPages, 'keypress', evt._detectKey);\n }\n\n // btns containers\n var btnNextSpan = createElm(\n 'span', ['id', this.prfxBtnNextSpan + tf.id]);\n var btnPrevSpan = createElm(\n 'span', ['id', this.prfxBtnPrevSpan + tf.id]);\n var btnLastSpan = createElm(\n 'span', ['id', this.prfxBtnLastSpan + tf.id]);\n var btnFirstSpan = createElm(\n 'span', ['id', this.prfxBtnFirstSpan + tf.id]);\n\n if (this.hasPagingBtns) {\n // Next button\n if (!this.btnNextPageHtml) {\n var btn_next = createElm(INPUT,\n ['id', this.prfxBtnNext + tf.id],\n ['type', 'button'],\n ['value', this.btnNextPageText],\n ['title', 'Next']\n );\n btn_next.className = this.btnPageCssClass;\n addEvt(btn_next, 'click', evt.next);\n btnNextSpan.appendChild(btn_next);\n } else {\n btnNextSpan.innerHTML = this.btnNextPageHtml;\n addEvt(btnNextSpan, 'click', evt.next);\n }\n // Previous button\n if (!this.btnPrevPageHtml) {\n var btn_prev = createElm(INPUT,\n ['id', this.prfxBtnPrev + tf.id],\n ['type', 'button'],\n ['value', this.btnPrevPageText],\n ['title', 'Previous']\n );\n btn_prev.className = this.btnPageCssClass;\n addEvt(btn_prev, 'click', evt.prev);\n btnPrevSpan.appendChild(btn_prev);\n } else {\n btnPrevSpan.innerHTML = this.btnPrevPageHtml;\n addEvt(btnPrevSpan, 'click', evt.prev);\n }\n // Last button\n if (!this.btnLastPageHtml) {\n var btn_last = createElm(INPUT,\n ['id', this.prfxBtnLast + tf.id],\n ['type', 'button'],\n ['value', this.btnLastPageText],\n ['title', 'Last']\n );\n btn_last.className = this.btnPageCssClass;\n addEvt(btn_last, 'click', evt.last);\n btnLastSpan.appendChild(btn_last);\n } else {\n btnLastSpan.innerHTML = this.btnLastPageHtml;\n addEvt(btnLastSpan, 'click', evt.last);\n }\n // First button\n if (!this.btnFirstPageHtml) {\n var btn_first = createElm(INPUT,\n ['id', this.prfxBtnFirst + tf.id],\n ['type', 'button'],\n ['value', this.btnFirstPageText],\n ['title', 'First']\n );\n btn_first.className = this.btnPageCssClass;\n addEvt(btn_first, 'click', evt.first);\n btnFirstSpan.appendChild(btn_first);\n } else {\n btnFirstSpan.innerHTML = this.btnFirstPageHtml;\n addEvt(btnFirstSpan, 'click', evt.first);\n }\n }\n\n // paging elements (buttons+drop-down list) are added to defined element\n if (!this.pagingTgtId) {\n tf.setToolbar();\n }\n var targetEl = !this.pagingTgtId ? tf.mDiv : elm(this.pagingTgtId);\n targetEl.appendChild(btnFirstSpan);\n targetEl.appendChild(btnPrevSpan);\n\n var pgBeforeSpan = createElm(\n 'span', ['id', this.prfxPgBeforeSpan + tf.id]);\n pgBeforeSpan.appendChild(createText(this.pageText));\n pgBeforeSpan.className = this.nbPgSpanCssClass;\n targetEl.appendChild(pgBeforeSpan);\n targetEl.appendChild(slcPages);\n var pgAfterSpan = createElm(\n 'span', ['id', this.prfxPgAfterSpan + tf.id]);\n pgAfterSpan.appendChild(createText(this.ofText));\n pgAfterSpan.className = this.nbPgSpanCssClass;\n targetEl.appendChild(pgAfterSpan);\n var pgspan = createElm('span', ['id', this.prfxPgSpan + tf.id]);\n pgspan.className = this.nbPgSpanCssClass;\n pgspan.appendChild(createText(' ' + this.nbPages + ' '));\n targetEl.appendChild(pgspan);\n targetEl.appendChild(btnNextSpan);\n targetEl.appendChild(btnLastSpan);\n this.pagingSlc = elm(this.prfxSlcPages + tf.id);\n\n this.setPagingInfo();\n\n if (!tf.fltGrid) {\n tf.validateAllRows();\n this.setPagingInfo(tf.validRowsIndex);\n }\n\n this.emitter.on(['after-filtering'], () => this.resetPagingInfo());\n this.emitter.on(['change-page'],\n (tf, pageNumber) => this.setPage(pageNumber));\n this.emitter.on(['change-page-results'],\n (tf, pageLength) => this.changeResultsPerPage(pageLength));\n\n /**\n * @inherited\n */\n this.initialized = true;\n }\n\n /**\n * Reset paging when filters are already instantiated\n * @param {Boolean} filterTable Execute filtering once paging instanciated\n */\n reset(filterTable = false) {\n var tf = this.tf;\n if (this.isEnabled()) {\n return;\n }\n this.enable();\n this.init();\n\n if (filterTable) {\n tf.filter();\n }\n }\n\n /**\n * Reset paging info from scratch after a filtering process\n */\n resetPagingInfo() {\n this.startPagingRow = 0;\n this.currentPageNb = 1;\n this.setPagingInfo(this.tf.validRowsIndex);\n }\n\n /**\n * Calculate number of pages based on valid rows\n * Refresh paging select according to number of pages\n * @param {Array} validRows Collection of valid rows\n */\n setPagingInfo(validRows) {\n var tf = this.tf;\n var mdiv = !this.pagingTgtId ? tf.mDiv : elm(this.pagingTgtId);\n var pgspan = elm(this.prfxPgSpan + tf.id);\n\n //store valid rows indexes\n tf.validRowsIndex = validRows || tf.getValidRows(true);\n\n //calculate nb of pages\n this.nbPages = Math.ceil(tf.validRowsIndex.length / this.pagingLength);\n //refresh page nb span\n pgspan.innerHTML = this.nbPages;\n //select clearing shortcut\n if (this.pageSelectorType === SELECT) {\n this.pagingSlc.innerHTML = '';\n }\n\n if (this.nbPages > 0) {\n mdiv.style.visibility = 'visible';\n if (this.pageSelectorType === SELECT) {\n for (var z = 0; z < this.nbPages; z++) {\n var opt = createOpt(z + 1, z * this.pagingLength, false);\n this.pagingSlc.options[z] = opt;\n }\n } else {\n //input type\n this.pagingSlc.value = this.currentPageNb;\n }\n\n } else {\n /*** if no results paging select and buttons are hidden ***/\n mdiv.style.visibility = 'hidden';\n }\n this.groupByPage(tf.validRowsIndex);\n }\n\n /**\n * Group table rows by page and display valid rows\n * @param {Array} validRows Collection of valid rows\n */\n groupByPage(validRows) {\n var tf = this.tf;\n var rows = tf.tbl.rows;\n var startPagingRow = parseInt(this.startPagingRow, 10);\n var endPagingRow = startPagingRow + parseInt(this.pagingLength, 10);\n\n //store valid rows indexes\n if (validRows) {\n tf.validRowsIndex = validRows;\n }\n\n //this loop shows valid rows of current page\n for (var h = 0, len = tf.getValidRowsNb(true); h < len; h++) {\n var validRowIdx = tf.validRowsIndex[h];\n var r = rows[validRowIdx];\n var isRowValid = r.getAttribute('validRow');\n var rowDisplayed = false;\n\n if (h >= startPagingRow && h < endPagingRow) {\n if (isNull(isRowValid) || Boolean(isRowValid === 'true')) {\n r.style.display = '';\n rowDisplayed = true;\n }\n } else {\n r.style.display = NONE;\n }\n this.emitter.emit('row-paged', tf, validRowIdx, h, rowDisplayed);\n }\n\n // broadcast grouping by page\n this.emitter.emit('grouped-by-page', tf, this);\n }\n\n /**\n * Return the current page number\n * @return {Number} Page number\n */\n getPage() {\n return this.currentPageNb;\n }\n\n /**\n * Show page defined by passed argument (string or number):\n * @param {String}/{Number} cmd possible string values: 'next',\n * 'previous', 'last', 'first' or page number as per param\n */\n setPage(cmd) {\n var tf = this.tf;\n if (!tf.isInitialized() || !this.isEnabled()) {\n return;\n }\n var btnEvt = this.evt,\n cmdtype = typeof cmd;\n if (cmdtype === 'string') {\n switch (cmd.toLowerCase()) {\n case 'next':\n btnEvt.next();\n break;\n case 'previous':\n btnEvt.prev();\n break;\n case 'last':\n btnEvt.last();\n break;\n case 'first':\n btnEvt.first();\n break;\n default:\n btnEvt.next();\n break;\n }\n }\n else if (cmdtype === 'number') {\n this.changePage(cmd - 1);\n }\n }\n\n /**\n * Generates UI elements for the number of results per page drop-down\n */\n setResultsPerPage() {\n var tf = this.tf;\n var evt = this.evt;\n\n if (this.resultsPerPageSlc || !this.resultsPerPage) {\n return;\n }\n\n evt.slcResultsChange = (ev) => {\n this.onChangeResultsPerPage();\n ev.target.blur();\n };\n\n var slcR = createElm(SELECT, ['id', this.prfxSlcResults + tf.id]);\n slcR.className = this.resultsSlcCssClass;\n var slcRText = this.resultsPerPage[0],\n slcROpts = this.resultsPerPage[1];\n var slcRSpan = createElm(\n 'span', ['id', this.prfxSlcResultsTxt + tf.id]);\n slcRSpan.className = this.resultsSpanCssClass;\n\n // results per page select is added to external element\n if (!this.resultsPerPageTgtId) {\n tf.setToolbar();\n }\n var targetEl = !this.resultsPerPageTgtId ?\n tf.rDiv : elm(this.resultsPerPageTgtId);\n slcRSpan.appendChild(createText(slcRText));\n\n var help = tf.feature('help');\n if (help && help.btn) {\n help.btn.parentNode.insertBefore(slcRSpan, help.btn);\n help.btn.parentNode.insertBefore(slcR, help.btn);\n } else {\n targetEl.appendChild(slcRSpan);\n targetEl.appendChild(slcR);\n }\n\n for (var r = 0; r < slcROpts.length; r++) {\n var currOpt = new Option(slcROpts[r], slcROpts[r], false, false);\n slcR.options[r] = currOpt;\n }\n addEvt(slcR, 'change', evt.slcResultsChange);\n this.resultsPerPageSlc = slcR;\n }\n\n /**\n * Remove number of results per page UI elements\n */\n removeResultsPerPage() {\n var tf = this.tf;\n if (!tf.isInitialized() || !this.resultsPerPageSlc ||\n !this.resultsPerPage) {\n return;\n }\n var slcR = this.resultsPerPageSlc,\n slcRSpan = elm(this.prfxSlcResultsTxt + tf.id);\n if (slcR) {\n removeElm(slcR);\n }\n if (slcRSpan) {\n removeElm(slcRSpan);\n }\n this.resultsPerPageSlc = null;\n }\n\n /**\n * Change the page based on passed index\n * @param {Number} index Index of the page (0-n)\n */\n changePage(index) {\n var tf = this.tf;\n\n if (!this.isEnabled()) {\n return;\n }\n\n this.emitter.emit('before-page-change', tf, (index + 1));\n\n if (index === null) {\n index = this.pageSelectorType === SELECT ?\n this.pagingSlc.options.selectedIndex : this.pagingSlc.value - 1;\n }\n if (index >= 0 && index <= (this.nbPages - 1)) {\n if (this.onBeforeChangePage) {\n this.onBeforeChangePage.call(null, this, (index + 1));\n }\n this.currentPageNb = parseInt(index, 10) + 1;\n if (this.pageSelectorType === SELECT) {\n this.pagingSlc.options[index].selected = true;\n } else {\n this.pagingSlc.value = this.currentPageNb;\n }\n\n this.startPagingRow = (this.pageSelectorType === SELECT) ?\n this.pagingSlc.value : (index * this.pagingLength);\n\n this.groupByPage();\n\n if (this.onAfterChangePage) {\n this.onAfterChangePage.call(null, this, (index + 1));\n }\n }\n\n this.emitter.emit('after-page-change', tf, (index + 1));\n }\n\n /**\n * Change the number of results per page based on passed value\n * @param {String} val The number of results per page\n */\n changeResultsPerPage(val) {\n if (!this.isEnabled() || isNaN(val)) {\n return;\n }\n\n this.resultsPerPageSlc.value = val;\n this.onChangeResultsPerPage();\n }\n\n /**\n * Change rows according to page results drop-down\n */\n onChangeResultsPerPage() {\n var tf = this.tf;\n\n if (!this.isEnabled()) {\n return;\n }\n\n this.emitter.emit('before-page-length-change', tf);\n\n var slcR = this.resultsPerPageSlc;\n var slcIndex = slcR.selectedIndex;\n var slcPagesSelIndex = (this.pageSelectorType === SELECT) ?\n this.pagingSlc.selectedIndex :\n parseInt(this.pagingSlc.value - 1, 10);\n this.pagingLength = parseInt(slcR.options[slcIndex].value, 10);\n this.startPagingRow = this.pagingLength * slcPagesSelIndex;\n\n if (!isNaN(this.pagingLength)) {\n if (this.startPagingRow >= tf.nbFilterableRows) {\n this.startPagingRow = (tf.nbFilterableRows - this.pagingLength);\n }\n this.setPagingInfo();\n\n if (this.pageSelectorType === SELECT) {\n var slcIdx =\n (this.pagingSlc.options.length - 1 <= slcPagesSelIndex) ?\n (this.pagingSlc.options.length - 1) : slcPagesSelIndex;\n this.pagingSlc.options[slcIdx].selected = true;\n }\n }\n\n this.emitter.emit('after-page-length-change', tf, this.pagingLength);\n }\n\n /**\n * Re-set page nb at page re-load\n */\n resetPage() {\n var tf = this.tf;\n if (!this.isEnabled()) {\n return;\n }\n this.emitter.emit('before-reset-page', tf);\n var pgNb = tf.feature('store').getPageNb();\n if (pgNb !== '') {\n this.changePage((pgNb - 1));\n }\n this.emitter.emit('after-reset-page', tf, pgNb);\n }\n\n /**\n * Re-set page length value at page re-load\n */\n resetPageLength() {\n var tf = this.tf;\n if (!this.isEnabled()) {\n return;\n }\n this.emitter.emit('before-reset-page-length', tf);\n var pglenIndex = tf.feature('store').getPageLength();\n\n if (pglenIndex !== '') {\n this.resultsPerPageSlc.options[pglenIndex].selected = true;\n this.changeResultsPerPage();\n }\n this.emitter.emit('after-reset-page-length', tf, pglenIndex);\n }\n\n /**\n * Remove paging feature\n */\n destroy() {\n var tf = this.tf;\n\n if (!this.initialized) {\n return;\n }\n // btns containers\n var btnNextSpan = elm(this.prfxBtnNextSpan + tf.id);\n var btnPrevSpan = elm(this.prfxBtnPrevSpan + tf.id);\n var btnLastSpan = elm(this.prfxBtnLastSpan + tf.id);\n var btnFirstSpan = elm(this.prfxBtnFirstSpan + tf.id);\n //span containing 'Page' text\n var pgBeforeSpan = elm(this.prfxPgBeforeSpan + tf.id);\n //span containing 'of' text\n var pgAfterSpan = elm(this.prfxPgAfterSpan + tf.id);\n //span containing nb of pages\n var pgspan = elm(this.prfxPgSpan + tf.id);\n\n var evt = this.evt;\n\n if (this.pagingSlc) {\n if (this.pageSelectorType === SELECT) {\n removeEvt(this.pagingSlc, 'change', evt.slcPagesChange);\n }\n else if (this.pageSelectorType === INPUT) {\n removeEvt(this.pagingSlc, 'keypress', evt._detectKey);\n }\n removeElm(this.pagingSlc);\n }\n\n if (btnNextSpan) {\n removeEvt(btnNextSpan, 'click', evt.next);\n removeElm(btnNextSpan);\n }\n\n if (btnPrevSpan) {\n removeEvt(btnPrevSpan, 'click', evt.prev);\n removeElm(btnPrevSpan);\n }\n\n if (btnLastSpan) {\n removeEvt(btnLastSpan, 'click', evt.last);\n removeElm(btnLastSpan);\n }\n\n if (btnFirstSpan) {\n removeEvt(btnFirstSpan, 'click', evt.first);\n removeElm(btnFirstSpan);\n }\n\n if (pgBeforeSpan) {\n removeElm(pgBeforeSpan);\n }\n\n if (pgAfterSpan) {\n removeElm(pgAfterSpan);\n }\n\n if (pgspan) {\n removeElm(pgspan);\n }\n\n if (this.hasResultsPerPage) {\n this.removeResultsPerPage();\n }\n\n this.emitter.off(['after-filtering'], () => this.resetPagingInfo());\n this.emitter.off(['change-page'],\n (tf, pageNumber) => this.setPage(pageNumber));\n this.emitter.off(['change-page-results'],\n (tf, pageLength) => this.changeResultsPerPage(pageLength));\n\n this.pagingSlc = null;\n this.nbPages = 0;\n this.disable();\n this.initialized = false;\n }\n}\n"
},
{
- "__docId__": 495,
+ "__docId__": 496,
"kind": "class",
"static": true,
"variation": null,
@@ -10542,7 +10580,7 @@
]
},
{
- "__docId__": 496,
+ "__docId__": 497,
"kind": "constructor",
"static": false,
"variation": null,
@@ -10567,7 +10605,7 @@
"generator": false
},
{
- "__docId__": 497,
+ "__docId__": 498,
"kind": "member",
"static": false,
"variation": null,
@@ -10587,7 +10625,7 @@
}
},
{
- "__docId__": 498,
+ "__docId__": 499,
"kind": "member",
"static": false,
"variation": null,
@@ -10607,7 +10645,7 @@
}
},
{
- "__docId__": 499,
+ "__docId__": 500,
"kind": "member",
"static": false,
"variation": null,
@@ -10627,7 +10665,7 @@
}
},
{
- "__docId__": 500,
+ "__docId__": 501,
"kind": "member",
"static": false,
"variation": null,
@@ -10647,7 +10685,7 @@
}
},
{
- "__docId__": 501,
+ "__docId__": 502,
"kind": "member",
"static": false,
"variation": null,
@@ -10667,7 +10705,7 @@
}
},
{
- "__docId__": 502,
+ "__docId__": 503,
"kind": "member",
"static": false,
"variation": null,
@@ -10687,7 +10725,7 @@
}
},
{
- "__docId__": 503,
+ "__docId__": 504,
"kind": "member",
"static": false,
"variation": null,
@@ -10707,7 +10745,7 @@
}
},
{
- "__docId__": 504,
+ "__docId__": 505,
"kind": "member",
"static": false,
"variation": null,
@@ -10727,7 +10765,7 @@
}
},
{
- "__docId__": 505,
+ "__docId__": 506,
"kind": "member",
"static": false,
"variation": null,
@@ -10747,7 +10785,7 @@
}
},
{
- "__docId__": 506,
+ "__docId__": 507,
"kind": "member",
"static": false,
"variation": null,
@@ -10767,7 +10805,7 @@
}
},
{
- "__docId__": 507,
+ "__docId__": 508,
"kind": "member",
"static": false,
"variation": null,
@@ -10787,7 +10825,7 @@
}
},
{
- "__docId__": 508,
+ "__docId__": 509,
"kind": "member",
"static": false,
"variation": null,
@@ -10807,7 +10845,7 @@
}
},
{
- "__docId__": 509,
+ "__docId__": 510,
"kind": "member",
"static": false,
"variation": null,
@@ -10827,7 +10865,7 @@
}
},
{
- "__docId__": 510,
+ "__docId__": 511,
"kind": "member",
"static": false,
"variation": null,
@@ -10847,7 +10885,7 @@
}
},
{
- "__docId__": 511,
+ "__docId__": 512,
"kind": "member",
"static": false,
"variation": null,
@@ -10867,7 +10905,7 @@
}
},
{
- "__docId__": 512,
+ "__docId__": 513,
"kind": "member",
"static": false,
"variation": null,
@@ -10887,7 +10925,7 @@
}
},
{
- "__docId__": 513,
+ "__docId__": 514,
"kind": "member",
"static": false,
"variation": null,
@@ -10907,7 +10945,7 @@
}
},
{
- "__docId__": 514,
+ "__docId__": 515,
"kind": "member",
"static": false,
"variation": null,
@@ -10927,7 +10965,7 @@
}
},
{
- "__docId__": 515,
+ "__docId__": 516,
"kind": "member",
"static": false,
"variation": null,
@@ -10947,7 +10985,7 @@
}
},
{
- "__docId__": 516,
+ "__docId__": 517,
"kind": "member",
"static": false,
"variation": null,
@@ -10967,7 +11005,7 @@
}
},
{
- "__docId__": 517,
+ "__docId__": 518,
"kind": "member",
"static": false,
"variation": null,
@@ -10987,7 +11025,7 @@
}
},
{
- "__docId__": 518,
+ "__docId__": 519,
"kind": "member",
"static": false,
"variation": null,
@@ -11007,7 +11045,7 @@
}
},
{
- "__docId__": 519,
+ "__docId__": 520,
"kind": "member",
"static": false,
"variation": null,
@@ -11027,7 +11065,7 @@
}
},
{
- "__docId__": 520,
+ "__docId__": 521,
"kind": "member",
"static": false,
"variation": null,
@@ -11047,7 +11085,7 @@
}
},
{
- "__docId__": 521,
+ "__docId__": 522,
"kind": "member",
"static": false,
"variation": null,
@@ -11067,7 +11105,7 @@
}
},
{
- "__docId__": 522,
+ "__docId__": 523,
"kind": "member",
"static": false,
"variation": null,
@@ -11087,7 +11125,7 @@
}
},
{
- "__docId__": 523,
+ "__docId__": 524,
"kind": "member",
"static": false,
"variation": null,
@@ -11107,7 +11145,7 @@
}
},
{
- "__docId__": 524,
+ "__docId__": 525,
"kind": "member",
"static": false,
"variation": null,
@@ -11127,7 +11165,7 @@
}
},
{
- "__docId__": 525,
+ "__docId__": 526,
"kind": "member",
"static": false,
"variation": null,
@@ -11147,7 +11185,7 @@
}
},
{
- "__docId__": 526,
+ "__docId__": 527,
"kind": "member",
"static": false,
"variation": null,
@@ -11167,7 +11205,7 @@
}
},
{
- "__docId__": 527,
+ "__docId__": 528,
"kind": "member",
"static": false,
"variation": null,
@@ -11187,7 +11225,7 @@
}
},
{
- "__docId__": 528,
+ "__docId__": 529,
"kind": "member",
"static": false,
"variation": null,
@@ -11207,7 +11245,7 @@
}
},
{
- "__docId__": 529,
+ "__docId__": 530,
"kind": "member",
"static": false,
"variation": null,
@@ -11227,7 +11265,7 @@
}
},
{
- "__docId__": 530,
+ "__docId__": 531,
"kind": "member",
"static": false,
"variation": null,
@@ -11247,7 +11285,7 @@
}
},
{
- "__docId__": 531,
+ "__docId__": 532,
"kind": "member",
"static": false,
"variation": null,
@@ -11267,7 +11305,7 @@
}
},
{
- "__docId__": 532,
+ "__docId__": 533,
"kind": "member",
"static": false,
"variation": null,
@@ -11287,7 +11325,7 @@
}
},
{
- "__docId__": 533,
+ "__docId__": 534,
"kind": "member",
"static": false,
"variation": null,
@@ -11307,7 +11345,7 @@
}
},
{
- "__docId__": 534,
+ "__docId__": 535,
"kind": "member",
"static": false,
"variation": null,
@@ -11327,7 +11365,7 @@
}
},
{
- "__docId__": 535,
+ "__docId__": 536,
"kind": "member",
"static": false,
"variation": null,
@@ -11347,7 +11385,7 @@
}
},
{
- "__docId__": 536,
+ "__docId__": 537,
"kind": "member",
"static": false,
"variation": null,
@@ -11367,7 +11405,7 @@
}
},
{
- "__docId__": 537,
+ "__docId__": 538,
"kind": "member",
"static": false,
"variation": null,
@@ -11387,7 +11425,7 @@
}
},
{
- "__docId__": 538,
+ "__docId__": 539,
"kind": "member",
"static": false,
"variation": null,
@@ -11407,7 +11445,7 @@
}
},
{
- "__docId__": 539,
+ "__docId__": 540,
"kind": "member",
"static": false,
"variation": null,
@@ -11427,7 +11465,7 @@
}
},
{
- "__docId__": 540,
+ "__docId__": 541,
"kind": "member",
"static": false,
"variation": null,
@@ -11447,7 +11485,7 @@
}
},
{
- "__docId__": 541,
+ "__docId__": 542,
"kind": "member",
"static": false,
"variation": null,
@@ -11465,7 +11503,7 @@
}
},
{
- "__docId__": 542,
+ "__docId__": 543,
"kind": "member",
"static": false,
"variation": null,
@@ -11485,7 +11523,7 @@
}
},
{
- "__docId__": 543,
+ "__docId__": 544,
"kind": "method",
"static": false,
"variation": null,
@@ -11499,7 +11537,7 @@
"generator": false
},
{
- "__docId__": 544,
+ "__docId__": 545,
"kind": "member",
"static": false,
"variation": null,
@@ -11517,7 +11555,7 @@
}
},
{
- "__docId__": 545,
+ "__docId__": 546,
"kind": "member",
"static": false,
"variation": null,
@@ -11535,7 +11573,7 @@
}
},
{
- "__docId__": 546,
+ "__docId__": 547,
"kind": "member",
"static": false,
"variation": null,
@@ -11553,7 +11591,7 @@
}
},
{
- "__docId__": 547,
+ "__docId__": 548,
"kind": "member",
"static": false,
"variation": null,
@@ -11576,7 +11614,7 @@
}
},
{
- "__docId__": 548,
+ "__docId__": 549,
"kind": "method",
"static": false,
"variation": null,
@@ -11601,7 +11639,7 @@
"generator": false
},
{
- "__docId__": 549,
+ "__docId__": 550,
"kind": "method",
"static": false,
"variation": null,
@@ -11615,7 +11653,7 @@
"generator": false
},
{
- "__docId__": 550,
+ "__docId__": 551,
"kind": "member",
"static": false,
"variation": null,
@@ -11633,7 +11671,7 @@
}
},
{
- "__docId__": 551,
+ "__docId__": 552,
"kind": "member",
"static": false,
"variation": null,
@@ -11651,7 +11689,7 @@
}
},
{
- "__docId__": 552,
+ "__docId__": 553,
"kind": "method",
"static": false,
"variation": null,
@@ -11676,7 +11714,7 @@
"generator": false
},
{
- "__docId__": 553,
+ "__docId__": 554,
"kind": "member",
"static": false,
"variation": null,
@@ -11694,7 +11732,7 @@
}
},
{
- "__docId__": 554,
+ "__docId__": 555,
"kind": "method",
"static": false,
"variation": null,
@@ -11719,7 +11757,7 @@
"generator": false
},
{
- "__docId__": 555,
+ "__docId__": 556,
"kind": "method",
"static": false,
"variation": null,
@@ -11741,7 +11779,7 @@
"generator": false
},
{
- "__docId__": 556,
+ "__docId__": 557,
"kind": "method",
"static": false,
"variation": null,
@@ -11766,7 +11804,7 @@
"generator": false
},
{
- "__docId__": 557,
+ "__docId__": 558,
"kind": "method",
"static": false,
"variation": null,
@@ -11780,7 +11818,7 @@
"generator": false
},
{
- "__docId__": 558,
+ "__docId__": 559,
"kind": "member",
"static": false,
"variation": null,
@@ -11798,7 +11836,7 @@
}
},
{
- "__docId__": 559,
+ "__docId__": 560,
"kind": "method",
"static": false,
"variation": null,
@@ -11812,7 +11850,7 @@
"generator": false
},
{
- "__docId__": 560,
+ "__docId__": 561,
"kind": "member",
"static": false,
"variation": null,
@@ -11830,7 +11868,7 @@
}
},
{
- "__docId__": 561,
+ "__docId__": 562,
"kind": "method",
"static": false,
"variation": null,
@@ -11855,7 +11893,7 @@
"generator": false
},
{
- "__docId__": 562,
+ "__docId__": 563,
"kind": "member",
"static": false,
"variation": null,
@@ -11873,7 +11911,7 @@
}
},
{
- "__docId__": 563,
+ "__docId__": 564,
"kind": "member",
"static": false,
"variation": null,
@@ -11891,7 +11929,7 @@
}
},
{
- "__docId__": 564,
+ "__docId__": 565,
"kind": "method",
"static": false,
"variation": null,
@@ -11916,7 +11954,7 @@
"generator": false
},
{
- "__docId__": 565,
+ "__docId__": 566,
"kind": "method",
"static": false,
"variation": null,
@@ -11930,7 +11968,7 @@
"generator": false
},
{
- "__docId__": 566,
+ "__docId__": 567,
"kind": "member",
"static": false,
"variation": null,
@@ -11948,7 +11986,7 @@
}
},
{
- "__docId__": 567,
+ "__docId__": 568,
"kind": "member",
"static": false,
"variation": null,
@@ -11966,7 +12004,7 @@
}
},
{
- "__docId__": 568,
+ "__docId__": 569,
"kind": "member",
"static": false,
"variation": null,
@@ -11984,7 +12022,7 @@
}
},
{
- "__docId__": 569,
+ "__docId__": 570,
"kind": "method",
"static": false,
"variation": null,
@@ -11998,7 +12036,7 @@
"generator": false
},
{
- "__docId__": 570,
+ "__docId__": 571,
"kind": "method",
"static": false,
"variation": null,
@@ -12012,7 +12050,7 @@
"generator": false
},
{
- "__docId__": 571,
+ "__docId__": 572,
"kind": "method",
"static": false,
"variation": null,
@@ -12026,7 +12064,7 @@
"generator": false
},
{
- "__docId__": 572,
+ "__docId__": 573,
"kind": "member",
"static": false,
"variation": null,
@@ -12044,7 +12082,7 @@
}
},
{
- "__docId__": 573,
+ "__docId__": 574,
"kind": "member",
"static": false,
"variation": null,
@@ -12062,7 +12100,7 @@
}
},
{
- "__docId__": 574,
+ "__docId__": 575,
"kind": "member",
"static": false,
"variation": null,
@@ -12080,7 +12118,7 @@
}
},
{
- "__docId__": 575,
+ "__docId__": 576,
"kind": "file",
"static": true,
"variation": null,
@@ -12093,7 +12131,7 @@
"content": "import {Feature} from '../feature';\nimport {isFn} from '../types';\nimport {createElm, removeElm} from '../dom';\nimport {addEvt, cancelEvt, stopEvt, targetEvt} from '../event';\nimport {INPUT, NONE} from '../const';\n\n/**\n * Pop-up filter component\n * @export\n * @class PopupFilter\n * @extends {Feature}\n */\nexport class PopupFilter extends Feature {\n\n /**\n * Creates an instance of PopupFilter\n * @param {TableFilter} tf TableFilter instance\n */\n constructor(tf) {\n super(tf, 'popupFilters');\n\n // Configuration object\n let f = this.config;\n\n // Enable external filters\n tf.isExternalFlt = true;\n tf.externalFltTgtIds = [];\n\n /**\n * Filter icon path\n * @type {String}\n */\n this.iconPath = f.popup_filters_image ||\n tf.themesPath + 'icn_filter.gif';\n\n /**\n * Active filter icon path\n * @type {string}\n */\n this.activeIconPath = f.popup_filters_image_active ||\n tf.themesPath + 'icn_filterActive.gif';\n\n /**\n * HTML for the filter icon\n * @type {string}\n */\n this.iconHtml = f.popup_filters_image_html ||\n '  ';\n\n /**\n * Css class assigned to filter container element\n * @type {String}\n */\n this.containerCssClass = f.popup_div_css_class || 'popUpFilter';\n\n /**\n * Callback fired before a popup filter is opened\n * @type {Function}\n */\n this.onBeforeOpen = isFn(f.on_before_popup_filter_open) ?\n f.on_before_popup_filter_open : null;\n\n /**\n * Callback fired after a popup filter is opened\n * @type {Function}\n */\n this.onAfterOpen = isFn(f.on_after_popup_filter_open) ?\n f.on_after_popup_filter_open : null;\n\n /**\n * Callback fired before a popup filter is closed\n * @type {Function}\n */\n this.onBeforeClose = isFn(f.on_before_popup_filter_close) ?\n f.on_before_popup_filter_close : null;\n\n /**\n * Callback fired after a popup filter is closed\n * @type {Function}\n */\n this.onAfterClose = isFn(f.on_after_popup_filter_close) ?\n f.on_after_popup_filter_close : null;\n\n /**\n * Collection of filters spans\n * @type {Array}\n * @private\n */\n this.fltSpans = [];\n\n /**\n * Collection of filters icons\n * @type {Array}\n * @private\n */\n this.fltIcons = [];\n\n /**\n * Collection of filters icons cached after pop-up filters are removed\n * @type {Array}\n * @private\n */\n this.filtersCache = null;\n\n /**\n * Collection of filters containers\n * @type {Array}\n * @private\n */\n this.fltElms = this.filtersCache || [];\n\n /**\n * Ensure filter's container element width matches column width\n * @type {Boolean}\n */\n this.adjustToContainer = true;\n\n /**\n * Prefix for pop-up filter span ID\n * @type {String}\n * @private\n */\n this.prfxSpan = 'popUpSpan_';\n\n /**\n * Prefix for pop-up filter container ID\n * @type {String}\n * @private\n */\n this.prfxDiv = 'popUpDiv_';\n }\n\n /**\n * Click event handler for pop-up filter icon\n * @private\n */\n onClick(evt) {\n let elm = targetEvt(evt).parentNode,\n colIndex = parseInt(elm.getAttribute('ci'), 10);\n\n this.closeAll(colIndex);\n this.toggle(colIndex);\n\n if (this.adjustToContainer) {\n let popUpDiv = this.fltElms[colIndex],\n header = this.tf.getHeaderElement(colIndex),\n headerWidth = header.clientWidth * 0.95;\n popUpDiv.style.width = parseInt(headerWidth, 10) + 'px';\n }\n cancelEvt(evt);\n stopEvt(evt);\n }\n\n /**\n * Initialize DOM elements\n */\n init() {\n if (this.initialized) {\n return;\n }\n\n let tf = this.tf;\n\n // Override headers row index if no grouped headers\n if (tf.headersRow <= 1) {\n tf.headersRow = 0;\n }\n\n for (let i = 0; i < tf.nbCells; i++) {\n if (tf.getFilterType(i) === NONE) {\n continue;\n }\n let popUpSpan = createElm(\n 'span',\n ['id', this.prfxSpan + tf.id + '_' + i],\n ['ci', i]\n );\n popUpSpan.innerHTML = this.iconHtml;\n let header = tf.getHeaderElement(i);\n header.appendChild(popUpSpan);\n addEvt(popUpSpan, 'click', (evt) => this.onClick(evt));\n this.fltSpans[i] = popUpSpan;\n this.fltIcons[i] = popUpSpan.firstChild;\n }\n\n // subscribe to events\n this.emitter.on(['before-filtering'], () => this.buildIcons());\n this.emitter.on(['after-filtering'], () => this.closeAll());\n this.emitter.on(['cell-processed'],\n (tf, cellIndex) => this.buildIcon(cellIndex, true));\n this.emitter.on(['filters-row-inserted'], () => this.tf.headersRow++);\n this.emitter.on(['before-filter-init'],\n (tf, colIndex) => this.build(colIndex));\n\n /**\n * @inherited\n */\n this.initialized = true;\n }\n\n /**\n * Reset previously destroyed feature\n */\n reset() {\n this.enable();\n this.init();\n this.buildAll();\n }\n\n /**\n * Build all pop-up filters elements\n */\n buildAll() {\n for (let i = 0; i < this.filtersCache.length; i++) {\n this.build(i, this.filtersCache[i]);\n }\n }\n\n /**\n * Build a specified pop-up filter elements\n * @param {Number} colIndex Column index\n * @param {Object} div Optional container DOM element\n */\n build(colIndex, div) {\n let tf = this.tf;\n let popUpDiv = !div ?\n createElm('div',\n ['id', this.prfxDiv + tf.id + '_' + colIndex]) :\n div;\n popUpDiv.className = this.containerCssClass;\n tf.externalFltTgtIds.push(popUpDiv.id);\n let header = tf.getHeaderElement(colIndex);\n header.insertBefore(popUpDiv, header.firstChild);\n addEvt(popUpDiv, 'click', (evt) => stopEvt(evt));\n this.fltElms[colIndex] = popUpDiv;\n }\n\n /**\n * Toogle visibility of specified filter\n * @param {Number} colIndex Column index\n */\n toggle(colIndex) {\n let tf = this.tf,\n popUpFltElm = this.fltElms[colIndex];\n\n if (popUpFltElm.style.display === NONE ||\n popUpFltElm.style.display === '') {\n if (this.onBeforeOpen) {\n this.onBeforeOpen.call(\n null, this, this.fltElms[colIndex], colIndex);\n }\n popUpFltElm.style.display = 'block';\n if (tf.getFilterType(colIndex) === INPUT) {\n let flt = tf.getFilterElement(colIndex);\n if (flt) {\n flt.focus();\n }\n }\n if (this.onAfterOpen) {\n this.onAfterOpen.call(\n null, this, this.fltElms[colIndex], colIndex);\n }\n } else {\n if (this.onBeforeClose) {\n this.onBeforeClose.call(\n null, this, this.fltElms[colIndex], colIndex);\n }\n popUpFltElm.style.display = NONE;\n if (this.onAfterClose) {\n this.onAfterClose.call(\n null, this, this.fltElms[colIndex], colIndex);\n }\n }\n }\n\n /**\n * Close all filters excepted for the specified one if any\n * @param {Number} exceptIdx Column index of the filter to not close\n */\n closeAll(exceptIdx) {\n for (let i = 0; i < this.fltElms.length; i++) {\n if (i === exceptIdx) {\n continue;\n }\n let popUpFltElm = this.fltElms[i];\n if (popUpFltElm) {\n popUpFltElm.style.display = NONE;\n }\n }\n }\n\n /**\n * Build all the icons representing the pop-up filters\n */\n buildIcons() {\n for (let i = 0; i < this.fltIcons.length; i++) {\n this.buildIcon(i, false);\n }\n }\n\n /**\n * Apply specified icon state\n * @param {Number} colIndex Column index\n * @param {Boolean} active Apply active state\n */\n buildIcon(colIndex, active) {\n if (this.fltIcons[colIndex]) {\n this.fltIcons[colIndex].src = active ?\n this.activeIconPath : this.iconPath;\n }\n }\n\n /**\n * Remove pop-up filters\n */\n destroy() {\n if (!this.initialized) {\n return;\n }\n\n this.filtersCache = [];\n for (let i = 0; i < this.fltElms.length; i++) {\n let popUpFltElm = this.fltElms[i],\n popUpFltSpan = this.fltSpans[i],\n popUpFltImg = this.fltIcons[i];\n if (popUpFltElm) {\n removeElm(popUpFltElm);\n this.filtersCache[i] = popUpFltElm;\n }\n popUpFltElm = null;\n if (popUpFltSpan) {\n removeElm(popUpFltSpan);\n }\n popUpFltSpan = null;\n if (popUpFltImg) {\n removeElm(popUpFltImg);\n }\n popUpFltImg = null;\n }\n this.fltElms = [];\n this.fltSpans = [];\n this.fltIcons = [];\n\n // unsubscribe to events\n this.emitter.off(['before-filtering'], () => this.buildIcons());\n this.emitter.off(['after-filtering'], () => this.closeAll());\n this.emitter.off(['cell-processed'],\n (tf, cellIndex) => this.buildIcon(cellIndex, true));\n this.emitter.off(['filters-row-inserted'], () => this.tf.headersRow++);\n this.emitter.off(['before-filter-init'],\n (tf, colIndex) => this.build(colIndex));\n\n this.initialized = false;\n }\n\n}\n"
},
{
- "__docId__": 576,
+ "__docId__": 577,
"kind": "class",
"static": true,
"variation": null,
@@ -12122,7 +12160,7 @@
]
},
{
- "__docId__": 577,
+ "__docId__": 578,
"kind": "constructor",
"static": false,
"variation": null,
@@ -12147,7 +12185,7 @@
"generator": false
},
{
- "__docId__": 578,
+ "__docId__": 579,
"kind": "member",
"static": false,
"variation": null,
@@ -12167,7 +12205,7 @@
}
},
{
- "__docId__": 579,
+ "__docId__": 580,
"kind": "member",
"static": false,
"variation": null,
@@ -12187,7 +12225,7 @@
}
},
{
- "__docId__": 580,
+ "__docId__": 581,
"kind": "member",
"static": false,
"variation": null,
@@ -12207,7 +12245,7 @@
}
},
{
- "__docId__": 581,
+ "__docId__": 582,
"kind": "member",
"static": false,
"variation": null,
@@ -12227,7 +12265,7 @@
}
},
{
- "__docId__": 582,
+ "__docId__": 583,
"kind": "member",
"static": false,
"variation": null,
@@ -12247,7 +12285,7 @@
}
},
{
- "__docId__": 583,
+ "__docId__": 584,
"kind": "member",
"static": false,
"variation": null,
@@ -12267,7 +12305,7 @@
}
},
{
- "__docId__": 584,
+ "__docId__": 585,
"kind": "member",
"static": false,
"variation": null,
@@ -12287,7 +12325,7 @@
}
},
{
- "__docId__": 585,
+ "__docId__": 586,
"kind": "member",
"static": false,
"variation": null,
@@ -12307,7 +12345,7 @@
}
},
{
- "__docId__": 586,
+ "__docId__": 587,
"kind": "member",
"static": false,
"variation": null,
@@ -12327,7 +12365,7 @@
}
},
{
- "__docId__": 587,
+ "__docId__": 588,
"kind": "member",
"static": false,
"variation": null,
@@ -12347,7 +12385,7 @@
}
},
{
- "__docId__": 588,
+ "__docId__": 589,
"kind": "member",
"static": false,
"variation": null,
@@ -12367,7 +12405,7 @@
}
},
{
- "__docId__": 589,
+ "__docId__": 590,
"kind": "member",
"static": false,
"variation": null,
@@ -12387,7 +12425,7 @@
}
},
{
- "__docId__": 590,
+ "__docId__": 591,
"kind": "member",
"static": false,
"variation": null,
@@ -12407,7 +12445,7 @@
}
},
{
- "__docId__": 591,
+ "__docId__": 592,
"kind": "member",
"static": false,
"variation": null,
@@ -12427,7 +12465,7 @@
}
},
{
- "__docId__": 592,
+ "__docId__": 593,
"kind": "member",
"static": false,
"variation": null,
@@ -12447,7 +12485,7 @@
}
},
{
- "__docId__": 593,
+ "__docId__": 594,
"kind": "method",
"static": false,
"variation": null,
@@ -12468,7 +12506,7 @@
"generator": false
},
{
- "__docId__": 594,
+ "__docId__": 595,
"kind": "method",
"static": false,
"variation": null,
@@ -12482,7 +12520,7 @@
"generator": false
},
{
- "__docId__": 595,
+ "__docId__": 596,
"kind": "member",
"static": false,
"variation": null,
@@ -12505,7 +12543,7 @@
}
},
{
- "__docId__": 596,
+ "__docId__": 597,
"kind": "method",
"static": false,
"variation": null,
@@ -12519,7 +12557,7 @@
"generator": false
},
{
- "__docId__": 597,
+ "__docId__": 598,
"kind": "method",
"static": false,
"variation": null,
@@ -12533,7 +12571,7 @@
"generator": false
},
{
- "__docId__": 598,
+ "__docId__": 599,
"kind": "method",
"static": false,
"variation": null,
@@ -12568,7 +12606,7 @@
"generator": false
},
{
- "__docId__": 599,
+ "__docId__": 600,
"kind": "method",
"static": false,
"variation": null,
@@ -12593,7 +12631,7 @@
"generator": false
},
{
- "__docId__": 600,
+ "__docId__": 601,
"kind": "method",
"static": false,
"variation": null,
@@ -12618,7 +12656,7 @@
"generator": false
},
{
- "__docId__": 601,
+ "__docId__": 602,
"kind": "method",
"static": false,
"variation": null,
@@ -12632,7 +12670,7 @@
"generator": false
},
{
- "__docId__": 602,
+ "__docId__": 603,
"kind": "method",
"static": false,
"variation": null,
@@ -12667,7 +12705,7 @@
"generator": false
},
{
- "__docId__": 603,
+ "__docId__": 604,
"kind": "method",
"static": false,
"variation": null,
@@ -12681,7 +12719,7 @@
"generator": false
},
{
- "__docId__": 604,
+ "__docId__": 605,
"kind": "member",
"static": false,
"variation": null,
@@ -12699,7 +12737,7 @@
}
},
{
- "__docId__": 605,
+ "__docId__": 606,
"kind": "member",
"static": false,
"variation": null,
@@ -12717,7 +12755,7 @@
}
},
{
- "__docId__": 606,
+ "__docId__": 607,
"kind": "member",
"static": false,
"variation": null,
@@ -12735,7 +12773,7 @@
}
},
{
- "__docId__": 607,
+ "__docId__": 608,
"kind": "member",
"static": false,
"variation": null,
@@ -12753,7 +12791,7 @@
}
},
{
- "__docId__": 608,
+ "__docId__": 609,
"kind": "member",
"static": false,
"variation": null,
@@ -12771,7 +12809,7 @@
}
},
{
- "__docId__": 609,
+ "__docId__": 610,
"kind": "file",
"static": true,
"variation": null,
@@ -12784,7 +12822,7 @@
"content": "import {Feature} from '../feature';\nimport {createElm, createText, elm, removeElm} from '../dom';\nimport {isFn} from '../types';\n\n/**\n * Rows counter UI component\n * @export\n * @class RowsCounter\n * @extends {Feature}\n */\nexport class RowsCounter extends Feature {\n\n /**\n * Creates an instance of RowsCounter\n * @param {TableFilter} tf TableFilter instance\n */\n constructor(tf) {\n super(tf, 'rowsCounter');\n\n // TableFilter configuration\n let f = this.config;\n\n /**\n * ID of custom container element\n * @type {String}\n */\n this.targetId = f.rows_counter_target_id || null;\n\n /**\n * Container DOM element\n * @type {DOMElement}\n * @private\n */\n this.container = null;\n\n /**\n * Container DOM element for label displaying the total number of rows\n * @type {DOMElement}\n * @private\n */\n this.label = null;\n\n /**\n * Text preceding the total number of rows\n * @type {String}\n */\n this.text = f.rows_counter_text || 'Rows: ';\n\n /**\n * Separator symbol appearing between the first and last visible rows of\n * current page when paging is enabled. ie: Rows: 31-40 / 70\n * @type {String}\n */\n this.fromToTextSeparator = f.from_to_text_separator || '-';\n\n /**\n * Separator symbol appearing between the first and last visible rows of\n * current page and the total number of filterable rows when paging is\n * enabled. ie: Rows: 31-40 / 70\n * @type {String}\n */\n this.overText = f.over_text || ' / ';\n\n /**\n * Css class for container element\n * @type {String}\n */\n this.cssClass = f.tot_rows_css_class || 'tot';\n\n /**\n * Prefix for container ID\n * @type {String}\n * @private\n */\n this.prfxCounter = 'counter_';\n\n /**\n * Prefix for DOM element containing the counter\n * @type {String}\n * @private\n */\n this.prfxLabel = 'totrows_span_';\n\n /**\n * Prefix for label preceding the counter\n * @type {String}\n * @private\n */\n this.prfxText = 'totRowsTextSpan_';\n\n /**\n * Callback fired before the counter is refreshed\n * @type {Function}\n */\n this.onBeforeRefreshCounter = isFn(f.on_before_refresh_counter) ?\n f.on_before_refresh_counter : null;\n\n /**\n * Callback fired after the counter is refreshed\n * @type {Function}\n */\n this.onAfterRefreshCounter = isFn(f.on_after_refresh_counter) ?\n f.on_after_refresh_counter : null;\n }\n\n /**\n * Initializes RowsCounter instance\n */\n init() {\n if (this.initialized) {\n return;\n }\n\n let tf = this.tf;\n\n //rows counter container\n let countDiv = createElm('div', ['id', this.prfxCounter + tf.id]);\n countDiv.className = this.cssClass;\n //rows counter label\n let countSpan = createElm('span', ['id', this.prfxLabel + tf.id]);\n let countText = createElm('span', ['id', this.prfxText + tf.id]);\n countText.appendChild(createText(this.text));\n\n // counter is added to defined element\n if (!this.targetId) {\n tf.setToolbar();\n }\n let targetEl = !this.targetId ? tf.lDiv : elm(this.targetId);\n\n //default container: 'lDiv'\n if (!this.targetId) {\n countDiv.appendChild(countText);\n countDiv.appendChild(countSpan);\n targetEl.appendChild(countDiv);\n }\n else {\n //custom container, no need to append statusDiv\n targetEl.appendChild(countText);\n targetEl.appendChild(countSpan);\n }\n this.container = countDiv;\n this.label = countSpan;\n\n // subscribe to events\n this.emitter.on(['after-filtering', 'grouped-by-page'],\n () => this.refresh(tf.getValidRowsNb()));\n this.emitter.on(['rows-changed'], () => this.refresh());\n\n /**\n * @inherited\n */\n this.initialized = true;\n this.refresh();\n }\n\n /**\n * Refreshes the rows counter\n * @param {Number} p Optional parameter the total number of rows to display\n * @returns\n */\n refresh(p) {\n if (!this.initialized || !this.isEnabled()) {\n return;\n }\n\n let tf = this.tf;\n\n if (this.onBeforeRefreshCounter) {\n this.onBeforeRefreshCounter.call(null, tf, this.label);\n }\n\n let totTxt;\n if (!tf.paging) {\n if (p && p !== '') {\n totTxt = p;\n } else {\n totTxt = tf.getFilterableRowsNb() - tf.nbHiddenRows;\n }\n } else {\n let paging = tf.feature('paging');\n if (paging) {\n //paging start row\n let pagingStartRow = parseInt(paging.startPagingRow, 10) +\n ((tf.getValidRowsNb() > 0) ? 1 : 0);\n let pagingEndRow =\n (pagingStartRow + paging.pagingLength) - 1 <=\n tf.getValidRowsNb() ?\n pagingStartRow + paging.pagingLength - 1 :\n tf.getValidRowsNb();\n totTxt = pagingStartRow + this.fromToTextSeparator +\n pagingEndRow + this.overText + tf.getValidRowsNb();\n }\n }\n\n this.label.innerHTML = totTxt;\n if (this.onAfterRefreshCounter) {\n this.onAfterRefreshCounter.call(null, tf, this.label, totTxt);\n }\n }\n\n /**\n * Remove feature\n */\n destroy() {\n if (!this.initialized) {\n return;\n }\n\n if (!this.targetId && this.container) {\n removeElm(this.container);\n } else {\n elm(this.targetId).innerHTML = '';\n }\n this.label = null;\n this.container = null;\n\n // unsubscribe to events\n this.emitter.off(['after-filtering', 'grouped-by-page'],\n () => this.refresh(tf.getValidRowsNb()));\n this.emitter.off(['rows-changed'], () => this.refresh());\n\n this.initialized = false;\n }\n}\n"
},
{
- "__docId__": 610,
+ "__docId__": 611,
"kind": "class",
"static": true,
"variation": null,
@@ -12813,7 +12851,7 @@
]
},
{
- "__docId__": 611,
+ "__docId__": 612,
"kind": "constructor",
"static": false,
"variation": null,
@@ -12838,7 +12876,7 @@
"generator": false
},
{
- "__docId__": 612,
+ "__docId__": 613,
"kind": "member",
"static": false,
"variation": null,
@@ -12858,7 +12896,7 @@
}
},
{
- "__docId__": 613,
+ "__docId__": 614,
"kind": "member",
"static": false,
"variation": null,
@@ -12878,7 +12916,7 @@
}
},
{
- "__docId__": 614,
+ "__docId__": 615,
"kind": "member",
"static": false,
"variation": null,
@@ -12898,7 +12936,7 @@
}
},
{
- "__docId__": 615,
+ "__docId__": 616,
"kind": "member",
"static": false,
"variation": null,
@@ -12918,7 +12956,7 @@
}
},
{
- "__docId__": 616,
+ "__docId__": 617,
"kind": "member",
"static": false,
"variation": null,
@@ -12938,7 +12976,7 @@
}
},
{
- "__docId__": 617,
+ "__docId__": 618,
"kind": "member",
"static": false,
"variation": null,
@@ -12958,7 +12996,7 @@
}
},
{
- "__docId__": 618,
+ "__docId__": 619,
"kind": "member",
"static": false,
"variation": null,
@@ -12978,7 +13016,7 @@
}
},
{
- "__docId__": 619,
+ "__docId__": 620,
"kind": "member",
"static": false,
"variation": null,
@@ -12998,7 +13036,7 @@
}
},
{
- "__docId__": 620,
+ "__docId__": 621,
"kind": "member",
"static": false,
"variation": null,
@@ -13018,7 +13056,7 @@
}
},
{
- "__docId__": 621,
+ "__docId__": 622,
"kind": "member",
"static": false,
"variation": null,
@@ -13038,7 +13076,7 @@
}
},
{
- "__docId__": 622,
+ "__docId__": 623,
"kind": "member",
"static": false,
"variation": null,
@@ -13058,7 +13096,7 @@
}
},
{
- "__docId__": 623,
+ "__docId__": 624,
"kind": "member",
"static": false,
"variation": null,
@@ -13078,7 +13116,7 @@
}
},
{
- "__docId__": 624,
+ "__docId__": 625,
"kind": "method",
"static": false,
"variation": null,
@@ -13092,7 +13130,7 @@
"generator": false
},
{
- "__docId__": 625,
+ "__docId__": 626,
"kind": "member",
"static": false,
"variation": null,
@@ -13110,7 +13148,7 @@
}
},
{
- "__docId__": 626,
+ "__docId__": 627,
"kind": "member",
"static": false,
"variation": null,
@@ -13128,7 +13166,7 @@
}
},
{
- "__docId__": 627,
+ "__docId__": 628,
"kind": "member",
"static": false,
"variation": null,
@@ -13151,7 +13189,7 @@
}
},
{
- "__docId__": 628,
+ "__docId__": 629,
"kind": "method",
"static": false,
"variation": null,
@@ -13182,7 +13220,7 @@
"generator": false
},
{
- "__docId__": 629,
+ "__docId__": 630,
"kind": "method",
"static": false,
"variation": null,
@@ -13196,7 +13234,7 @@
"generator": false
},
{
- "__docId__": 630,
+ "__docId__": 631,
"kind": "member",
"static": false,
"variation": null,
@@ -13214,7 +13252,7 @@
}
},
{
- "__docId__": 631,
+ "__docId__": 632,
"kind": "member",
"static": false,
"variation": null,
@@ -13232,7 +13270,7 @@
}
},
{
- "__docId__": 632,
+ "__docId__": 633,
"kind": "member",
"static": false,
"variation": null,
@@ -13250,7 +13288,7 @@
}
},
{
- "__docId__": 633,
+ "__docId__": 634,
"kind": "file",
"static": true,
"variation": null,
@@ -13263,7 +13301,7 @@
"content": "import {Feature} from '../feature';\nimport {Hash} from './hash';\nimport {Storage} from './storage';\nimport {isEmpty} from '../string';\nimport {isArray, isNull, isString, isUndef} from '../types';\n\n/**\n * Features state object persistable with localStorage, cookie or URL hash\n *\n * @export\n * @class State\n * @extends {Feature}\n */\nexport class State extends Feature {\n\n /**\n * Creates an instance of State\n * @param {TableFilter} tf TableFilter instance\n */\n constructor(tf) {\n super(tf, 'state');\n\n let cfg = this.config.state;\n\n /**\n * Determines whether state is persisted with URL hash\n * @type {Boolean}\n */\n this.enableHash = cfg === true ||\n (isArray(cfg.types) && cfg.types.indexOf('hash') !== -1);\n\n /**\n * Determines whether state is persisted with localStorage\n * @type {Boolean}\n */\n this.enableLocalStorage = isArray(cfg.types) &&\n cfg.types.indexOf('local_storage') !== -1;\n\n /**\n * Determines whether state is persisted with localStorage\n * @type {Boolean}\n */\n this.enableCookie = isArray(cfg.types) &&\n cfg.types.indexOf('cookie') !== -1;\n\n /**\n * Persist filters values, enabled by default\n * @type {Boolean}\n */\n this.persistFilters = cfg.filters === false ? false : true;\n\n /**\n * Persist current page number when paging is enabled\n * @type {Boolean}\n */\n this.persistPageNumber = Boolean(cfg.page_number);\n\n /**\n * Persist page length when paging is enabled\n * @type {Boolean}\n */\n this.persistPageLength = Boolean(cfg.page_length);\n\n /**\n * Persist column sorting\n * @type {Boolean}\n */\n this.persistSort = Boolean(cfg.sort);\n\n /**\n * Persist columns visibility\n * @type {Boolean}\n */\n this.persistColsVisibility = Boolean(cfg.columns_visibility);\n\n /**\n * Persist filters row visibility\n * @type {Boolean}\n */\n this.persistFiltersVisibility = Boolean(cfg.filters_visibility);\n\n /**\n * Cookie duration in hours\n * @type {Boolean}\n */\n this.cookieDuration = !isNaN(cfg.cookie_duration) ?\n parseInt(cfg.cookie_duration, 10) : 87600;\n\n /**\n * Enable Storage if localStorage or cookie is required\n * @type {Boolean}\n * @private\n */\n this.enableStorage = this.enableLocalStorage || this.enableCookie;\n\n /**\n * Storage instance if storage is required\n * @type {Storage}\n * @private\n */\n this.storage = null;\n\n /**\n * Hash instance if URL hash is required\n * @type {Boolean}\n * @private\n */\n this.hash = null;\n\n /**\n * Current page number\n * @type {Number}\n * @private\n */\n this.pageNb = null;\n\n /**\n * Current page length\n * @type {Number}\n * @private\n */\n this.pageLength = null;\n\n /**\n * Current column sorting\n * @type {Object}\n * @private\n */\n this.sort = null;\n\n /**\n * Current hidden columns\n * @type {Object}\n * @private\n */\n this.hiddenCols = null;\n\n /**\n * Filters row visibility\n * @type {Boolean}\n * @private\n */\n this.filtersVisibility = null;\n\n /**\n * State object\n * @type {Object}\n * @private\n */\n this.state = {};\n\n /**\n * Prefix for column ID\n * @type {String}\n * @private\n */\n this.prfxCol = 'col_';\n\n /**\n * Prefix for page number ID\n * @type {String}\n * @private\n */\n this.pageNbKey = 'page';\n\n /**\n * Prefix for page length ID\n * @type {String}\n * @private\n */\n this.pageLengthKey = 'page_length';\n\n /**\n * Prefix for filters visibility ID\n * @type {String}\n * @private\n */\n this.filtersVisKey = 'filters_visibility';\n }\n\n /**\n * Initializes State instance\n */\n init() {\n if (this.initialized) {\n return;\n }\n\n this.emitter.on(['after-filtering'], () => this.update());\n this.emitter.on(['after-page-change', 'after-clearing-filters'],\n (tf, pageNb) => this.updatePage(pageNb));\n this.emitter.on(['after-page-length-change'],\n (tf, pageLength) => this.updatePageLength(pageLength));\n this.emitter.on(['column-sorted'],\n (tf, index, descending) => this.updateSort(index, descending));\n this.emitter.on(['sort-initialized'], () => this._syncSort());\n this.emitter.on(['columns-visibility-initialized'],\n () => this._syncColsVisibility());\n this.emitter.on(['column-shown', 'column-hidden'], (tf, feature,\n colIndex, hiddenCols) => this.updateColsVisibility(hiddenCols));\n this.emitter.on(['filters-visibility-initialized'],\n () => this._syncFiltersVisibility());\n this.emitter.on(['filters-toggled'],\n (tf, extension, visible) => this.updateFiltersVisibility(visible));\n\n if (this.enableHash) {\n this.hash = new Hash(this);\n this.hash.init();\n }\n if (this.enableStorage) {\n this.storage = new Storage(this);\n this.storage.init();\n }\n\n /**\n * @inherited\n */\n this.initialized = true;\n }\n\n\n /**\n * Update state object based on current features state\n */\n update() {\n if (!this.isEnabled()) {\n return;\n }\n let state = this.state;\n let tf = this.tf;\n\n if (this.persistFilters) {\n let filterValues = tf.getFiltersValue();\n\n filterValues.forEach((val, idx) => {\n let key = `${this.prfxCol}${idx}`;\n\n if (isString(val) && isEmpty(val)) {\n if (state.hasOwnProperty(key)) {\n state[key].flt = undefined;\n }\n } else {\n state[key] = state[key] || {};\n state[key].flt = val;\n }\n });\n }\n\n if (this.persistPageNumber) {\n if (isNull(this.pageNb)) {\n state[this.pageNbKey] = undefined;\n } else {\n state[this.pageNbKey] = this.pageNb;\n }\n }\n\n if (this.persistPageLength) {\n if (isNull(this.pageLength)) {\n state[this.pageLengthKey] = undefined;\n } else {\n state[this.pageLengthKey] = this.pageLength;\n }\n }\n\n if (this.persistSort) {\n if (!isNull(this.sort)) {\n // Remove previuosly sorted column\n Object.keys(state).forEach((key) => {\n if (key.indexOf(this.prfxCol) !== -1 && state[key]) {\n state[key].sort = undefined;\n }\n });\n\n let key = `${this.prfxCol}${this.sort.column}`;\n state[key] = state[key] || {};\n state[key].sort = { descending: this.sort.descending };\n }\n }\n\n if (this.persistColsVisibility) {\n if (!isNull(this.hiddenCols)) {\n // Clear previuosly hidden columns\n Object.keys(state).forEach((key) => {\n if (key.indexOf(this.prfxCol) !== -1 && state[key]) {\n state[key].hidden = undefined;\n }\n });\n\n this.hiddenCols.forEach((colIdx) => {\n let key = `${this.prfxCol}${colIdx}`;\n state[key] = state[key] || {};\n state[key].hidden = true;\n });\n }\n }\n\n if (this.persistFiltersVisibility) {\n if (isNull(this.filtersVisibility)) {\n state[this.filtersVisKey] = undefined;\n } else {\n state[this.filtersVisKey] = this.filtersVisibility;\n }\n }\n\n this.emitter.emit('state-changed', tf, state);\n }\n\n /**\n * Refresh page number field on page number changes\n *\n * @param {Number} pageNb Current page number\n */\n updatePage(pageNb) {\n this.pageNb = pageNb;\n this.update();\n }\n\n /**\n * Refresh page length field on page length changes\n *\n * @param {Number} pageLength Current page length value\n */\n updatePageLength(pageLength) {\n this.pageLength = pageLength;\n this.update();\n }\n\n /**\n * Refresh column sorting information on sort changes\n *\n * @param index {Number} Column index\n * @param {Boolean} descending Descending manner\n */\n updateSort(index, descending) {\n this.sort = {\n column: index,\n descending: descending\n };\n this.update();\n }\n\n /**\n * Refresh hidden columns information on columns visibility changes\n *\n * @param {Array} hiddenCols Columns indexes\n */\n updateColsVisibility(hiddenCols) {\n this.hiddenCols = hiddenCols;\n this.update();\n }\n\n /**\n * Refresh filters visibility on filters visibility change\n *\n * @param {Boolean} visible Visibility flad\n */\n updateFiltersVisibility(visible) {\n this.filtersVisibility = visible;\n this.update();\n }\n\n /**\n * Override state field\n *\n * @param state State object\n */\n override(state) {\n this.state = state;\n }\n\n /**\n * Sync stored features state\n */\n sync() {\n let state = this.state;\n let tf = this.tf;\n\n this._syncFilters();\n\n if (this.persistPageNumber) {\n let pageNumber = state[this.pageNbKey];\n this.emitter.emit('change-page', tf, pageNumber);\n }\n\n if (this.persistPageLength) {\n let pageLength = state[this.pageLengthKey];\n this.emitter.emit('change-page-results', tf, pageLength);\n }\n\n this._syncSort();\n this._syncColsVisibility();\n this._syncFiltersVisibility();\n }\n\n /**\n * Override current state with passed one and sync features\n *\n * @param {Object} state State object\n */\n overrideAndSync(state) {\n // To prevent state to react to features changes, state is temporarily\n // disabled\n this.disable();\n // State is overriden with passed state object\n this.override(state);\n // New hash state is applied to features\n this.sync();\n // State is re-enabled\n this.enable();\n }\n\n /**\n * Sync filters with stored values and filter table\n *\n * @private\n */\n _syncFilters() {\n if (!this.persistFilters) {\n return;\n }\n let state = this.state;\n let tf = this.tf;\n\n Object.keys(state).forEach((key) => {\n if (key.indexOf(this.prfxCol) !== -1) {\n let colIdx = parseInt(key.replace(this.prfxCol, ''), 10);\n let val = state[key].flt;\n tf.setFilterValue(colIdx, val);\n }\n });\n\n tf.filter();\n }\n\n /**\n * Sync sorted column with stored sorting information and sort table\n *\n * @private\n */\n _syncSort() {\n if (!this.persistSort) {\n return;\n }\n let state = this.state;\n let tf = this.tf;\n\n Object.keys(state).forEach((key) => {\n if (key.indexOf(this.prfxCol) !== -1) {\n let colIdx = parseInt(key.replace(this.prfxCol, ''), 10);\n if (!isUndef(state[key].sort)) {\n let sort = state[key].sort;\n this.emitter.emit('sort', tf, colIdx, sort.descending);\n }\n }\n });\n }\n\n /**\n * Sync hidden columns with stored information\n *\n * @private\n */\n _syncColsVisibility() {\n if (!this.persistColsVisibility) {\n return;\n }\n let state = this.state;\n let tf = this.tf;\n let hiddenCols = [];\n\n Object.keys(state).forEach((key) => {\n if (key.indexOf(this.prfxCol) !== -1) {\n let colIdx = parseInt(key.replace(this.prfxCol, ''), 10);\n if (!isUndef(state[key].hidden)) {\n hiddenCols.push(colIdx);\n }\n }\n });\n\n hiddenCols.forEach((colIdx) => {\n this.emitter.emit('hide-column', tf, colIdx);\n });\n }\n\n /**\n * Sync filters visibility with stored information\n *\n * @private\n */\n _syncFiltersVisibility() {\n if (!this.persistFiltersVisibility) {\n return;\n }\n let state = this.state;\n let tf = this.tf;\n let filtersVisibility = state[this.filtersVisKey];\n\n this.filtersVisibility = filtersVisibility;\n this.emitter.emit('show-filters', tf, filtersVisibility);\n }\n\n /**\n * Destroy State instance\n */\n destroy() {\n if (!this.initialized) {\n return;\n }\n\n this.state = {};\n\n this.emitter.off(['after-filtering'], () => this.update());\n this.emitter.off(['after-page-change', 'after-clearing-filters'],\n (tf, pageNb) => this.updatePage(pageNb));\n this.emitter.off(['after-page-length-change'],\n (tf, index) => this.updatePageLength(index));\n this.emitter.off(['column-sorted'],\n (tf, index, descending) => this.updateSort(index, descending));\n this.emitter.off(['sort-initialized'], () => this._syncSort());\n this.emitter.off(['columns-visibility-initialized'],\n () => this._syncColsVisibility());\n this.emitter.off(['column-shown', 'column-hidden'], (tf, feature,\n colIndex, hiddenCols) => this.updateColsVisibility(hiddenCols));\n this.emitter.off(['filters-visibility-initialized'],\n () => this._syncFiltersVisibility());\n this.emitter.off(['filters-toggled'],\n (tf, extension, visible) => this.updateFiltersVisibility(visible));\n\n if (this.enableHash) {\n this.hash.destroy();\n this.hash = null;\n }\n\n if (this.enableStorage) {\n this.storage.destroy();\n this.storage = null;\n }\n\n this.initialized = false;\n }\n}\n"
},
{
- "__docId__": 634,
+ "__docId__": 635,
"kind": "class",
"static": true,
"variation": null,
@@ -13292,7 +13330,7 @@
]
},
{
- "__docId__": 635,
+ "__docId__": 636,
"kind": "constructor",
"static": false,
"variation": null,
@@ -13317,7 +13355,7 @@
"generator": false
},
{
- "__docId__": 636,
+ "__docId__": 637,
"kind": "member",
"static": false,
"variation": null,
@@ -13337,7 +13375,7 @@
}
},
{
- "__docId__": 637,
+ "__docId__": 638,
"kind": "member",
"static": false,
"variation": null,
@@ -13357,7 +13395,7 @@
}
},
{
- "__docId__": 638,
+ "__docId__": 639,
"kind": "member",
"static": false,
"variation": null,
@@ -13377,7 +13415,7 @@
}
},
{
- "__docId__": 639,
+ "__docId__": 640,
"kind": "member",
"static": false,
"variation": null,
@@ -13397,7 +13435,7 @@
}
},
{
- "__docId__": 640,
+ "__docId__": 641,
"kind": "member",
"static": false,
"variation": null,
@@ -13417,7 +13455,7 @@
}
},
{
- "__docId__": 641,
+ "__docId__": 642,
"kind": "member",
"static": false,
"variation": null,
@@ -13437,7 +13475,7 @@
}
},
{
- "__docId__": 642,
+ "__docId__": 643,
"kind": "member",
"static": false,
"variation": null,
@@ -13457,7 +13495,7 @@
}
},
{
- "__docId__": 643,
+ "__docId__": 644,
"kind": "member",
"static": false,
"variation": null,
@@ -13477,7 +13515,7 @@
}
},
{
- "__docId__": 644,
+ "__docId__": 645,
"kind": "member",
"static": false,
"variation": null,
@@ -13497,7 +13535,7 @@
}
},
{
- "__docId__": 645,
+ "__docId__": 646,
"kind": "member",
"static": false,
"variation": null,
@@ -13517,7 +13555,7 @@
}
},
{
- "__docId__": 646,
+ "__docId__": 647,
"kind": "member",
"static": false,
"variation": null,
@@ -13537,7 +13575,7 @@
}
},
{
- "__docId__": 647,
+ "__docId__": 648,
"kind": "member",
"static": false,
"variation": null,
@@ -13557,7 +13595,7 @@
}
},
{
- "__docId__": 648,
+ "__docId__": 649,
"kind": "member",
"static": false,
"variation": null,
@@ -13577,7 +13615,7 @@
}
},
{
- "__docId__": 649,
+ "__docId__": 650,
"kind": "member",
"static": false,
"variation": null,
@@ -13597,7 +13635,7 @@
}
},
{
- "__docId__": 650,
+ "__docId__": 651,
"kind": "member",
"static": false,
"variation": null,
@@ -13617,7 +13655,7 @@
}
},
{
- "__docId__": 651,
+ "__docId__": 652,
"kind": "member",
"static": false,
"variation": null,
@@ -13637,7 +13675,7 @@
}
},
{
- "__docId__": 652,
+ "__docId__": 653,
"kind": "member",
"static": false,
"variation": null,
@@ -13657,7 +13695,7 @@
}
},
{
- "__docId__": 653,
+ "__docId__": 654,
"kind": "member",
"static": false,
"variation": null,
@@ -13677,7 +13715,7 @@
}
},
{
- "__docId__": 654,
+ "__docId__": 655,
"kind": "member",
"static": false,
"variation": null,
@@ -13697,7 +13735,7 @@
}
},
{
- "__docId__": 655,
+ "__docId__": 656,
"kind": "member",
"static": false,
"variation": null,
@@ -13717,7 +13755,7 @@
}
},
{
- "__docId__": 656,
+ "__docId__": 657,
"kind": "member",
"static": false,
"variation": null,
@@ -13737,7 +13775,7 @@
}
},
{
- "__docId__": 657,
+ "__docId__": 658,
"kind": "member",
"static": false,
"variation": null,
@@ -13757,7 +13795,7 @@
}
},
{
- "__docId__": 658,
+ "__docId__": 659,
"kind": "member",
"static": false,
"variation": null,
@@ -13777,7 +13815,7 @@
}
},
{
- "__docId__": 659,
+ "__docId__": 660,
"kind": "method",
"static": false,
"variation": null,
@@ -13791,7 +13829,7 @@
"generator": false
},
{
- "__docId__": 660,
+ "__docId__": 661,
"kind": "member",
"static": false,
"variation": null,
@@ -13809,7 +13847,7 @@
}
},
{
- "__docId__": 661,
+ "__docId__": 662,
"kind": "member",
"static": false,
"variation": null,
@@ -13827,7 +13865,7 @@
}
},
{
- "__docId__": 662,
+ "__docId__": 663,
"kind": "member",
"static": false,
"variation": null,
@@ -13850,7 +13888,7 @@
}
},
{
- "__docId__": 663,
+ "__docId__": 664,
"kind": "method",
"static": false,
"variation": null,
@@ -13864,7 +13902,7 @@
"generator": false
},
{
- "__docId__": 664,
+ "__docId__": 665,
"kind": "method",
"static": false,
"variation": null,
@@ -13889,7 +13927,7 @@
"generator": false
},
{
- "__docId__": 665,
+ "__docId__": 666,
"kind": "member",
"static": false,
"variation": null,
@@ -13907,7 +13945,7 @@
}
},
{
- "__docId__": 666,
+ "__docId__": 667,
"kind": "method",
"static": false,
"variation": null,
@@ -13932,7 +13970,7 @@
"generator": false
},
{
- "__docId__": 667,
+ "__docId__": 668,
"kind": "member",
"static": false,
"variation": null,
@@ -13950,7 +13988,7 @@
}
},
{
- "__docId__": 668,
+ "__docId__": 669,
"kind": "method",
"static": false,
"variation": null,
@@ -13985,7 +14023,7 @@
"generator": false
},
{
- "__docId__": 669,
+ "__docId__": 670,
"kind": "member",
"static": false,
"variation": null,
@@ -14003,7 +14041,7 @@
}
},
{
- "__docId__": 670,
+ "__docId__": 671,
"kind": "method",
"static": false,
"variation": null,
@@ -14028,7 +14066,7 @@
"generator": false
},
{
- "__docId__": 671,
+ "__docId__": 672,
"kind": "member",
"static": false,
"variation": null,
@@ -14046,7 +14084,7 @@
}
},
{
- "__docId__": 672,
+ "__docId__": 673,
"kind": "method",
"static": false,
"variation": null,
@@ -14071,7 +14109,7 @@
"generator": false
},
{
- "__docId__": 673,
+ "__docId__": 674,
"kind": "member",
"static": false,
"variation": null,
@@ -14089,7 +14127,7 @@
}
},
{
- "__docId__": 674,
+ "__docId__": 675,
"kind": "method",
"static": false,
"variation": null,
@@ -14114,7 +14152,7 @@
"generator": false
},
{
- "__docId__": 675,
+ "__docId__": 676,
"kind": "member",
"static": false,
"variation": null,
@@ -14132,7 +14170,7 @@
}
},
{
- "__docId__": 676,
+ "__docId__": 677,
"kind": "method",
"static": false,
"variation": null,
@@ -14146,7 +14184,7 @@
"generator": false
},
{
- "__docId__": 677,
+ "__docId__": 678,
"kind": "method",
"static": false,
"variation": null,
@@ -14171,7 +14209,7 @@
"generator": false
},
{
- "__docId__": 678,
+ "__docId__": 679,
"kind": "method",
"static": false,
"variation": null,
@@ -14185,7 +14223,7 @@
"generator": false
},
{
- "__docId__": 679,
+ "__docId__": 680,
"kind": "method",
"static": false,
"variation": null,
@@ -14199,7 +14237,7 @@
"generator": false
},
{
- "__docId__": 680,
+ "__docId__": 681,
"kind": "method",
"static": false,
"variation": null,
@@ -14213,7 +14251,7 @@
"generator": false
},
{
- "__docId__": 681,
+ "__docId__": 682,
"kind": "method",
"static": false,
"variation": null,
@@ -14227,7 +14265,7 @@
"generator": false
},
{
- "__docId__": 682,
+ "__docId__": 683,
"kind": "member",
"static": false,
"variation": null,
@@ -14245,7 +14283,7 @@
}
},
{
- "__docId__": 683,
+ "__docId__": 684,
"kind": "method",
"static": false,
"variation": null,
@@ -14259,7 +14297,7 @@
"generator": false
},
{
- "__docId__": 684,
+ "__docId__": 685,
"kind": "member",
"static": false,
"variation": null,
@@ -14277,7 +14315,7 @@
}
},
{
- "__docId__": 685,
+ "__docId__": 686,
"kind": "member",
"static": false,
"variation": null,
@@ -14295,7 +14333,7 @@
}
},
{
- "__docId__": 686,
+ "__docId__": 687,
"kind": "member",
"static": false,
"variation": null,
@@ -14313,7 +14351,7 @@
}
},
{
- "__docId__": 687,
+ "__docId__": 688,
"kind": "member",
"static": false,
"variation": null,
@@ -14331,7 +14369,7 @@
}
},
{
- "__docId__": 688,
+ "__docId__": 689,
"kind": "file",
"static": true,
"variation": null,
@@ -14344,7 +14382,7 @@
"content": "import {Feature} from '../feature';\nimport {root} from '../root';\nimport {createElm, createText, elm, removeElm} from '../dom';\nimport {isFn} from '../types';\n\n/**\n * Status bar UI component\n * @export\n * @class StatusBar\n * @extends {Feature}\n */\nexport class StatusBar extends Feature {\n\n /**\n * Creates an instance of StatusBar\n * @param {TableFilter} tf TableFilter instance\n */\n constructor(tf) {\n super(tf, 'statusBar');\n\n // Configuration object\n let f = this.config;\n\n /**\n * ID of custom container element\n * @type {String}\n */\n this.targetId = f.status_bar_target_id || null;\n\n /**\n * Container DOM element\n * @type {DOMElement}\n * @private\n */\n this.container = null;\n\n /**\n * Message container DOM element\n * @type {DOMElement}\n * @private\n */\n this.msgContainer = null;\n\n /**\n * Label container DOM element\n * @type {DOMElement}\n * @private\n */\n this.labelContainer = null;\n\n /**\n * Text preceding status message\n * @type {String}\n */\n this.text = f.status_bar_text || '';\n\n /**\n * Css class for container element\n * @type {String}\n */\n this.cssClass = f.status_bar_css_class || 'status';\n\n /**\n * Message visibility duration in milliseconds\n * @type {Number}\n * @private\n */\n this.delay = 250;\n\n /**\n * Callback fired before the message is displayed\n * @type {Function}\n */\n this.onBeforeShowMsg = isFn(f.on_before_show_msg) ?\n f.on_before_show_msg : null;\n\n /**\n * Callback fired after the message is displayed\n * @type {Function}\n */\n this.onAfterShowMsg = isFn(f.on_after_show_msg) ?\n f.on_after_show_msg : null;\n\n /**\n * Message appearing upon filtering\n * @type {String}\n */\n this.msgFilter = f.msg_filter || 'Filtering data...';\n\n /**\n * Message appearing when a drop-down filter is populated\n * @type {String}\n */\n this.msgPopulate = f.msg_populate || 'Populating filter...';\n\n /**\n * Message appearing when a checklist filter is populated\n * @type {String}\n */\n this.msgPopulateCheckList = f.msg_populate_checklist ||\n 'Populating list...';\n\n /**\n * Message appearing when a pagination page is changed\n * @type {String}\n */\n this.msgChangePage = f.msg_change_page || 'Collecting paging data...';\n\n /**\n * Message appearing when filters are cleared\n * @type {String}\n */\n this.msgClear = f.msg_clear || 'Clearing filters...';\n\n /**\n * Message appearing when the page length is changed\n * @type {String}\n */\n this.msgChangeResults = f.msg_change_results ||\n 'Changing results per page...';\n\n /**\n * Message appearing when the page is re-set\n * @type {String}\n */\n this.msgResetPage = f.msg_reset_page || 'Re-setting page...';\n\n /**\n * Message appearing when the page length is re-set\n * @type {String}\n */\n this.msgResetPageLength = f.msg_reset_page_length ||\n 'Re-setting page length...';\n\n /**\n * Message appearing upon column sorting\n * @type {String}\n */\n this.msgSort = f.msg_sort || 'Sorting data...';\n\n /**\n * Message appearing when extensions are loading\n * @type {String}\n */\n this.msgLoadExtensions = f.msg_load_extensions ||\n 'Loading extensions...';\n\n /**\n * Message appearing when themes are loading\n * @type {String}\n */\n this.msgLoadThemes = f.msg_load_themes || 'Loading theme(s)...';\n\n /**\n * Prefix for container ID\n * @type {String}\n * @private\n */\n this.prfxCont = 'status_';\n\n /**\n * Prefix for label container ID\n * @type {String}\n * @private\n */\n this.prfxLabel = 'statusSpan_';\n\n /**\n * Prefix for text preceding the message\n * @type {String}\n * @private\n */\n this.prfxText = 'statusText_';\n }\n\n /**\n * Initializes StatusBar instance\n */\n init() {\n if (this.initialized) {\n return;\n }\n\n let tf = this.tf;\n let emitter = this.emitter;\n\n //status bar container\n let statusDiv = createElm('div', ['id', this.prfxCont + tf.id]);\n statusDiv.className = this.cssClass;\n\n //status bar label\n let statusSpan = createElm('span', ['id', this.prfxLabel + tf.id]);\n //preceding text\n let statusSpanText = createElm('span', ['id', this.prfxText + tf.id]);\n statusSpanText.appendChild(createText(this.text));\n\n // target element container\n if (!this.targetId) {\n tf.setToolbar();\n }\n let targetEl = (!this.targetId) ? tf.lDiv : elm(this.targetId);\n\n //default container: 'lDiv'\n if (!this.targetId) {\n statusDiv.appendChild(statusSpanText);\n statusDiv.appendChild(statusSpan);\n targetEl.appendChild(statusDiv);\n } else {\n // custom container, no need to append statusDiv\n targetEl.appendChild(statusSpanText);\n targetEl.appendChild(statusSpan);\n }\n\n this.container = statusDiv;\n this.msgContainer = statusSpan;\n this.labelContainer = statusSpanText;\n\n // Subscribe to events\n emitter.on(['before-filtering'], () => this.message(this.msgFilter));\n emitter.on(['before-populating-filter'],\n () => this.message(this.msgPopulate));\n emitter.on(['before-page-change'],\n () => this.message(this.msgChangePage));\n emitter.on(['before-clearing-filters'], () =>\n this.message(this.msgClear));\n emitter.on(['before-page-length-change'],\n () => this.message(this.msgChangeResults));\n emitter.on(['before-reset-page'],\n () => this.message(this.msgResetPage));\n emitter.on(['before-reset-page-length'],\n () => this.message(this.msgResetPageLength));\n emitter.on(['before-loading-extensions'],\n () => this.message(this.msgLoadExtensions));\n emitter.on(['before-loading-themes'],\n () => this.message(this.msgLoadThemes));\n\n emitter.on([\n 'after-filtering',\n 'after-populating-filter',\n 'after-page-change',\n 'after-clearing-filters',\n 'after-page-length-change',\n 'after-reset-page',\n 'after-reset-page-length',\n 'after-loading-extensions',\n 'after-loading-themes'],\n () => this.message('')\n );\n\n /**\n * @inherited\n */\n this.initialized = true;\n }\n\n /**\n * Display status message\n * @param {String} [t=''] Message to be displayed\n */\n message(t = '') {\n if (!this.isEnabled()) {\n return;\n }\n\n if (this.onBeforeShowMsg) {\n this.onBeforeShowMsg.call(null, this.tf, t);\n }\n\n let d = t === '' ? this.delay : 1;\n root.setTimeout(() => {\n if (!this.initialized) {\n return;\n }\n this.msgContainer.innerHTML = t;\n if (this.onAfterShowMsg) {\n this.onAfterShowMsg.call(null, this.tf, t);\n }\n }, d);\n }\n\n /**\n * Destroy StatusBar instance\n */\n destroy() {\n if (!this.initialized) {\n return;\n }\n\n let emitter = this.emitter;\n\n this.container.innerHTML = '';\n if (!this.targetId) {\n removeElm(this.container);\n }\n this.labelContainer = null;\n this.msgContainer = null;\n this.container = null;\n\n // Unsubscribe to events\n emitter.off(['before-filtering'], () => this.message(this.msgFilter));\n emitter.off(['before-populating-filter'],\n () => this.message(this.msgPopulate));\n emitter.off(['before-page-change'],\n () => this.message(this.msgChangePage));\n emitter.off(['before-clearing-filters'],\n () => this.message(this.msgClear));\n emitter.off(['before-page-length-change'],\n () => this.message(this.msgChangeResults));\n emitter.off(['before-reset-page'], () =>\n this.message(this.msgResetPage));\n emitter.off(['before-reset-page-length'],\n () => this.message(this.msgResetPageLength));\n emitter.off(['before-loading-extensions'],\n () => this.message(this.msgLoadExtensions));\n emitter.off(['before-loading-themes'],\n () => this.message(this.msgLoadThemes));\n\n emitter.off([\n 'after-filtering',\n 'after-populating-filter',\n 'after-page-change',\n 'after-clearing-filters',\n 'after-page-length-change',\n 'after-reset-page',\n 'after-reset-page-length',\n 'after-loading-extensions',\n 'after-loading-themes'],\n () => this.message('')\n );\n\n this.initialized = false;\n }\n}\n"
},
{
- "__docId__": 689,
+ "__docId__": 690,
"kind": "class",
"static": true,
"variation": null,
@@ -14373,7 +14411,7 @@
]
},
{
- "__docId__": 690,
+ "__docId__": 691,
"kind": "constructor",
"static": false,
"variation": null,
@@ -14398,7 +14436,7 @@
"generator": false
},
{
- "__docId__": 691,
+ "__docId__": 692,
"kind": "member",
"static": false,
"variation": null,
@@ -14418,7 +14456,7 @@
}
},
{
- "__docId__": 692,
+ "__docId__": 693,
"kind": "member",
"static": false,
"variation": null,
@@ -14438,7 +14476,7 @@
}
},
{
- "__docId__": 693,
+ "__docId__": 694,
"kind": "member",
"static": false,
"variation": null,
@@ -14458,7 +14496,7 @@
}
},
{
- "__docId__": 694,
+ "__docId__": 695,
"kind": "member",
"static": false,
"variation": null,
@@ -14478,7 +14516,7 @@
}
},
{
- "__docId__": 695,
+ "__docId__": 696,
"kind": "member",
"static": false,
"variation": null,
@@ -14498,7 +14536,7 @@
}
},
{
- "__docId__": 696,
+ "__docId__": 697,
"kind": "member",
"static": false,
"variation": null,
@@ -14518,7 +14556,7 @@
}
},
{
- "__docId__": 697,
+ "__docId__": 698,
"kind": "member",
"static": false,
"variation": null,
@@ -14538,7 +14576,7 @@
}
},
{
- "__docId__": 698,
+ "__docId__": 699,
"kind": "member",
"static": false,
"variation": null,
@@ -14558,7 +14596,7 @@
}
},
{
- "__docId__": 699,
+ "__docId__": 700,
"kind": "member",
"static": false,
"variation": null,
@@ -14578,7 +14616,7 @@
}
},
{
- "__docId__": 700,
+ "__docId__": 701,
"kind": "member",
"static": false,
"variation": null,
@@ -14598,7 +14636,7 @@
}
},
{
- "__docId__": 701,
+ "__docId__": 702,
"kind": "member",
"static": false,
"variation": null,
@@ -14618,7 +14656,7 @@
}
},
{
- "__docId__": 702,
+ "__docId__": 703,
"kind": "member",
"static": false,
"variation": null,
@@ -14638,7 +14676,7 @@
}
},
{
- "__docId__": 703,
+ "__docId__": 704,
"kind": "member",
"static": false,
"variation": null,
@@ -14658,7 +14696,7 @@
}
},
{
- "__docId__": 704,
+ "__docId__": 705,
"kind": "member",
"static": false,
"variation": null,
@@ -14678,7 +14716,7 @@
}
},
{
- "__docId__": 705,
+ "__docId__": 706,
"kind": "member",
"static": false,
"variation": null,
@@ -14698,7 +14736,7 @@
}
},
{
- "__docId__": 706,
+ "__docId__": 707,
"kind": "member",
"static": false,
"variation": null,
@@ -14718,7 +14756,7 @@
}
},
{
- "__docId__": 707,
+ "__docId__": 708,
"kind": "member",
"static": false,
"variation": null,
@@ -14738,7 +14776,7 @@
}
},
{
- "__docId__": 708,
+ "__docId__": 709,
"kind": "member",
"static": false,
"variation": null,
@@ -14758,7 +14796,7 @@
}
},
{
- "__docId__": 709,
+ "__docId__": 710,
"kind": "member",
"static": false,
"variation": null,
@@ -14778,7 +14816,7 @@
}
},
{
- "__docId__": 710,
+ "__docId__": 711,
"kind": "member",
"static": false,
"variation": null,
@@ -14798,7 +14836,7 @@
}
},
{
- "__docId__": 711,
+ "__docId__": 712,
"kind": "member",
"static": false,
"variation": null,
@@ -14818,7 +14856,7 @@
}
},
{
- "__docId__": 712,
+ "__docId__": 713,
"kind": "member",
"static": false,
"variation": null,
@@ -14838,7 +14876,7 @@
}
},
{
- "__docId__": 713,
+ "__docId__": 714,
"kind": "member",
"static": false,
"variation": null,
@@ -14858,7 +14896,7 @@
}
},
{
- "__docId__": 714,
+ "__docId__": 715,
"kind": "method",
"static": false,
"variation": null,
@@ -14872,7 +14910,7 @@
"generator": false
},
{
- "__docId__": 715,
+ "__docId__": 716,
"kind": "member",
"static": false,
"variation": null,
@@ -14890,7 +14928,7 @@
}
},
{
- "__docId__": 716,
+ "__docId__": 717,
"kind": "member",
"static": false,
"variation": null,
@@ -14908,7 +14946,7 @@
}
},
{
- "__docId__": 717,
+ "__docId__": 718,
"kind": "member",
"static": false,
"variation": null,
@@ -14926,7 +14964,7 @@
}
},
{
- "__docId__": 718,
+ "__docId__": 719,
"kind": "member",
"static": false,
"variation": null,
@@ -14949,7 +14987,7 @@
}
},
{
- "__docId__": 719,
+ "__docId__": 720,
"kind": "method",
"static": false,
"variation": null,
@@ -14976,7 +15014,7 @@
"generator": false
},
{
- "__docId__": 720,
+ "__docId__": 721,
"kind": "method",
"static": false,
"variation": null,
@@ -14990,7 +15028,7 @@
"generator": false
},
{
- "__docId__": 721,
+ "__docId__": 722,
"kind": "member",
"static": false,
"variation": null,
@@ -15008,7 +15046,7 @@
}
},
{
- "__docId__": 722,
+ "__docId__": 723,
"kind": "member",
"static": false,
"variation": null,
@@ -15026,7 +15064,7 @@
}
},
{
- "__docId__": 723,
+ "__docId__": 724,
"kind": "member",
"static": false,
"variation": null,
@@ -15044,7 +15082,7 @@
}
},
{
- "__docId__": 724,
+ "__docId__": 725,
"kind": "member",
"static": false,
"variation": null,
@@ -15062,7 +15100,7 @@
}
},
{
- "__docId__": 725,
+ "__docId__": 726,
"kind": "file",
"static": true,
"variation": null,
@@ -15075,7 +15113,7 @@
"content": "\nimport Cookie from '../cookie';\nimport {root} from '../root';\n\nconst JSON = root.JSON;\nconst localStorage = root.localStorage;\nconst location = root.location;\n\n/**\n * Checks if browser has Storage feature\n */\nexport const hasStorage = () => {\n return 'Storage' in root;\n};\n\n/**\n * Stores the features state in browser's local storage or cookie\n *\n * @export\n * @class Storage\n */\nexport class Storage {\n\n /**\n * Creates an instance of Storage\n *\n * @param {State} state Instance of State\n */\n constructor(state) {\n\n /**\n * State object\n * @type {State}\n * @private\n */\n this.state = state;\n\n /**\n * TableFilter object\n * @type {TableFilter}\n * @private\n */\n this.tf = state.tf;\n\n /**\n * Persist with local storage\n * @type {Boolean}\n * @private\n */\n this.enableLocalStorage = state.enableLocalStorage && hasStorage();\n\n /**\n * Persist with cookie\n * @type {Boolean}\n * @private\n */\n this.enableCookie = state.enableCookie && !this.enableLocalStorage;\n\n /**\n * Emitter object\n * @type {Emitter}\n * @private\n */\n this.emitter = state.emitter;\n\n /**\n * Cookie duration in hours from state object\n * @type {Number}\n * @private\n */\n this.duration = state.cookieDuration;\n }\n\n\n /**\n * Initializes the Storage object\n */\n init() {\n this.emitter.on(['state-changed'], (tf, state) => this.save(state));\n this.emitter.on(['initialized'], () => this.sync());\n }\n\n /**\n * Persists the features state on state changes\n *\n * @param {State} state Instance of State\n */\n save(state) {\n if (this.enableLocalStorage) {\n localStorage[this.getKey()] = JSON.stringify(state);\n } else {\n Cookie.write(this.getKey(), JSON.stringify(state), this.duration);\n }\n }\n\n /**\n * Turns stored string into a State JSON object\n *\n * @returns {Object} JSON object\n */\n retrieve() {\n let state = null;\n if (this.enableLocalStorage) {\n state = localStorage[this.getKey()];\n } else {\n state = Cookie.read(this.getKey());\n }\n\n if (!state) {\n return null;\n }\n return JSON.parse(state);\n }\n\n /**\n * Removes persisted state from storage\n */\n remove() {\n if (this.enableLocalStorage) {\n localStorage.removeItem(this.getKey());\n } else {\n Cookie.remove(this.getKey());\n }\n }\n\n /**\n * Applies persisted state to features\n */\n sync() {\n let state = this.retrieve();\n if (!state) {\n return;\n }\n // override current state with persisted one and sync features\n this.state.overrideAndSync(state);\n }\n\n /**\n * Returns the storage key\n *\n * @returns {String} Key\n */\n getKey() {\n return JSON.stringify({\n key: `${this.tf.prfxTf}_${this.tf.id}`,\n path: location.pathname\n });\n }\n\n /**\n * Release Storage event subscriptions and clear fields\n */\n destroy() {\n this.emitter.off(['state-changed'], (tf, state) => this.save(state));\n this.emitter.off(['initialized'], () => this.sync());\n\n this.remove();\n\n this.state = null;\n this.emitter = null;\n }\n}\n"
},
{
- "__docId__": 726,
+ "__docId__": 727,
"kind": "variable",
"static": true,
"variation": null,
@@ -15096,7 +15134,7 @@
}
},
{
- "__docId__": 727,
+ "__docId__": 728,
"kind": "variable",
"static": true,
"variation": null,
@@ -15117,7 +15155,7 @@
}
},
{
- "__docId__": 728,
+ "__docId__": 729,
"kind": "variable",
"static": true,
"variation": null,
@@ -15138,7 +15176,7 @@
}
},
{
- "__docId__": 729,
+ "__docId__": 730,
"kind": "variable",
"static": true,
"variation": null,
@@ -15158,7 +15196,7 @@
}
},
{
- "__docId__": 730,
+ "__docId__": 731,
"kind": "class",
"static": true,
"variation": null,
@@ -15184,7 +15222,7 @@
"interface": false
},
{
- "__docId__": 731,
+ "__docId__": 732,
"kind": "constructor",
"static": false,
"variation": null,
@@ -15209,7 +15247,7 @@
"generator": false
},
{
- "__docId__": 732,
+ "__docId__": 733,
"kind": "member",
"static": false,
"variation": null,
@@ -15229,7 +15267,7 @@
}
},
{
- "__docId__": 733,
+ "__docId__": 734,
"kind": "member",
"static": false,
"variation": null,
@@ -15249,7 +15287,7 @@
}
},
{
- "__docId__": 734,
+ "__docId__": 735,
"kind": "member",
"static": false,
"variation": null,
@@ -15269,7 +15307,7 @@
}
},
{
- "__docId__": 735,
+ "__docId__": 736,
"kind": "member",
"static": false,
"variation": null,
@@ -15289,7 +15327,7 @@
}
},
{
- "__docId__": 736,
+ "__docId__": 737,
"kind": "member",
"static": false,
"variation": null,
@@ -15309,7 +15347,7 @@
}
},
{
- "__docId__": 737,
+ "__docId__": 738,
"kind": "member",
"static": false,
"variation": null,
@@ -15329,7 +15367,7 @@
}
},
{
- "__docId__": 738,
+ "__docId__": 739,
"kind": "method",
"static": false,
"variation": null,
@@ -15343,7 +15381,7 @@
"generator": false
},
{
- "__docId__": 739,
+ "__docId__": 740,
"kind": "method",
"static": false,
"variation": null,
@@ -15368,7 +15406,7 @@
"generator": false
},
{
- "__docId__": 740,
+ "__docId__": 741,
"kind": "method",
"static": false,
"variation": null,
@@ -15396,7 +15434,7 @@
"generator": false
},
{
- "__docId__": 741,
+ "__docId__": 742,
"kind": "method",
"static": false,
"variation": null,
@@ -15410,7 +15448,7 @@
"generator": false
},
{
- "__docId__": 742,
+ "__docId__": 743,
"kind": "method",
"static": false,
"variation": null,
@@ -15424,7 +15462,7 @@
"generator": false
},
{
- "__docId__": 743,
+ "__docId__": 744,
"kind": "method",
"static": false,
"variation": null,
@@ -15452,7 +15490,7 @@
"generator": false
},
{
- "__docId__": 744,
+ "__docId__": 745,
"kind": "method",
"static": false,
"variation": null,
@@ -15466,7 +15504,7 @@
"generator": false
},
{
- "__docId__": 745,
+ "__docId__": 746,
"kind": "member",
"static": false,
"variation": null,
@@ -15484,7 +15522,7 @@
}
},
{
- "__docId__": 746,
+ "__docId__": 747,
"kind": "member",
"static": false,
"variation": null,
@@ -15502,7 +15540,7 @@
}
},
{
- "__docId__": 747,
+ "__docId__": 748,
"kind": "file",
"static": true,
"variation": null,
@@ -15515,7 +15553,7 @@
"content": "/**\n * Export window or global object depending on the environment\n */\nexport const root = (typeof self === 'object' && self.self === self && self) ||\n (typeof global === 'object' && global.global === global && global) ||\n this;\n"
},
{
- "__docId__": 748,
+ "__docId__": 749,
"kind": "variable",
"static": true,
"variation": null,
@@ -15535,7 +15573,7 @@
}
},
{
- "__docId__": 749,
+ "__docId__": 750,
"kind": "file",
"static": true,
"variation": null,
@@ -15548,7 +15586,7 @@
"content": "/**\n * Sorting utilities\n */\n\n/**\n * Case insensitive compare function for passed strings\n * @param {String} First string\n * @param {String} Second string\n * @return {Number} -1 if first string lower than second one\n * 0 if first string same order as second one\n * 1 if first string greater than second one\n */\nexport const ignoreCase = (a, b) => {\n let x = a.toLowerCase();\n let y = b.toLowerCase();\n return ((x < y) ? -1 : ((x > y) ? 1 : 0));\n}\n\n/**\n * Sorts passed numbers in a ascending manner\n * @param {Number} First number\n * @param {Number} Second number\n * @param {Number} Negative, zero or positive number\n */\nexport const numSortAsc = (a, b) => (a - b);\n\n/**\n * Sorts passed numbers in a descending manner\n * @param {Number} First number\n * @param {Number} Second number\n * @param {Number} Negative, zero or positive number\n */\nexport const numSortDesc = (a, b) => (b - a);\n"
},
{
- "__docId__": 750,
+ "__docId__": 751,
"kind": "variable",
"static": true,
"variation": null,
@@ -15598,7 +15636,7 @@
}
},
{
- "__docId__": 751,
+ "__docId__": 752,
"kind": "variable",
"static": true,
"variation": null,
@@ -15650,7 +15688,7 @@
}
},
{
- "__docId__": 752,
+ "__docId__": 753,
"kind": "variable",
"static": true,
"variation": null,
@@ -15702,7 +15740,7 @@
}
},
{
- "__docId__": 753,
+ "__docId__": 754,
"kind": "file",
"static": true,
"variation": null,
@@ -15715,7 +15753,7 @@
"content": "/**\n * String utilities\n */\n\n/**\n * Removes whitespace from both sides of passed string\n * @param {String} text\n * @return {String}\n */\nexport const trim = text => {\n if (text.trim) {\n return text.trim();\n }\n return text.replace(/^\\s*|\\s*$/g, '');\n}\n\n/**\n * Checks if passed string is empty\n * @param {String} text\n * @return {Boolean}\n */\nexport const isEmpty = (text) => trim(text) === '';\n\n/**\n * Makes regex safe string by escaping special characters from passed string\n * @param {String} text\n * @return {String} escaped string\n */\nexport const rgxEsc = text => {\n let chars = /[-\\/\\\\^$*+?.()|[\\]{}]/g;\n let escMatch = '\\\\$&';\n return String(text).replace(chars, escMatch);\n}\n\n/**\n * Returns passed string as lowercase if caseSensitive flag set false. By\n * default it returns the string with no casing changes.\n * @param {String} text\n * @return {String} string\n */\nexport const matchCase = (text, caseSensitive = false) => {\n if (!caseSensitive) {\n return text.toLowerCase();\n }\n return text;\n}\n\n/**\n * Checks if passed data contains the searched term\n * @param {String} term Searched term\n * @param {String} data Data string\n * @param {Boolean} exactMatch Exact match\n * @param {Boolean} caseSensitive Case sensitive\n * @return {Boolean}\n */\nexport const contains =\n (term, data, exactMatch = false, caseSensitive = false) => {\n // Improved by Cedric Wartel (cwl) automatic exact match for selects and\n // special characters are now filtered\n let regexp;\n let modifier = caseSensitive ? 'g' : 'gi';\n if (exactMatch) {\n regexp = new RegExp('(^\\\\s*)' + rgxEsc(term) + '(\\\\s*$)',\n modifier);\n } else {\n regexp = new RegExp(rgxEsc(term), modifier);\n }\n return regexp.test(data);\n }\n"
},
{
- "__docId__": 754,
+ "__docId__": 755,
"kind": "variable",
"static": true,
"variation": null,
@@ -15755,7 +15793,7 @@
}
},
{
- "__docId__": 755,
+ "__docId__": 756,
"kind": "variable",
"static": true,
"variation": null,
@@ -15795,7 +15833,7 @@
}
},
{
- "__docId__": 756,
+ "__docId__": 757,
"kind": "variable",
"static": true,
"variation": null,
@@ -15835,7 +15873,7 @@
}
},
{
- "__docId__": 757,
+ "__docId__": 758,
"kind": "variable",
"static": true,
"variation": null,
@@ -15875,7 +15913,7 @@
}
},
{
- "__docId__": 758,
+ "__docId__": 759,
"kind": "variable",
"static": true,
"variation": null,
@@ -15945,7 +15983,7 @@
}
},
{
- "__docId__": 759,
+ "__docId__": 760,
"kind": "file",
"static": true,
"variation": null,
@@ -15955,10 +15993,10 @@
"access": null,
"description": null,
"lineNumber": 1,
- "content": "import {addEvt, cancelEvt, stopEvt, targetEvt, keyCode} from './event';\nimport {\n addClass, createElm, createOpt, elm, getText, getFirstTextNode, hasClass,\n removeClass, removeElm, tag\n} from './dom';\nimport {contains, matchCase, rgxEsc, trim} from './string';\nimport {isEmpty as isEmptyString} from './string';\nimport {isArray, isEmpty, isFn, isNumber, isObj, isString, isUndef}\nfrom './types';\nimport {formatDate, isValidDate} from './date';\nimport {removeNbFormat} from './helpers';\n\nimport {root} from './root';\nimport {Emitter} from './emitter';\nimport {GridLayout} from './modules/gridLayout';\nimport {Loader} from './modules/loader';\nimport {HighlightKeyword} from './modules/highlightKeywords';\nimport {PopupFilter} from './modules/popupFilter';\nimport {Dropdown} from './modules/dropdown';\nimport {CheckList} from './modules/checkList';\nimport {RowsCounter} from './modules/rowsCounter';\nimport {StatusBar} from './modules/statusBar';\nimport {Paging} from './modules/paging';\nimport {ClearButton} from './modules/clearButton';\nimport {Help} from './modules/help';\nimport {AlternateRows} from './modules/alternateRows';\nimport {NoResults} from './modules/noResults';\nimport {State} from './modules/state';\n\nimport {\n INPUT, SELECT, MULTIPLE, CHECKLIST, NONE,\n ENTER_KEY, TAB_KEY, ESC_KEY, UP_ARROW_KEY, DOWN_ARROW_KEY,\n CELL_TAG, AUTO_FILTER_DELAY\n} from './const';\n\nlet doc = root.document;\n\n/**\n * Makes HTML tables filterable and a bit more :)\n *\n * @export\n * @class TableFilter\n */\nexport class TableFilter {\n\n /**\n * Creates an instance of TableFilter\n * requires `table` or `id` arguments, `row` and `configuration` optional\n * @param {DOMElement} table Table DOM element\n * @param {String} id Table id\n * @param {Number} row index indicating the 1st row\n * @param {Object} configuration object\n */\n constructor(...args) {\n /**\n * ID of current instance\n * @type {String}\n * @private\n */\n this.id = null;\n\n /**\n * Current version\n * @type {String}\n */\n this.version = '{VERSION}';\n\n /**\n * Current year\n * @type {Number}\n * @private\n */\n this.year = new Date().getFullYear();\n\n /**\n * HTML Table DOM element\n * @type {DOMElement}\n */\n this.tbl = null;\n\n /**\n * Calculated row's index from which starts filtering once filters\n * are generated\n * @type {Number}\n */\n this.refRow = null;\n\n /**\n * Index of the headers row\n * @type {Number}\n * @private\n */\n this.headersRow = null;\n\n /**\n * Configuration object\n * @type {Object}\n * @private\n */\n this.cfg = {};\n\n /**\n * Number of rows that can be filtered\n * @type {Number}\n * @private\n */\n this.nbFilterableRows = 0;\n\n /**\n * Number of cells in the reference row\n * @type {Number}\n * @private\n */\n this.nbCells = null;\n\n let startRow;\n\n // TODO: use for-of\n args.forEach((arg) => {\n if (typeof arg === 'object' && arg.nodeName === 'TABLE') {\n this.tbl = arg;\n this.id = arg.id || `tf_${new Date().getTime()}_`;\n } else if (isString(arg)) {\n this.id = arg;\n this.tbl = elm(arg);\n } else if (isNumber(arg)) {\n startRow = arg;\n } else if (isObj(arg)) {\n this.cfg = arg;\n }\n });\n\n if (!this.tbl || this.tbl.nodeName !== 'TABLE' ||\n this.getRowsNb() === 0) {\n throw new Error(`Could not instantiate TableFilter: HTML table\n DOM element not found.`);\n }\n\n // configuration object\n let f = this.cfg;\n\n /**\n * Event emitter instance\n * @type {Emitter}\n */\n this.emitter = new Emitter();\n\n //Start row et cols nb\n this.refRow = isUndef(startRow) ? 2 : (startRow + 1);\n try { this.nbCells = this.getCellsNb(this.refRow); }\n catch (e) { this.nbCells = this.getCellsNb(0); }\n\n /**\n * Base path for static assets\n * @type {String}\n */\n this.basePath = f.base_path || 'tablefilter/';\n\n /*** filters' grid properties ***/\n\n /**\n * Enable/disable filters\n * @type {Boolean}\n */\n this.fltGrid = f.grid === false ? false : true;\n\n /**\n * Enable/disable grid layout (fixed headers)\n * @type {Boolean}\n */\n this.gridLayout = Boolean(f.grid_layout);\n\n /**\n * Filters row index\n * @type {Number}\n */\n this.filtersRowIndex = isNaN(f.filters_row_index) ?\n 0 : f.filters_row_index;\n\n /**\n * Headers row index\n * @type {Number}\n */\n this.headersRow = isNaN(f.headers_row_index) ?\n (this.filtersRowIndex === 0 ? 1 : 0) : f.headers_row_index;\n\n /**\n * Define the type of cell containing a filter (td/th)\n * @type {String}\n */\n this.fltCellTag = isString(f.filters_cell_tag) ?\n f.filters_cell_tag : CELL_TAG;\n\n /**\n * List of filters IDs\n * @type {Array}\n * @private\n */\n this.fltIds = [];\n\n /**\n * List of valid rows indexes (rows visible upon filtering)\n * @type {Array}\n * @private\n */\n this.validRowsIndex = [];\n\n /**\n * Toolbar's container DOM element\n * @type {DOMElement}\n * @private\n */\n this.infDiv = null;\n\n /**\n * Left-side inner container DOM element (rows counter in toolbar)\n * @type {DOMElement}\n * @private\n */\n this.lDiv = null;\n\n /**\n * Right-side inner container DOM element (reset button,\n * page length selector in toolbar)\n * @type {DOMElement}\n * @private\n */\n this.rDiv = null;\n\n /**\n * Middle inner container DOM element (paging elements in toolbar)\n * @type {DOMElement}\n * @private\n */\n this.mDiv = null;\n\n /**\n * Css class for toolbar's container DOM element\n * @type {String}\n */\n this.infDivCssClass = f.inf_div_css_class || 'inf';\n\n /**\n * Css class for left-side inner container DOM element\n * @type {String}\n */\n this.lDivCssClass = f.left_div_css_class || 'ldiv';\n\n /**\n * Css class for right-side inner container DOM element\n * @type {String}\n */\n this.rDivCssClass = f.right_div_css_class || 'rdiv';\n\n /**\n * Css class for middle inner container DOM element\n * @type {String}\n */\n this.mDivCssClass = f.middle_div_css_class || 'mdiv';\n\n /*** filters' grid appearance ***/\n /**\n * Path for stylesheets\n * @type {String}\n */\n this.stylePath = f.style_path || this.basePath + 'style/';\n\n /**\n * Main stylesheet path\n * @type {String}\n */\n this.stylesheet = f.stylesheet || this.stylePath + 'tablefilter.css';\n\n /**\n * Main stylesheet ID\n * @type {String}\n * @private\n */\n this.stylesheetId = this.id + '_style';\n\n /**\n * Css class for the filters row\n * @type {String}\n */\n this.fltsRowCssClass = f.flts_row_css_class || 'fltrow';\n\n /**\n * Enable/disable icons (paging, reset button)\n * @type {Boolean}\n */\n this.enableIcons = f.enable_icons === false ? false : true;\n\n /**\n * Enable/disable alternating rows\n * @type {Boolean}\n */\n this.alternateRows = Boolean(f.alternate_rows);\n\n /**\n * Indicate whether columns widths are set\n * @type {Boolean}\n * @private\n */\n this.hasColWidths = isArray(f.col_widths);\n\n /**\n * Columns widths array\n * @type {Array}\n */\n this.colWidths = this.hasColWidths ? f.col_widths : [];\n\n /**\n * Css class for a filter element\n * @type {String}\n */\n this.fltCssClass = f.flt_css_class || 'flt';\n\n /**\n * Css class for multiple select filters\n * @type {String}\n */\n this.fltMultiCssClass = f.flt_multi_css_class || 'flt_multi';\n\n /**\n * Css class for small filter (when submit button is active)\n * @type {String}\n */\n this.fltSmallCssClass = f.flt_small_css_class || 'flt_s';\n\n /**\n * Css class for single filter type\n * @type {String}\n */\n this.singleFltCssClass = f.single_flt_css_class || 'single_flt';\n\n /*** filters' grid behaviours ***/\n\n /**\n * Enable/disable enter key for input type filters\n * @type {Boolean}\n */\n this.enterKey = f.enter_key === false ? false : true;\n\n /**\n * Callback fired before filtering process starts\n * @type {Function}\n */\n this.onBeforeFilter = isFn(f.on_before_filter) ?\n f.on_before_filter : null;\n\n /**\n * Callback fired after filtering process is completed\n * @type {Function}\n */\n this.onAfterFilter = isFn(f.on_after_filter) ? f.on_after_filter : null;\n\n /**\n * Enable/disable case sensitivity filtering\n * @type {Boolean}\n */\n this.caseSensitive = Boolean(f.case_sensitive);\n\n /**\n * Indicate whether exact match filtering is enabled on a per column\n * basis\n * @type {Boolean}\n * @private\n */\n this.hasExactMatchByCol = isArray(f.columns_exact_match);\n\n /**\n * Exact match filtering per column array\n * @type {Array}\n */\n this.exactMatchByCol = this.hasExactMatchByCol ?\n f.columns_exact_match : [];\n\n /**\n * Globally enable/disable exact match filtering\n * @type {Boolean}\n */\n this.exactMatch = Boolean(f.exact_match);\n\n /**\n * Enable/disable linked filters filtering mode\n * @type {Boolean}\n */\n this.linkedFilters = Boolean(f.linked_filters);\n\n /**\n * Enable/disable readonly state for excluded options when\n * linked filters filtering mode is on\n * @type {Boolean}\n */\n this.disableExcludedOptions = Boolean(f.disable_excluded_options);\n\n /**\n * Active filter ID\n * @type {String}\n * @private\n */\n this.activeFilterId = null;\n\n /**\n * Enable/disable always visible rows, excluded from filtering\n * @type {Boolean}\n */\n this.hasVisibleRows = Boolean(f.rows_always_visible);\n\n /**\n * List of row indexes to be excluded from filtering\n * @type {Array}\n */\n this.visibleRows = this.hasVisibleRows ? f.rows_always_visible : [];\n\n /**\n * Enable/disable external filters generation\n * @type {Boolean}\n */\n this.isExternalFlt = Boolean(f.external_flt_grid);\n\n /**\n * List of containers IDs where external filters will be generated\n * @type {Array}\n */\n this.externalFltTgtIds = f.external_flt_grid_ids || [];\n\n /**\n * Callback fired after filters are generated\n * @type {Function}\n */\n this.onFiltersLoaded = isFn(f.on_filters_loaded) ?\n f.on_filters_loaded : null;\n\n /**\n * Enable/disable single filter filtering all columns\n * @type {Boolean}\n */\n this.singleSearchFlt = Boolean(f.single_filter);\n\n /**\n * Callback fired after a row is validated during filtering\n * @type {Function}\n */\n this.onRowValidated = isFn(f.on_row_validated) ?\n f.on_row_validated : null;\n\n /**\n * List of columns implementing custom filtering\n * @type {Array}\n */\n this.customCellDataCols = f.custom_cell_data_cols ?\n f.custom_cell_data_cols : [];\n\n /**\n * Delegate function for retrieving cell data with custom logic\n * @type {Function}\n */\n this.customCellData = isFn(f.custom_cell_data) ?\n f.custom_cell_data : null;\n\n /**\n * Global watermark text for input filter type or watermark for each\n * filter if an array is supplied\n * @type {String|Array}\n */\n this.watermark = f.watermark || '';\n\n /**\n * Indicate whether watermark is on a per column basis\n * @type {Boolean}\n * @private\n */\n this.isWatermarkArray = isArray(this.watermark);\n\n /**\n * Toolbar's custom container ID\n * @type {String}\n */\n this.toolBarTgtId = f.toolbar_target_id || null;\n\n /**\n * Indicate whether help UI component is disabled\n * @type {Boolean}\n */\n this.help = isUndef(f.help_instructions) ?\n undefined : Boolean(f.help_instructions);\n\n /**\n * Indicate whether pop-up filters UI is enabled\n * @type {Boolean}\n */\n this.popupFilters = Boolean(f.popup_filters);\n\n /**\n * Indicate whether filtered (active) columns indicator is enabled\n * @type {Boolean}\n */\n this.markActiveColumns = Boolean(f.mark_active_columns);\n\n /**\n * Css class for filtered (active) columns\n * @type {String}\n */\n this.activeColumnsCssClass = f.active_columns_css_class ||\n 'activeHeader';\n\n /**\n * Callback fired before a column is marked as filtered\n * @type {Function}\n */\n this.onBeforeActiveColumn = isFn(f.on_before_active_column) ?\n f.on_before_active_column : null;\n\n /**\n * Callback fired after a column is marked as filtered\n * @type {Function}\n */\n this.onAfterActiveColumn = isFn(f.on_after_active_column) ?\n f.on_after_active_column : null;\n\n /*** select filter's customisation and behaviours ***/\n /**\n * Text for clear option in drop-down filter types (1st option)\n * @type {String}\n */\n this.displayAllText = f.display_all_text || 'Clear';\n\n /**\n * Indicate whether empty option is enabled in drop-down filter types\n * @type {Boolean}\n */\n this.enableEmptyOption = Boolean(f.enable_empty_option);\n\n /**\n * Text for empty option in drop-down filter types\n * @type {String}\n */\n this.emptyText = f.empty_text || '(Empty)';\n\n /**\n * Indicate whether non-empty option is enabled in drop-down filter\n * types\n * @type {Boolean}\n */\n this.enableNonEmptyOption = Boolean(f.enable_non_empty_option);\n\n /**\n * Text for non-empty option in drop-down filter types\n * @type {String}\n */\n this.nonEmptyText = f.non_empty_text || '(Non empty)';\n\n /**\n * Indicate whether drop-down filter types filter the table by default\n * on change event\n * @type {Boolean}\n */\n this.onSlcChange = f.on_change === false ? false : true;\n\n /**\n * Indicate whether options in drop-down filter types are sorted in a\n * alpha-numeric manner by default\n * @type {Boolean}\n */\n this.sortSlc = f.sort_select === false ? false : true;\n\n /**\n * Indicate whether options in drop-down filter types are sorted in a\n * ascending numeric manner\n * @type {Boolean}\n * @private\n */\n this.isSortNumAsc = Boolean(f.sort_num_asc);\n\n /**\n * List of columns implementing options sorting in a ascending numeric\n * manner\n * @type {Array}\n */\n this.sortNumAsc = this.isSortNumAsc ? f.sort_num_asc : [];\n\n /**\n * Indicate whether options in drop-down filter types are sorted in a\n * descending numeric manner\n * @type {Boolean}\n * @private\n */\n this.isSortNumDesc = Boolean(f.sort_num_desc);\n\n /**\n * List of columns implementing options sorting in a descending numeric\n * manner\n * @type {Array}\n */\n this.sortNumDesc = this.isSortNumDesc ? f.sort_num_desc : [];\n\n /**\n * Indicate whether drop-down filter types are populated on demand at\n * first usage\n * @type {Boolean}\n */\n this.loadFltOnDemand = Boolean(f.load_filters_on_demand);\n\n /**\n * Indicate whether custom drop-down filter options are implemented\n * @type {Boolean}\n */\n this.hasCustomOptions = isObj(f.custom_options);\n\n /**\n * Custom options definition of a per column basis, ie:\n *\tcustom_options: {\n * cols:[0, 1],\n * texts: [\n * ['a0', 'b0', 'c0'],\n * ['a1', 'b1', 'c1']\n * ],\n * values: [\n * ['a0', 'b0', 'c0'],\n * ['a1', 'b1', 'c1']\n * ],\n * sorts: [false, true]\n * }\n *\n * @type {Object}\n */\n this.customOptions = f.custom_options;\n\n /*** Filter operators ***/\n /**\n * Regular expression operator for input filter. Defaults to 'rgx:'\n * @type {String}\n */\n this.rgxOperator = f.regexp_operator || 'rgx:';\n\n /**\n * Empty cells operator for input filter. Defaults to '[empty]'\n * @type {String}\n */\n this.emOperator = f.empty_operator || '[empty]';\n\n /**\n * Non-empty cells operator for input filter. Defaults to '[nonempty]'\n * @type {String}\n */\n this.nmOperator = f.nonempty_operator || '[nonempty]';\n\n /**\n * Logical OR operator for input filter. Defaults to '||'\n * @type {String}\n */\n this.orOperator = f.or_operator || '||';\n\n /**\n * Logical AND operator for input filter. Defaults to '&&'\n * @type {String}\n */\n this.anOperator = f.and_operator || '&&';\n\n /**\n * Greater than operator for input filter. Defaults to '>'\n * @type {String}\n */\n this.grOperator = f.greater_operator || '>';\n\n /**\n * Lower than operator for input filter. Defaults to '<'\n * @type {String}\n */\n this.lwOperator = f.lower_operator || '<';\n\n /**\n * Lower than or equal operator for input filter. Defaults to '<='\n * @type {String}\n */\n this.leOperator = f.lower_equal_operator || '<=';\n\n /**\n * Greater than or equal operator for input filter. Defaults to '>='\n * @type {String}\n */\n this.geOperator = f.greater_equal_operator || '>=';\n\n /**\n * Inequality operator for input filter. Defaults to '!'\n * @type {String}\n */\n this.dfOperator = f.different_operator || '!';\n\n /**\n * Like operator for input filter. Defaults to '!'\n * @type {String}\n */\n this.lkOperator = f.like_operator || '*';\n\n /**\n * Strict equality operator for input filter. Defaults to '='\n * @type {String}\n */\n this.eqOperator = f.equal_operator || '=';\n\n /**\n * Starts with operator for input filter. Defaults to '='\n * @type {String}\n */\n this.stOperator = f.start_with_operator || '{';\n\n /**\n * Ends with operator for input filter. Defaults to '='\n * @type {String}\n */\n this.enOperator = f.end_with_operator || '}';\n\n // this.curExp = f.cur_exp || '^[¥£€$]';\n\n /**\n * Stored values separator\n * @type {String}\n */\n this.separator = f.separator || ',';\n\n /**\n * Enable rows counter UI component\n * @type {Boolean}\n */\n this.rowsCounter = Boolean(f.rows_counter);\n\n /**\n * Enable status bar UI component\n * @type {Boolean}\n */\n this.statusBar = Boolean(f.status_bar);\n\n /**\n * Enable activity/spinner indicator UI component\n * @type {Boolean}\n */\n this.loader = Boolean(f.loader);\n\n /*** validation - reset buttons/links ***/\n /**\n * Enable filters submission button\n * @type {Boolean}\n */\n this.displayBtn = Boolean(f.btn);\n\n /**\n * Define filters submission button text\n * @type {String}\n */\n this.btnText = f.btn_text || (!this.enableIcons ? 'Go' : '');\n\n /**\n * Css class for filters submission button\n * @type {String}\n */\n this.btnCssClass = f.btn_css_class ||\n (!this.enableIcons ? 'btnflt' : 'btnflt_icon');\n\n /**\n * Enable clear button\n * @type {Boolean}\n */\n this.btnReset = Boolean(f.btn_reset);\n\n /**\n * Css class for reset button\n * @type {String}\n */\n this.btnResetCssClass = f.btn_reset_css_class || 'reset';\n\n /**\n * Callback fired before filters are cleared\n * @type {Function}\n */\n this.onBeforeReset = isFn(f.on_before_reset) ?\n f.on_before_reset : null;\n\n /**\n * Callback fired after filters are cleared\n * @type {Function}\n */\n this.onAfterReset = isFn(f.on_after_reset) ? f.on_after_reset : null;\n\n /**\n * Enable paging component\n * @type {Boolean}\n */\n this.paging = Boolean(f.paging);\n\n /**\n * Number of hidden rows\n * @type {Number}\n * @private\n */\n this.nbHiddenRows = 0;\n\n /**\n * Enable auto-filter behaviour, table is filtered when a user\n * stops typing\n * @type {Boolean}\n */\n this.autoFilter = Boolean(f.auto_filter);\n\n /**\n * Auto-filter delay in msecs\n * @type {Number}\n */\n this.autoFilterDelay = !isNaN(f.auto_filter_delay) ?\n f.auto_filter_delay : AUTO_FILTER_DELAY;\n\n /**\n * Indicate whether user is typing\n * @type {Boolean}\n * @private\n */\n this.isUserTyping = null;\n\n /**\n * Auto-filter interval ID\n * @type {String}\n * @private\n */\n this.autoFilterTimer = null;\n\n /**\n * Enable keyword highlighting behaviour\n * @type {Boolean}\n */\n this.highlightKeywords = Boolean(f.highlight_keywords);\n\n /**\n * Enable no results message UI component\n * @type {Boolean}\n */\n this.noResults = isObj(f.no_results_message) ||\n Boolean(f.no_results_message);\n\n /**\n * Enable state persistence\n * @type {Boolean}\n */\n this.state = isObj(f.state) || Boolean(f.state);\n\n /*** data types ***/\n /**\n * Define default date type (DMY)\n * @type {String}\n */\n this.defaultDateType = f.default_date_type || 'DMY';\n\n /**\n * Define thousands separator ',' or '.', defaults to ','\n * @type {String}\n */\n this.thousandsSeparator = f.thousands_separator || ',';\n\n /**\n * Define decimal separator ',' or '.', defaults to '.'\n * @type {String}\n */\n this.decimalSeparator = f.decimal_separator || '.';\n\n /**\n * Determine whether table has columns with numeric formats\n * @type {Boolean}\n * @private\n */\n this.hasColNbFormat = isArray(f.col_number_format);\n\n /**\n * Define numeric format on a column basis, two possible values 'EU' and\n * 'US', ie:\n * col_number_format : [null, 'US', 'EU', null]\n * @type {Array}\n */\n this.colNbFormat = this.hasColNbFormat ? f.col_number_format : null;\n\n /**\n * Determine whether table has columns with date types\n * @type {Boolean}\n * @private\n */\n this.hasColDateType = isArray(f.col_date_type);\n\n /**\n * Define date format on a column basis, possible values 'DMY', 'MDY',\n * 'YMD', 'DDMMMYYYY', ie:\n * col_date_type : [null, 'DMY', 'MDY', 'YMD', null, 'DDMMMYYYY']\n * @type {Array}\n */\n this.colDateType = this.hasColDateType ? f.col_date_type : null;\n\n /*** ids prefixes ***/\n /**\n * Main prefix\n * @private\n */\n this.prfxTf = 'TF';\n\n /**\n * Filter's ID prefix (inputs - selects)\n * @private\n */\n this.prfxFlt = 'flt';\n\n /**\n * Button's ID prefix\n * @private\n */\n this.prfxValButton = 'btn';\n\n /**\n * Toolbar container ID prefix\n * @private\n */\n this.prfxInfDiv = 'inf_';\n\n /**\n * Toolbar left element ID prefix\n * @private\n */\n this.prfxLDiv = 'ldiv_';\n\n /**\n * Toolbar right element ID prefix\n * @private\n */\n this.prfxRDiv = 'rdiv_';\n\n /**\n * Toolbar middle element ID prefix\n * @private\n */\n this.prfxMDiv = 'mdiv_';\n\n /**\n * Responsive Css class\n * @private\n */\n this.prfxResponsive = 'resp';\n\n /*** extensions ***/\n /**\n * List of loaded extensions\n * @type {Array}\n * @private\n */\n this.extensions = f.extensions;\n\n /**\n * Determine whether extensions are loaded\n * @type {Boolean}\n * @private\n */\n this.hasExtensions = isArray(this.extensions);\n\n /*** themes ***/\n /**\n * Enable default theme\n * @type {Boolean}\n */\n this.enableDefaultTheme = Boolean(f.enable_default_theme);\n\n /**\n * Determine whether themes are enables\n * @type {Boolean}\n * @private\n */\n this.hasThemes = (this.enableDefaultTheme || isArray(f.themes));\n\n /**\n * List of themes, ie:\n * themes: [{ name: 'skyblue' }]\n * @type {Array}\n */\n this.themes = f.themes || [];\n\n /**\n * Define path to themes assets, defaults to\n * 'tablefilter/style/themes/'. Usage:\n * themes: [{ name: 'skyblue' }]\n * @type {Array}\n */\n this.themesPath = f.themes_path || this.stylePath + 'themes/';\n\n /**\n * Enable responsive layout\n * @type {Boolean}\n */\n this.responsive = Boolean(f.responsive);\n\n /**\n * Features registry\n * @private\n */\n this.Mod = {};\n\n /**\n * Extensions registry\n * @private\n */\n this.ExtRegistry = {};\n }\n\n /**\n * Initialise features and layout\n */\n init() {\n if (this.initialized) {\n return;\n }\n\n let Mod = this.Mod;\n let n = this.singleSearchFlt ? 1 : this.nbCells;\n let inpclass;\n\n //loads stylesheet if not imported\n this.import(this.stylesheetId, this.stylesheet, null, 'link');\n\n //loads theme\n if (this.hasThemes) {\n this.loadThemes();\n }\n\n // Instantiate help feature and initialise only if set true\n if (!Mod.help) {\n Mod.help = new Help(this);\n }\n if (this.help) {\n Mod.help.init();\n }\n\n if (this.state) {\n if (!Mod.state) {\n Mod.state = new State(this);\n }\n Mod.state.init();\n }\n\n if (this.gridLayout) {\n if (!Mod.gridLayout) {\n Mod.gridLayout = new GridLayout(this);\n }\n Mod.gridLayout.init();\n }\n\n if (this.loader) {\n if (!Mod.loader) {\n Mod.loader = new Loader(this);\n }\n Mod.loader.init();\n }\n\n if (this.highlightKeywords) {\n Mod.highlightKeyword = new HighlightKeyword(this);\n Mod.highlightKeyword.init();\n }\n\n if (this.popupFilters) {\n if (!Mod.popupFilter) {\n Mod.popupFilter = new PopupFilter(this);\n }\n Mod.popupFilter.init();\n }\n\n //filters grid is not generated\n if (!this.fltGrid) {\n this._initNoFilters();\n } else {\n let fltrow = this._insertFiltersRow();\n\n this.nbFilterableRows = this.getRowsNb();\n\n // Generate filters\n for (let i = 0; i < n; i++) {\n this.emitter.emit('before-filter-init', this, i);\n\n let fltcell = createElm(this.fltCellTag),\n col = this.getFilterType(i);\n\n if (this.singleSearchFlt) {\n fltcell.colSpan = this.nbCells;\n }\n if (!this.gridLayout) {\n fltrow.appendChild(fltcell);\n }\n inpclass = (i === n - 1 && this.displayBtn) ?\n this.fltSmallCssClass : this.fltCssClass;\n\n //only 1 input for single search\n if (this.singleSearchFlt) {\n col = INPUT;\n inpclass = this.singleFltCssClass;\n }\n\n //drop-down filters\n if (col === SELECT || col === MULTIPLE) {\n if (!Mod.dropdown) {\n Mod.dropdown = new Dropdown(this);\n }\n Mod.dropdown.init(i, this.isExternalFlt, fltcell);\n }\n // checklist\n else if (col === CHECKLIST) {\n if (!Mod.checkList) {\n Mod.checkList = new CheckList(this);\n }\n Mod.checkList.init(i, this.isExternalFlt, fltcell);\n } else {\n this._buildInputFilter(i, inpclass, fltcell);\n }\n\n // this adds submit button\n if (i === n - 1 && this.displayBtn) {\n this._buildSubmitButton(i, fltcell);\n }\n\n this.emitter.emit('after-filter-init', this, i);\n }\n\n this.emitter.on(['filter-focus'],\n (tf, filter) => this.setActiveFilterId(filter.id));\n\n }//if this.fltGrid\n\n /* Features */\n if (this.hasVisibleRows) {\n this.emitter.on(['after-filtering'],\n () => this.enforceVisibility());\n this.enforceVisibility();\n }\n if (this.rowsCounter) {\n Mod.rowsCounter = new RowsCounter(this);\n Mod.rowsCounter.init();\n }\n if (this.statusBar) {\n Mod.statusBar = new StatusBar(this);\n Mod.statusBar.init();\n }\n if (this.paging) {\n if (!Mod.paging) {\n Mod.paging = new Paging(this);\n Mod.paging.init();\n } else {\n Mod.paging.reset();\n }\n }\n if (this.btnReset) {\n Mod.clearButton = new ClearButton(this);\n Mod.clearButton.init();\n }\n\n if (this.hasColWidths && !this.gridLayout) {\n this.setColWidths();\n }\n if (this.alternateRows) {\n Mod.alternateRows = new AlternateRows(this);\n Mod.alternateRows.init();\n }\n if (this.noResults) {\n if (!Mod.noResults) {\n Mod.noResults = new NoResults(this);\n }\n Mod.noResults.init();\n }\n\n //TF css class is added to table\n if (!this.gridLayout) {\n addClass(this.tbl, this.prfxTf);\n if (this.responsive) {\n addClass(this.tbl, this.prfxResponsive);\n }\n }\n\n /* Loads extensions */\n if (this.hasExtensions) {\n this.initExtensions();\n }\n\n // Subscribe to events\n if (this.markActiveColumns) {\n this.emitter.on(['before-filtering'],\n () => this.clearActiveColumns());\n this.emitter.on(['cell-processed'],\n (tf, colIndex) => this.markActiveColumn(colIndex));\n }\n if (this.linkedFilters) {\n this.emitter.on(['after-filtering'], () => this.linkFilters());\n }\n\n /**\n * @inherited\n */\n this.initialized = true;\n\n if (this.onFiltersLoaded) {\n this.onFiltersLoaded.call(null, this);\n }\n this.emitter.emit('initialized', this);\n }\n\n /**\n * Detect key\n * @param {Event} evt\n */\n detectKey(evt) {\n if (!this.enterKey) {\n return;\n }\n if (evt) {\n let key = keyCode(evt);\n if (key === ENTER_KEY) {\n this.filter();\n cancelEvt(evt);\n stopEvt(evt);\n } else {\n this.isUserTyping = true;\n root.clearInterval(this.autoFilterTimer);\n this.autoFilterTimer = null;\n }\n }\n }\n\n /**\n * Filter's keyup event: if auto-filter on, detect user is typing and filter\n * columns\n * @param {Event} evt\n */\n onKeyUp(evt) {\n if (!this.autoFilter) {\n return;\n }\n let key = keyCode(evt);\n this.isUserTyping = false;\n\n function filter() {\n root.clearInterval(this.autoFilterTimer);\n this.autoFilterTimer = null;\n if (!this.isUserTyping) {\n this.filter();\n this.isUserTyping = null;\n }\n }\n\n if (key !== ENTER_KEY && key !== TAB_KEY && key !== ESC_KEY &&\n key !== UP_ARROW_KEY && key !== DOWN_ARROW_KEY) {\n if (this.autoFilterTimer === null) {\n this.autoFilterTimer = root.setInterval(filter.bind(this),\n this.autoFilterDelay);\n }\n } else {\n root.clearInterval(this.autoFilterTimer);\n this.autoFilterTimer = null;\n }\n }\n\n /**\n * Filter's keydown event: if auto-filter on, detect user is typing\n */\n onKeyDown() {\n if (this.autoFilter) {\n this.isUserTyping = true;\n }\n }\n\n /**\n * Filter's focus event\n * @param {Event} evt\n */\n onInpFocus(evt) {\n let elm = targetEvt(evt);\n this.emitter.emit('filter-focus', this, elm);\n }\n\n /**\n * Filter's blur event: if auto-filter on, clear interval on filter blur\n */\n onInpBlur() {\n if (this.autoFilter) {\n this.isUserTyping = false;\n root.clearInterval(this.autoFilterTimer);\n }\n this.emitter.emit('filter-blur', this);\n }\n\n /**\n * Insert filters row at initialization\n */\n _insertFiltersRow() {\n if (this.gridLayout) {\n return;\n }\n let fltrow;\n\n let thead = tag(this.tbl, 'thead');\n if (thead.length > 0) {\n fltrow = thead[0].insertRow(this.filtersRowIndex);\n } else {\n fltrow = this.tbl.insertRow(this.filtersRowIndex);\n }\n\n fltrow.className = this.fltsRowCssClass;\n\n if (this.isExternalFlt) {\n fltrow.style.display = NONE;\n }\n\n this.emitter.emit('filters-row-inserted', this, fltrow);\n return fltrow;\n }\n\n /**\n * Initialize filtersless table\n */\n _initNoFilters() {\n if (this.fltGrid) {\n return;\n }\n this.refRow = this.refRow > 0 ? this.refRow - 1 : 0;\n this.nbFilterableRows = this.getRowsNb();\n }\n\n /**\n * Build input filter type\n * @param {Number} colIndex Column index\n * @param {String} cssClass Css class applied to filter\n * @param {DOMElement} container Container DOM element\n */\n _buildInputFilter(colIndex, cssClass, container) {\n let col = this.getFilterType(colIndex);\n let externalFltTgtId = this.isExternalFlt ?\n this.externalFltTgtIds[colIndex] : null;\n let inptype = col === INPUT ? 'text' : 'hidden';\n let inp = createElm(INPUT,\n ['id', this.prfxFlt + colIndex + '_' + this.id],\n ['type', inptype], ['ct', colIndex]);\n\n if (inptype !== 'hidden' && this.watermark) {\n inp.setAttribute('placeholder',\n this.isWatermarkArray ? (this.watermark[colIndex] || '') :\n this.watermark\n );\n }\n inp.className = cssClass || this.fltCssClass;\n addEvt(inp, 'focus', (evt) => this.onInpFocus(evt));\n\n //filter is appended in custom element\n if (externalFltTgtId) {\n elm(externalFltTgtId).appendChild(inp);\n } else {\n container.appendChild(inp);\n }\n\n this.fltIds.push(inp.id);\n\n addEvt(inp, 'keypress', (evt) => this.detectKey(evt));\n addEvt(inp, 'keydown', () => this.onKeyDown());\n addEvt(inp, 'keyup', (evt) => this.onKeyUp(evt));\n addEvt(inp, 'blur', () => this.onInpBlur());\n }\n\n /**\n * Build submit button\n * @param {Number} colIndex Column index\n * @param {DOMElement} container Container DOM element\n */\n _buildSubmitButton(colIndex, container) {\n let externalFltTgtId = this.isExternalFlt ?\n this.externalFltTgtIds[colIndex] : null;\n let btn = createElm(INPUT,\n ['id', this.prfxValButton + colIndex + '_' + this.id],\n ['type', 'button'], ['value', this.btnText]);\n btn.className = this.btnCssClass;\n\n //filter is appended in custom element\n if (externalFltTgtId) {\n elm(externalFltTgtId).appendChild(btn);\n } else {\n container.appendChild(btn);\n }\n\n addEvt(btn, 'click', () => this.filter());\n }\n\n /**\n * Return a feature instance for a given name\n * @param {String} name Name of the feature\n * @return {Object}\n */\n feature(name) {\n return this.Mod[name];\n }\n\n /**\n * Initialise all the extensions defined in the configuration object\n */\n initExtensions() {\n let exts = this.extensions;\n // Set config's publicPath dynamically for Webpack...\n __webpack_public_path__ = this.basePath;\n\n this.emitter.emit('before-loading-extensions', this);\n for (let i = 0, len = exts.length; i < len; i++) {\n let ext = exts[i];\n if (!this.ExtRegistry[ext.name]) {\n this.loadExtension(ext);\n }\n }\n this.emitter.emit('after-loading-extensions', this);\n }\n\n /**\n * Load an extension module\n * @param {Object} ext Extension config object\n */\n loadExtension(ext) {\n if (!ext || !ext.name) {\n return;\n }\n\n let name = ext.name;\n let path = ext.path;\n let modulePath;\n\n if (name && path) {\n modulePath = ext.path + name;\n } else {\n name = name.replace('.js', '');\n modulePath = 'extensions/{}/{}'.replace(/{}/g, name);\n }\n\n // Require pattern for Webpack\n require(['./' + modulePath], (mod) => {\n /* eslint-disable */\n let inst = new mod.default(this, ext);\n /* eslint-enable */\n inst.init();\n this.ExtRegistry[name] = inst;\n });\n }\n\n /**\n * Get an extension instance\n * @param {String} name Name of the extension\n * @return {Object} Extension instance\n */\n extension(name) {\n return this.ExtRegistry[name];\n }\n\n /**\n * Check passed extension name exists\n * @param {String} name Name of the extension\n * @return {Boolean}\n */\n hasExtension(name) {\n return !isEmpty(this.ExtRegistry[name]);\n }\n\n /**\n * Destroy all the extensions defined in the configuration object\n */\n destroyExtensions() {\n let exts = this.extensions;\n\n for (let i = 0, len = exts.length; i < len; i++) {\n let ext = exts[i];\n let extInstance = this.ExtRegistry[ext.name];\n if (extInstance) {\n extInstance.destroy();\n this.ExtRegistry[ext.name] = undefined;\n }\n }\n }\n\n /**\n * Load themes defined in the configuration object\n */\n loadThemes() {\n let themes = this.themes;\n this.emitter.emit('before-loading-themes', this);\n\n //Default theme config\n if (this.enableDefaultTheme) {\n let defaultTheme = { name: 'default' };\n this.themes.push(defaultTheme);\n }\n if (isArray(themes)) {\n for (let i = 0, len = themes.length; i < len; i++) {\n let theme = themes[i];\n let name = theme.name;\n let path = theme.path;\n let styleId = this.prfxTf + name;\n if (name && !path) {\n path = this.themesPath + name + '/' + name + '.css';\n }\n else if (!name && theme.path) {\n name = 'theme{0}'.replace('{0}', i);\n }\n\n if (!this.isImported(path, 'link')) {\n this.import(styleId, path, null, 'link');\n }\n }\n }\n\n // Enable loader indicator\n this.loader = true;\n\n this.emitter.emit('after-loading-themes', this);\n }\n\n /**\n * Return stylesheet DOM element for a given theme name\n * @return {DOMElement} stylesheet element\n */\n getStylesheet(name = 'default') {\n return elm(this.prfxTf + name);\n }\n\n /**\n * Destroy filter grid\n */\n destroy() {\n if (!this.initialized) {\n return;\n }\n\n let Mod = this.Mod;\n let emitter = this.emitter;\n\n if (this.isExternalFlt && !this.popupFilters) {\n this.removeExternalFlts();\n }\n if (this.infDiv) {\n this.removeToolbar();\n }\n if (this.markActiveColumns) {\n this.clearActiveColumns();\n emitter.off(['before-filtering'], () => this.clearActiveColumns());\n emitter.off(['cell-processed'],\n (tf, colIndex) => this.markActiveColumn(colIndex));\n }\n if (this.hasExtensions) {\n this.destroyExtensions();\n }\n\n this.validateAllRows();\n\n if (this.fltGrid && !this.gridLayout) {\n this.tbl.deleteRow(this.filtersRowIndex);\n }\n\n // broadcast destroy event\n emitter.emit('destroy', this);\n\n // Destroy modules\n // TODO: subcribe modules to destroy event instead\n Object.keys(Mod).forEach(function (key) {\n let feature = Mod[key];\n if (feature && isFn(feature.destroy)) {\n feature.destroy();\n }\n });\n\n // unsubscribe to events\n if (this.hasVisibleRows) {\n emitter.off(['after-filtering'], () => this.enforceVisibility());\n }\n if (this.linkedFilters) {\n emitter.off(['after-filtering'], () => this.linkFilters());\n }\n this.emitter.off(['filter-focus'],\n (tf, filter) => this.setActiveFilterId(filter.id));\n\n removeClass(this.tbl, this.prfxTf);\n removeClass(this.tbl, this.prfxResponsive);\n\n this.nbHiddenRows = 0;\n this.validRowsIndex = [];\n this.fltIds = [];\n this.initialized = false;\n }\n\n /**\n * Generate container element for paging, reset button, rows counter etc.\n */\n setToolbar() {\n if (this.infDiv) {\n return;\n }\n\n /*** container div ***/\n let infdiv = createElm('div', ['id', this.prfxInfDiv + this.id]);\n infdiv.className = this.infDivCssClass;\n\n //custom container\n if (this.toolBarTgtId) {\n elm(this.toolBarTgtId).appendChild(infdiv);\n }\n //grid-layout\n else if (this.gridLayout) {\n let gridLayout = this.Mod.gridLayout;\n gridLayout.tblMainCont.appendChild(infdiv);\n infdiv.className = gridLayout.infDivCssClass;\n }\n //default location: just above the table\n else {\n let cont = createElm('caption');\n cont.appendChild(infdiv);\n this.tbl.insertBefore(cont, this.tbl.firstChild);\n }\n this.infDiv = elm(this.prfxInfDiv + this.id);\n\n /*** left div containing rows # displayer ***/\n let ldiv = createElm('div', ['id', this.prfxLDiv + this.id]);\n ldiv.className = this.lDivCssClass;\n infdiv.appendChild(ldiv);\n this.lDiv = elm(this.prfxLDiv + this.id);\n\n /*** right div containing reset button\n + nb results per page select ***/\n let rdiv = createElm('div', ['id', this.prfxRDiv + this.id]);\n rdiv.className = this.rDivCssClass;\n infdiv.appendChild(rdiv);\n this.rDiv = elm(this.prfxRDiv + this.id);\n\n /*** mid div containing paging elements ***/\n let mdiv = createElm('div', ['id', this.prfxMDiv + this.id]);\n mdiv.className = this.mDivCssClass;\n infdiv.appendChild(mdiv);\n this.mDiv = elm(this.prfxMDiv + this.id);\n\n // emit help initialisation only if undefined\n if (isUndef(this.help)) {\n // explicitily set enabled field to true to initialise help by\n // default, only if setting is undefined\n this.Mod.help.enabled = true;\n this.emitter.emit('init-help', this);\n }\n }\n\n /**\n * Remove toolbar container element\n */\n removeToolbar() {\n if (!this.infDiv) {\n return;\n }\n removeElm(this.infDiv);\n this.infDiv = null;\n\n let tbl = this.tbl;\n let captions = tag(tbl, 'caption');\n if (captions.length > 0) {\n [].forEach.call(captions, (elm) => tbl.removeChild(elm));\n }\n }\n\n /**\n * Remove all the external column filters\n */\n removeExternalFlts() {\n if (!this.isExternalFlt) {\n return;\n }\n let ids = this.externalFltTgtIds,\n len = ids.length;\n for (let ct = 0; ct < len; ct++) {\n let externalFltTgtId = ids[ct],\n externalFlt = elm(externalFltTgtId);\n if (externalFlt) {\n externalFlt.innerHTML = '';\n }\n }\n }\n\n /**\n * Check if given column implements a filter with custom options\n * @param {Number} colIndex Column's index\n * @return {Boolean}\n */\n isCustomOptions(colIndex) {\n return this.hasCustomOptions &&\n this.customOptions.cols.indexOf(colIndex) !== -1;\n }\n\n /**\n * Returns an array [[value0, value1 ...],[text0, text1 ...]] with the\n * custom options values and texts\n * @param {Number} colIndex Column's index\n * @return {Array}\n */\n getCustomOptions(colIndex) {\n if (isEmpty(colIndex) || !this.isCustomOptions(colIndex)) {\n return;\n }\n\n let customOptions = this.customOptions;\n let cols = customOptions.cols;\n let optTxt = [], optArray = [];\n let index = cols.indexOf(colIndex);\n let slcValues = customOptions.values[index];\n let slcTexts = customOptions.texts[index];\n let slcSort = customOptions.sorts[index];\n\n for (let r = 0, len = slcValues.length; r < len; r++) {\n optArray.push(slcValues[r]);\n if (slcTexts[r]) {\n optTxt.push(slcTexts[r]);\n } else {\n optTxt.push(slcValues[r]);\n }\n }\n if (slcSort) {\n optArray.sort();\n optTxt.sort();\n }\n return [optArray, optTxt];\n }\n\n /**\n * Filter the table by retrieving the data from each cell in every single\n * row and comparing it to the search term for current column. A row is\n * hidden when all the search terms are not found in inspected row.\n */\n filter() {\n if (!this.fltGrid || !this.initialized) {\n return;\n }\n //invoke onbefore callback\n if (this.onBeforeFilter) {\n this.onBeforeFilter.call(null, this);\n }\n this.emitter.emit('before-filtering', this);\n\n let row = this.tbl.rows,\n nbRows = this.getRowsNb(true),\n hiddenRows = 0;\n\n this.validRowsIndex = [];\n // search args re-init\n let searchArgs = this.getFiltersValue();\n\n let numCellData;\n let nbFormat;\n let re_le = new RegExp(this.leOperator),\n re_ge = new RegExp(this.geOperator),\n re_l = new RegExp(this.lwOperator),\n re_g = new RegExp(this.grOperator),\n re_d = new RegExp(this.dfOperator),\n re_lk = new RegExp(rgxEsc(this.lkOperator)),\n re_eq = new RegExp(this.eqOperator),\n re_st = new RegExp(this.stOperator),\n re_en = new RegExp(this.enOperator),\n // re_an = new RegExp(this.anOperator),\n // re_cr = new RegExp(this.curExp),\n re_em = this.emOperator,\n re_nm = this.nmOperator,\n re_re = new RegExp(rgxEsc(this.rgxOperator));\n\n //keyword highlighting\n function highlight(str, ok, cell) {\n /*jshint validthis:true */\n if (this.highlightKeywords && ok) {\n str = str.replace(re_lk, '');\n str = str.replace(re_eq, '');\n str = str.replace(re_st, '');\n str = str.replace(re_en, '');\n let w = str;\n if (re_le.test(str) || re_ge.test(str) || re_l.test(str) ||\n re_g.test(str) || re_d.test(str)) {\n w = getText(cell);\n }\n if (w !== '') {\n this.emitter.emit('highlight-keyword', this, cell, w);\n }\n }\n }\n\n //looks for search argument in current row\n function hasArg(sA, cellData, j) {\n sA = matchCase(sA, this.caseSensitive);\n\n let occurence;\n let dtType = this.hasColDateType ?\n this.colDateType[j] : this.defaultDateType;\n\n //Search arg operator tests\n let hasLO = re_l.test(sA),\n hasLE = re_le.test(sA),\n hasGR = re_g.test(sA),\n hasGE = re_ge.test(sA),\n hasDF = re_d.test(sA),\n hasEQ = re_eq.test(sA),\n hasLK = re_lk.test(sA),\n // hasAN = re_an.test(sA),\n hasST = re_st.test(sA),\n hasEN = re_en.test(sA),\n hasEM = (re_em === sA),\n hasNM = (re_nm === sA),\n hasRE = re_re.test(sA);\n\n //Search arg dates tests\n let isLDate = hasLO && isValidDate(sA.replace(re_l, ''), dtType);\n let isLEDate = hasLE && isValidDate(sA.replace(re_le, ''), dtType);\n let isGDate = hasGR && isValidDate(sA.replace(re_g, ''), dtType);\n let isGEDate = hasGE && isValidDate(sA.replace(re_ge, ''), dtType);\n let isDFDate = hasDF && isValidDate(sA.replace(re_d, ''), dtType);\n let isEQDate = hasEQ && isValidDate(sA.replace(re_eq, ''), dtType);\n\n let dte1, dte2;\n //dates\n if (isValidDate(cellData, dtType)) {\n dte1 = formatDate(cellData, dtType);\n // lower date\n if (isLDate) {\n dte2 = formatDate(sA.replace(re_l, ''), dtType);\n occurence = dte1 < dte2;\n }\n // lower equal date\n else if (isLEDate) {\n dte2 = formatDate(sA.replace(re_le, ''), dtType);\n occurence = dte1 <= dte2;\n }\n // greater equal date\n else if (isGEDate) {\n dte2 = formatDate(sA.replace(re_ge, ''), dtType);\n occurence = dte1 >= dte2;\n }\n // greater date\n else if (isGDate) {\n dte2 = formatDate(sA.replace(re_g, ''), dtType);\n occurence = dte1 > dte2;\n }\n // different date\n else if (isDFDate) {\n dte2 = formatDate(sA.replace(re_d, ''), dtType);\n occurence = dte1.toString() !== dte2.toString();\n }\n // equal date\n else if (isEQDate) {\n dte2 = formatDate(sA.replace(re_eq, ''), dtType);\n occurence = dte1.toString() === dte2.toString();\n }\n // searched keyword with * operator doesn't have to be a date\n else if (re_lk.test(sA)) {// like date\n occurence = contains(sA.replace(re_lk, ''), cellData,\n false, this.caseSensitive);\n }\n else if (isValidDate(sA, dtType)) {\n dte2 = formatDate(sA, dtType);\n occurence = dte1.toString() === dte2.toString();\n }\n //empty\n else if (hasEM) {\n occurence = isEmptyString(cellData);\n }\n //non-empty\n else if (hasNM) {\n occurence = !isEmptyString(cellData);\n } else {\n occurence = contains(sA, cellData, this.isExactMatch(j),\n this.caseSensitive);\n }\n }\n\n else {\n //first numbers need to be formated\n if (this.hasColNbFormat && this.colNbFormat[j]) {\n numCellData = removeNbFormat(cellData, this.colNbFormat[j]);\n nbFormat = this.colNbFormat[j];\n } else {\n if (this.thousandsSeparator === ',' &&\n this.decimalSeparator === '.') {\n numCellData = removeNbFormat(cellData, 'us');\n nbFormat = 'us';\n } else {\n numCellData = removeNbFormat(cellData, 'eu');\n nbFormat = 'eu';\n }\n }\n\n // first checks if there is any operator (<,>,<=,>=,!,*,=,{,},\n // rgx:)\n // lower equal\n if (hasLE) {\n occurence = numCellData <= removeNbFormat(\n sA.replace(re_le, ''), nbFormat);\n }\n //greater equal\n else if (hasGE) {\n occurence = numCellData >= removeNbFormat(\n sA.replace(re_ge, ''), nbFormat);\n }\n //lower\n else if (hasLO) {\n occurence = numCellData < removeNbFormat(\n sA.replace(re_l, ''), nbFormat);\n }\n //greater\n else if (hasGR) {\n occurence = numCellData > removeNbFormat(\n sA.replace(re_g, ''), nbFormat);\n }\n //different\n else if (hasDF) {\n occurence = contains(sA.replace(re_d, ''), cellData,\n false, this.caseSensitive) ? false : true;\n }\n //like\n else if (hasLK) {\n occurence = contains(sA.replace(re_lk, ''), cellData,\n false, this.caseSensitive);\n }\n //equal\n else if (hasEQ) {\n occurence = contains(sA.replace(re_eq, ''), cellData,\n true, this.caseSensitive);\n }\n //starts with\n else if (hasST) {\n occurence = cellData.indexOf(sA.replace(re_st, '')) === 0 ?\n true : false;\n }\n //ends with\n else if (hasEN) {\n let searchArg = sA.replace(re_en, '');\n occurence =\n cellData.lastIndexOf(searchArg, cellData.length - 1) ===\n (cellData.length - 1) - (searchArg.length - 1) &&\n cellData.lastIndexOf(searchArg, cellData.length - 1)\n > -1 ? true : false;\n }\n //empty\n else if (hasEM) {\n occurence = isEmptyString(cellData);\n }\n //non-empty\n else if (hasNM) {\n occurence = !isEmptyString(cellData);\n }\n //regexp\n else if (hasRE) {\n //in case regexp fires an exception\n try {\n //operator is removed\n let srchArg = sA.replace(re_re, '');\n let rgx = new RegExp(srchArg);\n occurence = rgx.test(cellData);\n } catch (ex) {\n occurence = false;\n }\n } else {\n // If numeric type data, perform a strict equality test and\n // fallback to unformatted number string comparison\n if (numCellData && this.hasColNbFormat &&\n this.colNbFormat[j] && !this.singleSearchFlt) {\n // removeNbFormat can return 0 for strings which are not\n // formatted numbers, in that case return the original\n // string. TODO: handle this in removeNbFormat\n sA = removeNbFormat(sA, nbFormat) || sA;\n occurence = numCellData === sA ||\n contains(sA.toString(), numCellData.toString(),\n this.isExactMatch(j), this.caseSensitive);\n } else {\n // Finally test search term is contained in cell data\n occurence = contains(sA, cellData, this.isExactMatch(j),\n this.caseSensitive);\n }\n }\n\n }//else\n return occurence;\n }//fn\n\n for (let k = this.refRow; k < nbRows; k++) {\n // already filtered rows display re-init\n row[k].style.display = '';\n\n let cells = row[k].cells;\n let nchilds = cells.length;\n\n // checks if row has exact cell #\n if (nchilds !== this.nbCells) {\n continue;\n }\n\n let occurence = [],\n isRowValid = true,\n //only for single filter search\n singleFltRowValid = false;\n\n // this loop retrieves cell data\n for (let j = 0; j < nchilds; j++) {\n //searched keyword\n let sA = searchArgs[this.singleSearchFlt ? 0 : j];\n\n if (sA === '') {\n continue;\n }\n\n let cellData = matchCase(this.getCellData(cells[j]),\n this.caseSensitive);\n\n //multiple search parameter operator ||\n let sAOrSplit = sA.toString().split(this.orOperator),\n //multiple search || parameter boolean\n hasMultiOrSA = sAOrSplit.length > 1,\n //multiple search parameter operator &&\n sAAndSplit = sA.toString().split(this.anOperator),\n //multiple search && parameter boolean\n hasMultiAndSA = sAAndSplit.length > 1;\n\n //detect operators or array query\n if (isArray(sA) || hasMultiOrSA || hasMultiAndSA) {\n let cS,\n s,\n occur = false;\n if (isArray(sA)) {\n s = sA;\n } else {\n s = hasMultiOrSA ? sAOrSplit : sAAndSplit;\n }\n // TODO: improve clarity/readability of this block\n for (let w = 0, len = s.length; w < len; w++) {\n cS = trim(s[w]);\n occur = hasArg.call(this, cS, cellData, j);\n highlight.call(this, cS, occur, cells[j]);\n if ((hasMultiOrSA && occur) ||\n (hasMultiAndSA && !occur)) {\n break;\n }\n if (isArray(sA) && occur) {\n break;\n }\n }\n occurence[j] = occur;\n\n }\n //single search parameter\n else {\n occurence[j] = hasArg.call(this, trim(sA), cellData, j);\n highlight.call(this, sA, occurence[j], cells[j]);\n }//else single param\n\n if (!occurence[j]) {\n isRowValid = false;\n }\n if (this.singleSearchFlt && occurence[j]) {\n singleFltRowValid = true;\n }\n\n this.emitter.emit('cell-processed', this, j, cells[j]);\n }//for j\n\n if (this.singleSearchFlt && singleFltRowValid) {\n isRowValid = true;\n }\n\n if (!isRowValid) {\n this.validateRow(k, false);\n hiddenRows++;\n } else {\n this.validateRow(k, true);\n }\n\n this.emitter.emit('row-processed', this, k,\n this.validRowsIndex.length, isRowValid);\n }// for k\n\n this.nbHiddenRows = hiddenRows;\n\n //invokes onafterfilter callback\n if (this.onAfterFilter) {\n this.onAfterFilter.call(null, this);\n }\n\n this.emitter.emit('after-filtering', this, searchArgs);\n }\n\n /**\n * Return the data of a specified column\n * @param {Number} colIndex Column index\n * @param {Boolean} includeHeaders Optional: include headers row\n * @param {Boolean} num Optional: return unformatted number\n * @param {Array} exclude Optional: list of row indexes to be excluded\n * @return {Array} Flat list of data for a column\n */\n getColValues(colIndex, includeHeaders = false, num = false, exclude = []) {\n if (!this.fltGrid) {\n return;\n }\n let row = this.tbl.rows;\n let nbRows = this.getRowsNb(true);\n let colValues = [];\n\n if (includeHeaders) {\n colValues.push(this.getHeadersText()[colIndex]);\n }\n\n for (let i = this.refRow; i < nbRows; i++) {\n let isExludedRow = false;\n // checks if current row index appears in exclude array\n if (exclude.length > 0) {\n isExludedRow = exclude.indexOf(i) !== -1;\n }\n let cell = row[i].cells,\n nchilds = cell.length;\n\n // checks if row has exact cell # and is not excluded\n if (nchilds === this.nbCells && !isExludedRow) {\n // this loop retrieves cell data\n for (let j = 0; j < nchilds; j++) {\n if (j !== colIndex || row[i].style.display !== '') {\n continue;\n }\n let cellData = this.getCellData(cell[j]),\n nbFormat = this.colNbFormat ?\n this.colNbFormat[colIndex] : undefined,\n data = num ? removeNbFormat(cellData, nbFormat) :\n cellData;\n colValues.push(data);\n }\n }\n }\n return colValues;\n }\n\n /**\n * Return the filter's value of a specified column\n * @param {Number} index Column index\n * @return {String} Filter value\n */\n getFilterValue(index) {\n if (!this.fltGrid) {\n return;\n }\n let fltValue = '';\n let flt = this.getFilterElement(index);\n if (!flt) {\n return fltValue;\n }\n\n let fltColType = this.getFilterType(index);\n if (fltColType !== MULTIPLE && fltColType !== CHECKLIST) {\n fltValue = flt.value;\n }\n //mutiple select\n else if (fltColType === MULTIPLE) {\n fltValue = this.feature('dropdown').getValues(index);\n }\n //checklist\n else if (fltColType === CHECKLIST) {\n fltValue = this.feature('checkList').getValues(index);\n }\n //return an empty string if collection is empty or contains a single\n //empty string\n if (isArray(fltValue) && fltValue.length === 0 ||\n (fltValue.length === 1 && fltValue[0] === '')) {\n fltValue = '';\n }\n\n return fltValue;\n }\n\n /**\n * Return the filters' values\n * @return {Array} List of filters' values\n */\n getFiltersValue() {\n if (!this.fltGrid) {\n return;\n }\n let searchArgs = [];\n for (let i = 0, len = this.fltIds.length; i < len; i++) {\n let fltValue = this.getFilterValue(i);\n if (isArray(fltValue)) {\n searchArgs.push(fltValue);\n } else {\n searchArgs.push(trim(fltValue));\n }\n }\n return searchArgs;\n }\n\n /**\n * Return the ID of a specified column's filter\n * @param {Number} index Column's index\n * @return {String} ID of the filter element\n */\n getFilterId(index) {\n if (!this.fltGrid) {\n return;\n }\n return this.fltIds[index];\n }\n\n /**\n * Return the list of ids of filters matching a specified type.\n * Note: hidden filters are also returned\n *\n * @param {String} type Filter type string ('input', 'select', 'multiple',\n * 'checklist')\n * @param {Boolean} bool If true returns columns indexes instead of IDs\n * @return {[type]} List of element IDs or column indexes\n */\n getFiltersByType(type, bool) {\n if (!this.fltGrid) {\n return;\n }\n let arr = [];\n for (let i = 0, len = this.fltIds.length; i < len; i++) {\n let fltType = this.getFilterType(i);\n if (fltType === type.toLowerCase()) {\n let a = bool ? i : this.fltIds[i];\n arr.push(a);\n }\n }\n return arr;\n }\n\n /**\n * Return the filter's DOM element for a given column\n * @param {Number} index Column's index\n * @return {DOMElement}\n */\n getFilterElement(index) {\n let fltId = this.fltIds[index];\n return elm(fltId);\n }\n\n /**\n * Return the number of cells for a given row index\n * @param {Number} rowIndex Index of the row\n * @return {Number} Number of cells\n */\n getCellsNb(rowIndex = 0) {\n let tr = this.tbl.rows[rowIndex];\n return tr.cells.length;\n }\n\n /**\n * Return the number of filterable rows starting from reference row if\n * defined\n * @param {Boolean} includeHeaders Include the headers row\n * @return {Number} Number of filterable rows\n */\n getRowsNb(includeHeaders) {\n let s = isUndef(this.refRow) ? 0 : this.refRow;\n let ntrs = this.tbl.rows.length;\n if (includeHeaders) {\n s = 0;\n }\n return parseInt(ntrs - s, 10);\n }\n\n /**\n * Return the data of a given cell\n * @param {DOMElement} cell Cell's DOM object\n * @return {String}\n */\n getCellData(cell) {\n let idx = cell.cellIndex;\n //Check for customCellData callback\n if (this.customCellData &&\n this.customCellDataCols.indexOf(idx) !== -1) {\n return this.customCellData.call(null, this, cell, idx);\n } else {\n return getText(cell);\n }\n }\n\n /**\n * Return the table data with following format:\n * [\n * [rowIndex, [value0, value1...]],\n * [rowIndex, [value0, value1...]]\n * ]\n * @param {Boolean} includeHeaders Optional: include headers row\n * @param {Boolean} excludeHiddenCols Optional: exclude hidden columns\n * @return {Array}\n *\n * TODO: provide an API returning data in JSON format\n */\n getTableData(includeHeaders = false, excludeHiddenCols = false) {\n let rows = this.tbl.rows;\n let nbRows = this.getRowsNb(true);\n let tblData = [];\n if (includeHeaders) {\n let headers = this.getHeadersText(excludeHiddenCols);\n tblData.push([this.getHeadersRowIndex(), headers]);\n }\n for (let k = this.refRow; k < nbRows; k++) {\n let rowData = [k, []];\n let cells = rows[k].cells;\n for (let j = 0, len = cells.length; j < len; j++) {\n if (excludeHiddenCols && this.hasExtension('colsVisibility')) {\n if (this.extension('colsVisibility').isColHidden(j)) {\n continue;\n }\n }\n let cellData = this.getCellData(cells[j]);\n rowData[1].push(cellData);\n }\n tblData.push(rowData);\n }\n return tblData;\n }\n\n /**\n * Return the filtered data with following format:\n * [\n * [rowIndex, [value0, value1...]],\n * [rowIndex, [value0, value1...]]\n * ]\n * @param {Boolean} includeHeaders Optional: include headers row\n * @param {Boolean} excludeHiddenCols Optional: exclude hidden columns\n * @return {Array}\n *\n * TODO: provide an API returning data in JSON format\n */\n getFilteredData(includeHeaders = false, excludeHiddenCols = false) {\n if (!this.validRowsIndex) {\n return [];\n }\n let rows = this.tbl.rows,\n filteredData = [];\n if (includeHeaders) {\n let headers = this.getHeadersText(excludeHiddenCols);\n filteredData.push([this.getHeadersRowIndex(), headers]);\n }\n\n let validRows = this.getValidRows(true);\n for (let i = 0; i < validRows.length; i++) {\n let rData = [this.validRowsIndex[i], []],\n cells = rows[this.validRowsIndex[i]].cells;\n for (let k = 0; k < cells.length; k++) {\n if (excludeHiddenCols && this.hasExtension('colsVisibility')) {\n if (this.extension('colsVisibility').isColHidden(k)) {\n continue;\n }\n }\n let cellData = this.getCellData(cells[k]);\n rData[1].push(cellData);\n }\n filteredData.push(rData);\n }\n return filteredData;\n }\n\n /**\n * Return the filtered data for a given column index\n * @param {Number} colIndex Colmun's index\n * @param {Boolean} includeHeaders Optional: include headers row\n * @return {Array} Flat list of values ['val0','val1','val2'...]\n *\n * TODO: provide an API returning data in JSON format\n */\n getFilteredDataCol(colIndex, includeHeaders = false) {\n if (isUndef(colIndex)) {\n return [];\n }\n let data = this.getFilteredData(),\n colData = [];\n if (includeHeaders) {\n colData.push(this.getHeadersText()[colIndex]);\n }\n for (let i = 0, len = data.length; i < len; i++) {\n let r = data[i],\n //cols values of current row\n d = r[1],\n //data of searched column\n c = d[colIndex];\n colData.push(c);\n }\n return colData;\n }\n\n /**\n * Get the display value of a row\n * @param {HTMLTableRowElement} row DOM element of the row\n * @return {String} Usually 'none' or ''\n */\n getRowDisplay(row) {\n return row.style.display;\n }\n\n /**\n * Validate/invalidate row by setting the 'validRow' attribute on the row\n * @param {Number} rowIndex Index of the row\n * @param {Boolean} isValid\n */\n validateRow(rowIndex, isValid) {\n let row = this.tbl.rows[rowIndex];\n if (!row || typeof isValid !== 'boolean') {\n return;\n }\n\n // always visible rows are valid\n if (this.hasVisibleRows && this.visibleRows.indexOf(rowIndex) !== -1) {\n isValid = true;\n }\n\n let displayFlag = isValid ? '' : NONE,\n validFlag = isValid ? 'true' : 'false';\n row.style.display = displayFlag;\n\n if (this.paging) {\n row.setAttribute('validRow', validFlag);\n }\n\n if (isValid) {\n if (this.validRowsIndex.indexOf(rowIndex) === -1) {\n this.validRowsIndex.push(rowIndex);\n }\n\n if (this.onRowValidated) {\n this.onRowValidated.call(null, this, rowIndex);\n }\n\n this.emitter.emit('row-validated', this, rowIndex);\n }\n }\n\n /**\n * Validate all filterable rows\n */\n validateAllRows() {\n if (!this.initialized) {\n return;\n }\n this.validRowsIndex = [];\n for (let k = this.refRow; k < this.nbFilterableRows; k++) {\n this.validateRow(k, true);\n }\n }\n\n /**\n * Set search value to a given filter\n * @param {Number} index Column's index\n * @param {String or Array} query searcharg Search term\n */\n setFilterValue(index, query = '') {\n if (!this.fltGrid) {\n return;\n }\n let slc = this.getFilterElement(index),\n fltColType = this.getFilterType(index);\n\n if (fltColType !== MULTIPLE && fltColType !== CHECKLIST) {\n if (this.loadFltOnDemand && !this.initialized) {\n this.emitter.emit('build-select-filter', this, index,\n this.linkedFilters, this.isExternalFlt);\n }\n slc.value = query;\n }\n //multiple selects\n else if (fltColType === MULTIPLE) {\n let values = isArray(query) ? query :\n query.split(' ' + this.orOperator + ' ');\n\n if (this.loadFltOnDemand && !this.initialized) {\n this.emitter.emit('build-select-filter', this, index,\n this.linkedFilters, this.isExternalFlt);\n }\n\n this.emitter.emit('select-options', this, index, values);\n }\n //checklist\n else if (fltColType === CHECKLIST) {\n let values = [];\n if (this.loadFltOnDemand && !this.initialized) {\n this.emitter.emit('build-checklist-filter', this, index,\n this.isExternalFlt);\n }\n if (isArray(query)) {\n values = query;\n } else {\n query = matchCase(query, this.caseSensitive);\n values = query.split(' ' + this.orOperator + ' ');\n }\n\n this.emitter.emit('select-checklist-options', this, index, values);\n }\n }\n\n /**\n * Set them columns' widths as per configuration\n * @param {Element} tbl DOM element\n */\n setColWidths(tbl) {\n if (!this.hasColWidths) {\n return;\n }\n tbl = tbl || this.tbl;\n\n let nbCols = this.nbCells;\n let colWidths = this.colWidths;\n let colTags = tag(tbl, 'col');\n let tblHasColTag = colTags.length > 0;\n let frag = !tblHasColTag ? doc.createDocumentFragment() : null;\n for (let k = 0; k < nbCols; k++) {\n let col;\n if (tblHasColTag) {\n col = colTags[k];\n } else {\n col = createElm('col', ['id', this.id + '_col_' + k]);\n frag.appendChild(col);\n }\n col.style.width = colWidths[k];\n }\n if (!tblHasColTag) {\n tbl.insertBefore(frag, tbl.firstChild);\n }\n }\n\n /**\n * Makes defined rows always visible\n */\n enforceVisibility() {\n if (!this.hasVisibleRows) {\n return;\n }\n let nbRows = this.getRowsNb(true);\n for (let i = 0, len = this.visibleRows.length; i < len; i++) {\n let row = this.visibleRows[i];\n //row index cannot be > nrows\n if (row <= nbRows) {\n this.validateRow(row, true);\n }\n }\n }\n\n /**\n * Clear all the filters' values\n */\n clearFilters() {\n if (!this.fltGrid) {\n return;\n }\n\n this.emitter.emit('before-clearing-filters', this);\n\n if (this.onBeforeReset) {\n this.onBeforeReset.call(null, this, this.getFiltersValue());\n }\n for (let i = 0, len = this.fltIds.length; i < len; i++) {\n this.setFilterValue(i, '');\n }\n\n this.filter();\n\n if (this.onAfterReset) {\n this.onAfterReset.call(null, this);\n }\n this.emitter.emit('after-clearing-filters', this);\n }\n\n /**\n * Clears filtered columns visual indicator (background color)\n */\n clearActiveColumns() {\n for (let i = 0, len = this.getCellsNb(this.headersRow); i < len; i++) {\n removeClass(this.getHeaderElement(i), this.activeColumnsCssClass);\n }\n }\n\n /**\n * Mark currently filtered column\n * @param {Number} colIndex Column index\n */\n markActiveColumn(colIndex) {\n let header = this.getHeaderElement(colIndex);\n if (hasClass(header, this.activeColumnsCssClass)) {\n return;\n }\n if (this.onBeforeActiveColumn) {\n this.onBeforeActiveColumn.call(null, this, colIndex);\n }\n addClass(header, this.activeColumnsCssClass);\n if (this.onAfterActiveColumn) {\n this.onAfterActiveColumn.call(null, this, colIndex);\n }\n }\n\n /**\n * Return the ID of the current active filter\n * @returns {String}\n */\n getActiveFilterId() {\n return this.activeFilterId;\n }\n\n /**\n * Set the ID of the current active filter\n * @param {String} filterId Element ID\n */\n setActiveFilterId(filterId) {\n this.activeFilterId = filterId;\n }\n\n /**\n * Return the column index for a given filter ID\n * @param {string} [filterId=''] Filter ID\n * @returns {Number} Column index\n */\n getColumnIndexFromFilterId(filterId = '') {\n let idx = filterId.split('_')[0];\n idx = idx.split(this.prfxFlt)[1];\n return parseInt(idx, 10);\n }\n\n /**\n * Make specified column's filter active\n * @param colIndex Index of a column\n */\n activateFilter(colIndex) {\n if (isUndef(colIndex)) {\n return;\n }\n this.setActiveFilterId(this.getFilterId(colIndex));\n }\n\n /**\n * Refresh the filters subject to linking ('select', 'multiple',\n * 'checklist' type)\n */\n linkFilters() {\n if (!this.linkedFilters || !this.activeFilterId) {\n return;\n }\n let slcA1 = this.getFiltersByType(SELECT, true),\n slcA2 = this.getFiltersByType(MULTIPLE, true),\n slcA3 = this.getFiltersByType(CHECKLIST, true),\n slcIndex = slcA1.concat(slcA2);\n slcIndex = slcIndex.concat(slcA3);\n\n let activeIdx = this.getColumnIndexFromFilterId(this.activeFilterId);\n\n for (let i = 0, len = slcIndex.length; i < len; i++) {\n let curSlc = elm(this.fltIds[slcIndex[i]]);\n let slcSelectedValue = this.getFilterValue(slcIndex[i]);\n\n // Welcome to cyclomatic complexity hell :)\n // TODO: simplify/refactor if statement\n if (activeIdx !== slcIndex[i] ||\n (this.paging && slcA1.indexOf(slcIndex[i]) !== -1 &&\n activeIdx === slcIndex[i]) ||\n (!this.paging && (slcA3.indexOf(slcIndex[i]) !== -1 ||\n slcA2.indexOf(slcIndex[i]) !== -1)) ||\n slcSelectedValue === this.displayAllText) {\n\n //1st option needs to be inserted\n if (this.loadFltOnDemand) {\n let opt0 = createOpt(this.displayAllText, '');\n curSlc.innerHTML = '';\n curSlc.appendChild(opt0);\n }\n\n if (slcA3.indexOf(slcIndex[i]) !== -1) {\n this.emitter.emit('build-checklist-filter', this,\n slcIndex[i]);\n } else {\n this.emitter.emit('build-select-filter', this, slcIndex[i],\n true);\n }\n\n this.setFilterValue(slcIndex[i], slcSelectedValue);\n }\n }\n }\n\n /**\n * Determines if passed filter column implements exact query match\n * @param {Number} colIndex [description]\n * @return {Boolean} [description]\n */\n isExactMatch(colIndex) {\n let fltType = this.getFilterType(colIndex);\n return this.exactMatchByCol[colIndex] || this.exactMatch ||\n fltType !== INPUT;\n }\n\n /**\n * Check if passed script or stylesheet is already imported\n * @param {String} filePath Ressource path\n * @param {String} type Possible values: 'script' or 'link'\n * @return {Boolean}\n */\n isImported(filePath, type = 'script') {\n let imported = false,\n attr = type === 'script' ? 'src' : 'href',\n files = tag(doc, type);\n for (let i = 0, len = files.length; i < len; i++) {\n if (isUndef(files[i][attr])) {\n continue;\n }\n if (files[i][attr].match(filePath)) {\n imported = true;\n break;\n }\n }\n return imported;\n }\n\n /**\n * Import script or stylesheet\n * @param {String} fileId Ressource ID\n * @param {String} filePath Ressource path\n * @param {Function} callback Callback\n * @param {String} type Possible values: 'script' or 'link'\n */\n import(fileId, filePath, callback, type = 'script') {\n if (this.isImported(filePath, type)) {\n return;\n }\n let o = this,\n isLoaded = false,\n file,\n head = tag(doc, 'head')[0];\n\n if (type.toLowerCase() === 'link') {\n file = createElm('link',\n ['id', fileId], ['type', 'text/css'],\n ['rel', 'stylesheet'], ['href', filePath]\n );\n } else {\n file = createElm('script',\n ['id', fileId],\n ['type', 'text/javascript'], ['src', filePath]\n );\n }\n\n //Browser <> IE onload event works only for scripts, not for stylesheets\n file.onload = file.onreadystatechange = () => {\n if (!isLoaded &&\n (!this.readyState || this.readyState === 'loaded' ||\n this.readyState === 'complete')) {\n isLoaded = true;\n if (typeof callback === 'function') {\n callback.call(null, o);\n }\n }\n };\n file.onerror = function () {\n throw new Error(`TableFilter could not load: ${filePath}`);\n };\n head.appendChild(file);\n }\n\n /**\n * Check if table has filters grid\n * @return {Boolean}\n */\n isInitialized() {\n return this.initialized;\n }\n\n /**\n * Get list of filter IDs\n * @return {[type]} [description]\n */\n getFiltersId() {\n return this.fltIds || [];\n }\n\n /**\n * Get filtered (valid) rows indexes\n * @param {Boolean} reCalc Force calculation of filtered rows list\n * @return {Array} List of row indexes\n */\n getValidRows(reCalc) {\n if (!reCalc) {\n return this.validRowsIndex;\n }\n\n let nbRows = this.getRowsNb(true);\n this.validRowsIndex = [];\n for (let k = this.refRow; k < nbRows; k++) {\n let r = this.tbl.rows[k];\n if (!this.paging) {\n if (this.getRowDisplay(r) !== NONE) {\n this.validRowsIndex.push(r.rowIndex);\n }\n } else {\n if (r.getAttribute('validRow') === 'true' ||\n r.getAttribute('validRow') === null) {\n this.validRowsIndex.push(r.rowIndex);\n }\n }\n }\n return this.validRowsIndex;\n }\n\n /**\n * Get the index of the row containing the filters\n * @return {Number}\n */\n getFiltersRowIndex() {\n return this.filtersRowIndex;\n }\n\n /**\n * Get the index of the headers row\n * @return {Number}\n */\n getHeadersRowIndex() {\n return this.headersRow;\n }\n\n /**\n * Get the row index from where the filtering process start (1st filterable\n * row)\n * @return {Number}\n */\n getStartRowIndex() {\n return this.refRow;\n }\n\n /**\n * Get the index of the last row\n * @return {Number}\n */\n getLastRowIndex() {\n let nbRows = this.getRowsNb(true);\n return (nbRows - 1);\n }\n\n /**\n * Get the header DOM element for a given column index\n * @param {Number} colIndex Column index\n * @return {Element}\n */\n getHeaderElement(colIndex) {\n let table = this.gridLayout ? this.Mod.gridLayout.headTbl : this.tbl;\n let tHead = tag(table, 'thead');\n let headersRow = this.headersRow;\n let header;\n for (let i = 0; i < this.nbCells; i++) {\n if (i !== colIndex) {\n continue;\n }\n if (tHead.length === 0) {\n header = table.rows[headersRow].cells[i];\n }\n if (tHead.length === 1) {\n header = tHead[0].rows[headersRow].cells[i];\n }\n break;\n }\n return header;\n }\n\n /**\n * Return the list of headers' text\n * @param {Boolean} excludeHiddenCols Optional: exclude hidden columns\n * @return {Array} list of headers' text\n */\n getHeadersText(excludeHiddenCols = false) {\n let headers = [];\n for (let j = 0; j < this.nbCells; j++) {\n if (excludeHiddenCols && this.hasExtension('colsVisibility')) {\n if (this.extension('colsVisibility').isColHidden(j)) {\n continue;\n }\n }\n let header = this.getHeaderElement(j);\n let headerText = getFirstTextNode(header);\n headers.push(headerText);\n }\n return headers;\n }\n\n /**\n * Return the filter type for a specified column\n * @param {Number} colIndex Column's index\n * @return {String}\n */\n getFilterType(colIndex) {\n let colType = this.cfg['col_' + colIndex];\n return !colType ? INPUT : colType.toLowerCase();\n }\n\n /**\n * Get the total number of filterable rows\n * @return {Number}\n */\n getFilterableRowsNb() {\n return this.getRowsNb(false);\n }\n\n /**\n * Return the total number of valid rows\n * @param {Boolean} [reCalc=false] Forces calculation of filtered rows\n * @returns {Number}\n */\n getValidRowsNb(reCalc = false) {\n return this.getValidRows(reCalc).length;\n }\n\n /**\n * Get the configuration object (literal object)\n * @return {Object}\n */\n config() {\n return this.cfg;\n }\n}\n"
+ "content": "import {addEvt, cancelEvt, stopEvt, targetEvt, keyCode} from './event';\nimport {\n addClass, createElm, createOpt, elm, getText, getFirstTextNode, hasClass,\n removeClass, removeElm, tag\n} from './dom';\nimport {contains, matchCase, rgxEsc, trim} from './string';\nimport {isEmpty as isEmptyString} from './string';\nimport {isArray, isEmpty, isFn, isNumber, isObj, isString, isUndef}\nfrom './types';\nimport {formatDate, isValidDate} from './date';\nimport {removeNbFormat} from './helpers';\n\nimport {root} from './root';\nimport {Emitter} from './emitter';\nimport {GridLayout} from './modules/gridLayout';\nimport {Loader} from './modules/loader';\nimport {HighlightKeyword} from './modules/highlightKeywords';\nimport {PopupFilter} from './modules/popupFilter';\nimport {Dropdown} from './modules/dropdown';\nimport {CheckList} from './modules/checkList';\nimport {RowsCounter} from './modules/rowsCounter';\nimport {StatusBar} from './modules/statusBar';\nimport {Paging} from './modules/paging';\nimport {ClearButton} from './modules/clearButton';\nimport {Help} from './modules/help';\nimport {AlternateRows} from './modules/alternateRows';\nimport {NoResults} from './modules/noResults';\nimport {State} from './modules/state';\n\nimport {\n INPUT, SELECT, MULTIPLE, CHECKLIST, NONE,\n ENTER_KEY, TAB_KEY, ESC_KEY, UP_ARROW_KEY, DOWN_ARROW_KEY,\n CELL_TAG, AUTO_FILTER_DELAY\n} from './const';\n\nlet doc = root.document;\n\n/**\n * Makes HTML tables filterable and a bit more :)\n *\n * @export\n * @class TableFilter\n */\nexport class TableFilter {\n\n /**\n * Creates an instance of TableFilter\n * requires `table` or `id` arguments, `row` and `configuration` optional\n * @param {DOMElement} table Table DOM element\n * @param {String} id Table id\n * @param {Number} row index indicating the 1st row\n * @param {Object} configuration object\n */\n constructor(...args) {\n /**\n * ID of current instance\n * @type {String}\n * @private\n */\n this.id = null;\n\n /**\n * Current version\n * @type {String}\n */\n this.version = '{VERSION}';\n\n /**\n * Current year\n * @type {Number}\n * @private\n */\n this.year = new Date().getFullYear();\n\n /**\n * HTML Table DOM element\n * @type {DOMElement}\n */\n this.tbl = null;\n\n /**\n * Calculated row's index from which starts filtering once filters\n * are generated\n * @type {Number}\n */\n this.refRow = null;\n\n /**\n * Index of the headers row\n * @type {Number}\n * @private\n */\n this.headersRow = null;\n\n /**\n * Configuration object\n * @type {Object}\n * @private\n */\n this.cfg = {};\n\n /**\n * Number of rows that can be filtered\n * @type {Number}\n * @private\n */\n this.nbFilterableRows = 0;\n\n /**\n * Number of cells in the reference row\n * @type {Number}\n * @private\n */\n this.nbCells = null;\n\n let startRow;\n\n // TODO: use for-of\n args.forEach((arg) => {\n if (typeof arg === 'object' && arg.nodeName === 'TABLE') {\n this.tbl = arg;\n this.id = arg.id || `tf_${new Date().getTime()}_`;\n } else if (isString(arg)) {\n this.id = arg;\n this.tbl = elm(arg);\n } else if (isNumber(arg)) {\n startRow = arg;\n } else if (isObj(arg)) {\n this.cfg = arg;\n }\n });\n\n if (!this.tbl || this.tbl.nodeName !== 'TABLE' ||\n this.getRowsNb() === 0) {\n throw new Error(`Could not instantiate TableFilter: HTML table\n DOM element not found.`);\n }\n\n // configuration object\n let f = this.cfg;\n\n /**\n * Event emitter instance\n * @type {Emitter}\n */\n this.emitter = new Emitter();\n\n //Start row et cols nb\n this.refRow = isUndef(startRow) ? 2 : (startRow + 1);\n try { this.nbCells = this.getCellsNb(this.refRow); }\n catch (e) { this.nbCells = this.getCellsNb(0); }\n\n /**\n * Base path for static assets\n * @type {String}\n */\n this.basePath = f.base_path || 'tablefilter/';\n\n /*** filters' grid properties ***/\n\n /**\n * Enable/disable filters\n * @type {Boolean}\n */\n this.fltGrid = f.grid === false ? false : true;\n\n /**\n * Enable/disable grid layout (fixed headers)\n * @type {Boolean}\n */\n this.gridLayout = Boolean(f.grid_layout);\n\n /**\n * Filters row index\n * @type {Number}\n */\n this.filtersRowIndex = isNaN(f.filters_row_index) ?\n 0 : f.filters_row_index;\n\n /**\n * Headers row index\n * @type {Number}\n */\n this.headersRow = isNaN(f.headers_row_index) ?\n (this.filtersRowIndex === 0 ? 1 : 0) : f.headers_row_index;\n\n /**\n * Define the type of cell containing a filter (td/th)\n * @type {String}\n */\n this.fltCellTag = isString(f.filters_cell_tag) ?\n f.filters_cell_tag : CELL_TAG;\n\n /**\n * List of filters IDs\n * @type {Array}\n * @private\n */\n this.fltIds = [];\n\n /**\n * List of valid rows indexes (rows visible upon filtering)\n * @type {Array}\n * @private\n */\n this.validRowsIndex = [];\n\n /**\n * Toolbar's container DOM element\n * @type {DOMElement}\n * @private\n */\n this.infDiv = null;\n\n /**\n * Left-side inner container DOM element (rows counter in toolbar)\n * @type {DOMElement}\n * @private\n */\n this.lDiv = null;\n\n /**\n * Right-side inner container DOM element (reset button,\n * page length selector in toolbar)\n * @type {DOMElement}\n * @private\n */\n this.rDiv = null;\n\n /**\n * Middle inner container DOM element (paging elements in toolbar)\n * @type {DOMElement}\n * @private\n */\n this.mDiv = null;\n\n /**\n * Css class for toolbar's container DOM element\n * @type {String}\n */\n this.infDivCssClass = f.inf_div_css_class || 'inf';\n\n /**\n * Css class for left-side inner container DOM element\n * @type {String}\n */\n this.lDivCssClass = f.left_div_css_class || 'ldiv';\n\n /**\n * Css class for right-side inner container DOM element\n * @type {String}\n */\n this.rDivCssClass = f.right_div_css_class || 'rdiv';\n\n /**\n * Css class for middle inner container DOM element\n * @type {String}\n */\n this.mDivCssClass = f.middle_div_css_class || 'mdiv';\n\n /*** filters' grid appearance ***/\n /**\n * Path for stylesheets\n * @type {String}\n */\n this.stylePath = f.style_path || this.basePath + 'style/';\n\n /**\n * Main stylesheet path\n * @type {String}\n */\n this.stylesheet = f.stylesheet || this.stylePath + 'tablefilter.css';\n\n /**\n * Main stylesheet ID\n * @type {String}\n * @private\n */\n this.stylesheetId = this.id + '_style';\n\n /**\n * Css class for the filters row\n * @type {String}\n */\n this.fltsRowCssClass = f.flts_row_css_class || 'fltrow';\n\n /**\n * Enable/disable icons (paging, reset button)\n * @type {Boolean}\n */\n this.enableIcons = f.enable_icons === false ? false : true;\n\n /**\n * Enable/disable alternating rows\n * @type {Boolean}\n */\n this.alternateRows = Boolean(f.alternate_rows);\n\n /**\n * Indicate whether columns widths are set\n * @type {Boolean}\n * @private\n */\n this.hasColWidths = isArray(f.col_widths);\n\n /**\n * Columns widths array\n * @type {Array}\n */\n this.colWidths = this.hasColWidths ? f.col_widths : [];\n\n /**\n * Css class for a filter element\n * @type {String}\n */\n this.fltCssClass = f.flt_css_class || 'flt';\n\n /**\n * Css class for multiple select filters\n * @type {String}\n */\n this.fltMultiCssClass = f.flt_multi_css_class || 'flt_multi';\n\n /**\n * Css class for small filter (when submit button is active)\n * @type {String}\n */\n this.fltSmallCssClass = f.flt_small_css_class || 'flt_s';\n\n /**\n * Css class for single filter type\n * @type {String}\n */\n this.singleFltCssClass = f.single_flt_css_class || 'single_flt';\n\n /*** filters' grid behaviours ***/\n\n /**\n * Enable/disable enter key for input type filters\n * @type {Boolean}\n */\n this.enterKey = f.enter_key === false ? false : true;\n\n /**\n * Callback fired before filtering process starts\n * @type {Function}\n */\n this.onBeforeFilter = isFn(f.on_before_filter) ?\n f.on_before_filter : null;\n\n /**\n * Callback fired after filtering process is completed\n * @type {Function}\n */\n this.onAfterFilter = isFn(f.on_after_filter) ? f.on_after_filter : null;\n\n /**\n * Enable/disable case sensitivity filtering\n * @type {Boolean}\n */\n this.caseSensitive = Boolean(f.case_sensitive);\n\n /**\n * Indicate whether exact match filtering is enabled on a per column\n * basis\n * @type {Boolean}\n * @private\n */\n this.hasExactMatchByCol = isArray(f.columns_exact_match);\n\n /**\n * Exact match filtering per column array\n * @type {Array}\n */\n this.exactMatchByCol = this.hasExactMatchByCol ?\n f.columns_exact_match : [];\n\n /**\n * Globally enable/disable exact match filtering\n * @type {Boolean}\n */\n this.exactMatch = Boolean(f.exact_match);\n\n /**\n * Enable/disable linked filters filtering mode\n * @type {Boolean}\n */\n this.linkedFilters = Boolean(f.linked_filters);\n\n /**\n * Enable/disable readonly state for excluded options when\n * linked filters filtering mode is on\n * @type {Boolean}\n */\n this.disableExcludedOptions = Boolean(f.disable_excluded_options);\n\n /**\n * Active filter ID\n * @type {String}\n * @private\n */\n this.activeFilterId = null;\n\n /**\n * Enable/disable always visible rows, excluded from filtering\n * @type {Boolean}\n */\n this.hasVisibleRows = Boolean(f.rows_always_visible);\n\n /**\n * List of row indexes to be excluded from filtering\n * @type {Array}\n */\n this.visibleRows = this.hasVisibleRows ? f.rows_always_visible : [];\n\n /**\n * Enable/disable external filters generation\n * @type {Boolean}\n */\n this.isExternalFlt = Boolean(f.external_flt_grid);\n\n /**\n * List of containers IDs where external filters will be generated\n * @type {Array}\n */\n this.externalFltTgtIds = f.external_flt_grid_ids || [];\n\n /**\n * Callback fired after filters are generated\n * @type {Function}\n */\n this.onFiltersLoaded = isFn(f.on_filters_loaded) ?\n f.on_filters_loaded : null;\n\n /**\n * Enable/disable single filter filtering all columns\n * @type {Boolean}\n */\n this.singleSearchFlt = Boolean(f.single_filter);\n\n /**\n * Callback fired after a row is validated during filtering\n * @type {Function}\n */\n this.onRowValidated = isFn(f.on_row_validated) ?\n f.on_row_validated : null;\n\n /**\n * List of columns implementing custom filtering\n * @type {Array}\n */\n this.customCellDataCols = f.custom_cell_data_cols ?\n f.custom_cell_data_cols : [];\n\n /**\n * Delegate function for retrieving cell data with custom logic\n * @type {Function}\n */\n this.customCellData = isFn(f.custom_cell_data) ?\n f.custom_cell_data : null;\n\n /**\n * Global watermark text for input filter type or watermark for each\n * filter if an array is supplied\n * @type {String|Array}\n */\n this.watermark = f.watermark || '';\n\n /**\n * Indicate whether watermark is on a per column basis\n * @type {Boolean}\n * @private\n */\n this.isWatermarkArray = isArray(this.watermark);\n\n /**\n * Toolbar's custom container ID\n * @type {String}\n */\n this.toolBarTgtId = f.toolbar_target_id || null;\n\n /**\n * Indicate whether help UI component is disabled\n * @type {Boolean}\n */\n this.help = isUndef(f.help_instructions) ?\n undefined : Boolean(f.help_instructions);\n\n /**\n * Indicate whether pop-up filters UI is enabled\n * @type {Boolean}\n */\n this.popupFilters = Boolean(f.popup_filters);\n\n /**\n * Indicate whether filtered (active) columns indicator is enabled\n * @type {Boolean}\n */\n this.markActiveColumns = Boolean(f.mark_active_columns);\n\n /**\n * Css class for filtered (active) columns\n * @type {String}\n */\n this.activeColumnsCssClass = f.active_columns_css_class ||\n 'activeHeader';\n\n /**\n * Callback fired before a column is marked as filtered\n * @type {Function}\n */\n this.onBeforeActiveColumn = isFn(f.on_before_active_column) ?\n f.on_before_active_column : null;\n\n /**\n * Callback fired after a column is marked as filtered\n * @type {Function}\n */\n this.onAfterActiveColumn = isFn(f.on_after_active_column) ?\n f.on_after_active_column : null;\n\n /*** select filter's customisation and behaviours ***/\n /**\n * Text for clear option in drop-down filter types (1st option)\n * @type {String}\n */\n this.displayAllText = f.display_all_text || 'Clear';\n\n /**\n * Indicate whether empty option is enabled in drop-down filter types\n * @type {Boolean}\n */\n this.enableEmptyOption = Boolean(f.enable_empty_option);\n\n /**\n * Text for empty option in drop-down filter types\n * @type {String}\n */\n this.emptyText = f.empty_text || '(Empty)';\n\n /**\n * Indicate whether non-empty option is enabled in drop-down filter\n * types\n * @type {Boolean}\n */\n this.enableNonEmptyOption = Boolean(f.enable_non_empty_option);\n\n /**\n * Text for non-empty option in drop-down filter types\n * @type {String}\n */\n this.nonEmptyText = f.non_empty_text || '(Non empty)';\n\n /**\n * Indicate whether drop-down filter types filter the table by default\n * on change event\n * @type {Boolean}\n */\n this.onSlcChange = f.on_change === false ? false : true;\n\n /**\n * Indicate whether options in drop-down filter types are sorted in a\n * alpha-numeric manner by default\n * @type {Boolean}\n */\n this.sortSlc = f.sort_select === false ? false : true;\n\n /**\n * Indicate whether options in drop-down filter types are sorted in a\n * ascending numeric manner\n * @type {Boolean}\n * @private\n */\n this.isSortNumAsc = Boolean(f.sort_num_asc);\n\n /**\n * List of columns implementing options sorting in a ascending numeric\n * manner\n * @type {Array}\n */\n this.sortNumAsc = this.isSortNumAsc ? f.sort_num_asc : [];\n\n /**\n * Indicate whether options in drop-down filter types are sorted in a\n * descending numeric manner\n * @type {Boolean}\n * @private\n */\n this.isSortNumDesc = Boolean(f.sort_num_desc);\n\n /**\n * List of columns implementing options sorting in a descending numeric\n * manner\n * @type {Array}\n */\n this.sortNumDesc = this.isSortNumDesc ? f.sort_num_desc : [];\n\n /**\n * Indicate whether drop-down filter types are populated on demand at\n * first usage\n * @type {Boolean}\n */\n this.loadFltOnDemand = Boolean(f.load_filters_on_demand);\n\n /**\n * Indicate whether custom drop-down filter options are implemented\n * @type {Boolean}\n */\n this.hasCustomOptions = isObj(f.custom_options);\n\n /**\n * Custom options definition of a per column basis, ie:\n *\tcustom_options: {\n * cols:[0, 1],\n * texts: [\n * ['a0', 'b0', 'c0'],\n * ['a1', 'b1', 'c1']\n * ],\n * values: [\n * ['a0', 'b0', 'c0'],\n * ['a1', 'b1', 'c1']\n * ],\n * sorts: [false, true]\n * }\n *\n * @type {Object}\n */\n this.customOptions = f.custom_options;\n\n /*** Filter operators ***/\n /**\n * Regular expression operator for input filter. Defaults to 'rgx:'\n * @type {String}\n */\n this.rgxOperator = f.regexp_operator || 'rgx:';\n\n /**\n * Empty cells operator for input filter. Defaults to '[empty]'\n * @type {String}\n */\n this.emOperator = f.empty_operator || '[empty]';\n\n /**\n * Non-empty cells operator for input filter. Defaults to '[nonempty]'\n * @type {String}\n */\n this.nmOperator = f.nonempty_operator || '[nonempty]';\n\n /**\n * Logical OR operator for input filter. Defaults to '||'\n * @type {String}\n */\n this.orOperator = f.or_operator || '||';\n\n /**\n * Logical AND operator for input filter. Defaults to '&&'\n * @type {String}\n */\n this.anOperator = f.and_operator || '&&';\n\n /**\n * Greater than operator for input filter. Defaults to '>'\n * @type {String}\n */\n this.grOperator = f.greater_operator || '>';\n\n /**\n * Lower than operator for input filter. Defaults to '<'\n * @type {String}\n */\n this.lwOperator = f.lower_operator || '<';\n\n /**\n * Lower than or equal operator for input filter. Defaults to '<='\n * @type {String}\n */\n this.leOperator = f.lower_equal_operator || '<=';\n\n /**\n * Greater than or equal operator for input filter. Defaults to '>='\n * @type {String}\n */\n this.geOperator = f.greater_equal_operator || '>=';\n\n /**\n * Inequality operator for input filter. Defaults to '!'\n * @type {String}\n */\n this.dfOperator = f.different_operator || '!';\n\n /**\n * Like operator for input filter. Defaults to '!'\n * @type {String}\n */\n this.lkOperator = f.like_operator || '*';\n\n /**\n * Strict equality operator for input filter. Defaults to '='\n * @type {String}\n */\n this.eqOperator = f.equal_operator || '=';\n\n /**\n * Starts with operator for input filter. Defaults to '='\n * @type {String}\n */\n this.stOperator = f.start_with_operator || '{';\n\n /**\n * Ends with operator for input filter. Defaults to '='\n * @type {String}\n */\n this.enOperator = f.end_with_operator || '}';\n\n // this.curExp = f.cur_exp || '^[¥£€$]';\n\n /**\n * Stored values separator\n * @type {String}\n */\n this.separator = f.separator || ',';\n\n /**\n * Enable rows counter UI component\n * @type {Boolean}\n */\n this.rowsCounter = Boolean(f.rows_counter);\n\n /**\n * Enable status bar UI component\n * @type {Boolean}\n */\n this.statusBar = Boolean(f.status_bar);\n\n /**\n * Enable activity/spinner indicator UI component\n * @type {Boolean}\n */\n this.loader = Boolean(f.loader);\n\n /*** validation - reset buttons/links ***/\n /**\n * Enable filters submission button\n * @type {Boolean}\n */\n this.displayBtn = Boolean(f.btn);\n\n /**\n * Define filters submission button text\n * @type {String}\n */\n this.btnText = f.btn_text || (!this.enableIcons ? 'Go' : '');\n\n /**\n * Css class for filters submission button\n * @type {String}\n */\n this.btnCssClass = f.btn_css_class ||\n (!this.enableIcons ? 'btnflt' : 'btnflt_icon');\n\n /**\n * Enable clear button\n * @type {Boolean}\n */\n this.btnReset = Boolean(f.btn_reset);\n\n /**\n * Callback fired before filters are cleared\n * @type {Function}\n */\n this.onBeforeReset = isFn(f.on_before_reset) ?\n f.on_before_reset : null;\n\n /**\n * Callback fired after filters are cleared\n * @type {Function}\n */\n this.onAfterReset = isFn(f.on_after_reset) ? f.on_after_reset : null;\n\n /**\n * Enable paging component\n * @type {Boolean}\n */\n this.paging = Boolean(f.paging);\n\n /**\n * Number of hidden rows\n * @type {Number}\n * @private\n */\n this.nbHiddenRows = 0;\n\n /**\n * Enable auto-filter behaviour, table is filtered when a user\n * stops typing\n * @type {Boolean}\n */\n this.autoFilter = Boolean(f.auto_filter);\n\n /**\n * Auto-filter delay in msecs\n * @type {Number}\n */\n this.autoFilterDelay = !isNaN(f.auto_filter_delay) ?\n f.auto_filter_delay : AUTO_FILTER_DELAY;\n\n /**\n * Indicate whether user is typing\n * @type {Boolean}\n * @private\n */\n this.isUserTyping = null;\n\n /**\n * Auto-filter interval ID\n * @type {String}\n * @private\n */\n this.autoFilterTimer = null;\n\n /**\n * Enable keyword highlighting behaviour\n * @type {Boolean}\n */\n this.highlightKeywords = Boolean(f.highlight_keywords);\n\n /**\n * Enable no results message UI component\n * @type {Boolean}\n */\n this.noResults = isObj(f.no_results_message) ||\n Boolean(f.no_results_message);\n\n /**\n * Enable state persistence\n * @type {Boolean}\n */\n this.state = isObj(f.state) || Boolean(f.state);\n\n /*** data types ***/\n /**\n * Define default date type (DMY)\n * @type {String}\n */\n this.defaultDateType = f.default_date_type || 'DMY';\n\n /**\n * Define thousands separator ',' or '.', defaults to ','\n * @type {String}\n */\n this.thousandsSeparator = f.thousands_separator || ',';\n\n /**\n * Define decimal separator ',' or '.', defaults to '.'\n * @type {String}\n */\n this.decimalSeparator = f.decimal_separator || '.';\n\n /**\n * Determine whether table has columns with numeric formats\n * @type {Boolean}\n * @private\n */\n this.hasColNbFormat = isArray(f.col_number_format);\n\n /**\n * Define numeric format on a column basis, two possible values 'EU' and\n * 'US', ie:\n * col_number_format : [null, 'US', 'EU', null]\n * @type {Array}\n */\n this.colNbFormat = this.hasColNbFormat ? f.col_number_format : null;\n\n /**\n * Determine whether table has columns with date types\n * @type {Boolean}\n * @private\n */\n this.hasColDateType = isArray(f.col_date_type);\n\n /**\n * Define date format on a column basis, possible values 'DMY', 'MDY',\n * 'YMD', 'DDMMMYYYY', ie:\n * col_date_type : [null, 'DMY', 'MDY', 'YMD', null, 'DDMMMYYYY']\n * @type {Array}\n */\n this.colDateType = this.hasColDateType ? f.col_date_type : null;\n\n /*** ids prefixes ***/\n /**\n * Main prefix\n * @private\n */\n this.prfxTf = 'TF';\n\n /**\n * Filter's ID prefix (inputs - selects)\n * @private\n */\n this.prfxFlt = 'flt';\n\n /**\n * Button's ID prefix\n * @private\n */\n this.prfxValButton = 'btn';\n\n /**\n * Toolbar container ID prefix\n * @private\n */\n this.prfxInfDiv = 'inf_';\n\n /**\n * Toolbar left element ID prefix\n * @private\n */\n this.prfxLDiv = 'ldiv_';\n\n /**\n * Toolbar right element ID prefix\n * @private\n */\n this.prfxRDiv = 'rdiv_';\n\n /**\n * Toolbar middle element ID prefix\n * @private\n */\n this.prfxMDiv = 'mdiv_';\n\n /**\n * Responsive Css class\n * @private\n */\n this.prfxResponsive = 'resp';\n\n /*** extensions ***/\n /**\n * List of loaded extensions\n * @type {Array}\n * @private\n */\n this.extensions = f.extensions;\n\n /**\n * Determine whether extensions are loaded\n * @type {Boolean}\n * @private\n */\n this.hasExtensions = isArray(this.extensions);\n\n /*** themes ***/\n /**\n * Enable default theme\n * @type {Boolean}\n */\n this.enableDefaultTheme = Boolean(f.enable_default_theme);\n\n /**\n * Determine whether themes are enables\n * @type {Boolean}\n * @private\n */\n this.hasThemes = (this.enableDefaultTheme || isArray(f.themes));\n\n /**\n * List of themes, ie:\n * themes: [{ name: 'skyblue' }]\n * @type {Array}\n */\n this.themes = f.themes || [];\n\n /**\n * Define path to themes assets, defaults to\n * 'tablefilter/style/themes/'. Usage:\n * themes: [{ name: 'skyblue' }]\n * @type {Array}\n */\n this.themesPath = f.themes_path || this.stylePath + 'themes/';\n\n /**\n * Enable responsive layout\n * @type {Boolean}\n */\n this.responsive = Boolean(f.responsive);\n\n /**\n * Features registry\n * @private\n */\n this.Mod = {};\n\n /**\n * Extensions registry\n * @private\n */\n this.ExtRegistry = {};\n }\n\n /**\n * Initialise features and layout\n */\n init() {\n if (this.initialized) {\n return;\n }\n\n let Mod = this.Mod;\n let n = this.singleSearchFlt ? 1 : this.nbCells;\n let inpclass;\n\n //loads stylesheet if not imported\n this.import(this.stylesheetId, this.stylesheet, null, 'link');\n\n //loads theme\n if (this.hasThemes) {\n this.loadThemes();\n }\n\n // Instantiate help feature and initialise only if set true\n if (!Mod.help) {\n Mod.help = new Help(this);\n }\n if (this.help) {\n Mod.help.init();\n }\n\n if (this.state) {\n if (!Mod.state) {\n Mod.state = new State(this);\n }\n Mod.state.init();\n }\n\n if (this.gridLayout) {\n if (!Mod.gridLayout) {\n Mod.gridLayout = new GridLayout(this);\n }\n Mod.gridLayout.init();\n }\n\n if (this.loader) {\n if (!Mod.loader) {\n Mod.loader = new Loader(this);\n }\n Mod.loader.init();\n }\n\n if (this.highlightKeywords) {\n Mod.highlightKeyword = new HighlightKeyword(this);\n Mod.highlightKeyword.init();\n }\n\n if (this.popupFilters) {\n if (!Mod.popupFilter) {\n Mod.popupFilter = new PopupFilter(this);\n }\n Mod.popupFilter.init();\n }\n\n //filters grid is not generated\n if (!this.fltGrid) {\n this._initNoFilters();\n } else {\n let fltrow = this._insertFiltersRow();\n\n this.nbFilterableRows = this.getRowsNb();\n\n // Generate filters\n for (let i = 0; i < n; i++) {\n this.emitter.emit('before-filter-init', this, i);\n\n let fltcell = createElm(this.fltCellTag),\n col = this.getFilterType(i);\n\n if (this.singleSearchFlt) {\n fltcell.colSpan = this.nbCells;\n }\n if (!this.gridLayout) {\n fltrow.appendChild(fltcell);\n }\n inpclass = (i === n - 1 && this.displayBtn) ?\n this.fltSmallCssClass : this.fltCssClass;\n\n //only 1 input for single search\n if (this.singleSearchFlt) {\n col = INPUT;\n inpclass = this.singleFltCssClass;\n }\n\n //drop-down filters\n if (col === SELECT || col === MULTIPLE) {\n if (!Mod.dropdown) {\n Mod.dropdown = new Dropdown(this);\n }\n Mod.dropdown.init(i, this.isExternalFlt, fltcell);\n }\n // checklist\n else if (col === CHECKLIST) {\n if (!Mod.checkList) {\n Mod.checkList = new CheckList(this);\n }\n Mod.checkList.init(i, this.isExternalFlt, fltcell);\n } else {\n this._buildInputFilter(i, inpclass, fltcell);\n }\n\n // this adds submit button\n if (i === n - 1 && this.displayBtn) {\n this._buildSubmitButton(i, fltcell);\n }\n\n this.emitter.emit('after-filter-init', this, i);\n }\n\n this.emitter.on(['filter-focus'],\n (tf, filter) => this.setActiveFilterId(filter.id));\n\n }//if this.fltGrid\n\n /* Features */\n if (this.hasVisibleRows) {\n this.emitter.on(['after-filtering'],\n () => this.enforceVisibility());\n this.enforceVisibility();\n }\n if (this.rowsCounter) {\n Mod.rowsCounter = new RowsCounter(this);\n Mod.rowsCounter.init();\n }\n if (this.statusBar) {\n Mod.statusBar = new StatusBar(this);\n Mod.statusBar.init();\n }\n if (this.paging) {\n if (!Mod.paging) {\n Mod.paging = new Paging(this);\n Mod.paging.init();\n } else {\n Mod.paging.reset();\n }\n }\n if (this.btnReset) {\n Mod.clearButton = new ClearButton(this);\n Mod.clearButton.init();\n }\n\n if (this.hasColWidths && !this.gridLayout) {\n this.setColWidths();\n }\n if (this.alternateRows) {\n Mod.alternateRows = new AlternateRows(this);\n Mod.alternateRows.init();\n }\n if (this.noResults) {\n if (!Mod.noResults) {\n Mod.noResults = new NoResults(this);\n }\n Mod.noResults.init();\n }\n\n //TF css class is added to table\n if (!this.gridLayout) {\n addClass(this.tbl, this.prfxTf);\n if (this.responsive) {\n addClass(this.tbl, this.prfxResponsive);\n }\n }\n\n /* Loads extensions */\n if (this.hasExtensions) {\n this.initExtensions();\n }\n\n // Subscribe to events\n if (this.markActiveColumns) {\n this.emitter.on(['before-filtering'],\n () => this.clearActiveColumns());\n this.emitter.on(['cell-processed'],\n (tf, colIndex) => this.markActiveColumn(colIndex));\n }\n if (this.linkedFilters) {\n this.emitter.on(['after-filtering'], () => this.linkFilters());\n }\n\n /**\n * @inherited\n */\n this.initialized = true;\n\n if (this.onFiltersLoaded) {\n this.onFiltersLoaded.call(null, this);\n }\n this.emitter.emit('initialized', this);\n }\n\n /**\n * Detect key\n * @param {Event} evt\n */\n detectKey(evt) {\n if (!this.enterKey) {\n return;\n }\n if (evt) {\n let key = keyCode(evt);\n if (key === ENTER_KEY) {\n this.filter();\n cancelEvt(evt);\n stopEvt(evt);\n } else {\n this.isUserTyping = true;\n root.clearInterval(this.autoFilterTimer);\n this.autoFilterTimer = null;\n }\n }\n }\n\n /**\n * Filter's keyup event: if auto-filter on, detect user is typing and filter\n * columns\n * @param {Event} evt\n */\n onKeyUp(evt) {\n if (!this.autoFilter) {\n return;\n }\n let key = keyCode(evt);\n this.isUserTyping = false;\n\n function filter() {\n root.clearInterval(this.autoFilterTimer);\n this.autoFilterTimer = null;\n if (!this.isUserTyping) {\n this.filter();\n this.isUserTyping = null;\n }\n }\n\n if (key !== ENTER_KEY && key !== TAB_KEY && key !== ESC_KEY &&\n key !== UP_ARROW_KEY && key !== DOWN_ARROW_KEY) {\n if (this.autoFilterTimer === null) {\n this.autoFilterTimer = root.setInterval(filter.bind(this),\n this.autoFilterDelay);\n }\n } else {\n root.clearInterval(this.autoFilterTimer);\n this.autoFilterTimer = null;\n }\n }\n\n /**\n * Filter's keydown event: if auto-filter on, detect user is typing\n */\n onKeyDown() {\n if (this.autoFilter) {\n this.isUserTyping = true;\n }\n }\n\n /**\n * Filter's focus event\n * @param {Event} evt\n */\n onInpFocus(evt) {\n let elm = targetEvt(evt);\n this.emitter.emit('filter-focus', this, elm);\n }\n\n /**\n * Filter's blur event: if auto-filter on, clear interval on filter blur\n */\n onInpBlur() {\n if (this.autoFilter) {\n this.isUserTyping = false;\n root.clearInterval(this.autoFilterTimer);\n }\n this.emitter.emit('filter-blur', this);\n }\n\n /**\n * Insert filters row at initialization\n */\n _insertFiltersRow() {\n if (this.gridLayout) {\n return;\n }\n let fltrow;\n\n let thead = tag(this.tbl, 'thead');\n if (thead.length > 0) {\n fltrow = thead[0].insertRow(this.filtersRowIndex);\n } else {\n fltrow = this.tbl.insertRow(this.filtersRowIndex);\n }\n\n fltrow.className = this.fltsRowCssClass;\n\n if (this.isExternalFlt) {\n fltrow.style.display = NONE;\n }\n\n this.emitter.emit('filters-row-inserted', this, fltrow);\n return fltrow;\n }\n\n /**\n * Initialize filtersless table\n */\n _initNoFilters() {\n if (this.fltGrid) {\n return;\n }\n this.refRow = this.refRow > 0 ? this.refRow - 1 : 0;\n this.nbFilterableRows = this.getRowsNb();\n }\n\n /**\n * Build input filter type\n * @param {Number} colIndex Column index\n * @param {String} cssClass Css class applied to filter\n * @param {DOMElement} container Container DOM element\n */\n _buildInputFilter(colIndex, cssClass, container) {\n let col = this.getFilterType(colIndex);\n let externalFltTgtId = this.isExternalFlt ?\n this.externalFltTgtIds[colIndex] : null;\n let inptype = col === INPUT ? 'text' : 'hidden';\n let inp = createElm(INPUT,\n ['id', this.prfxFlt + colIndex + '_' + this.id],\n ['type', inptype], ['ct', colIndex]);\n\n if (inptype !== 'hidden' && this.watermark) {\n inp.setAttribute('placeholder',\n this.isWatermarkArray ? (this.watermark[colIndex] || '') :\n this.watermark\n );\n }\n inp.className = cssClass || this.fltCssClass;\n addEvt(inp, 'focus', (evt) => this.onInpFocus(evt));\n\n //filter is appended in custom element\n if (externalFltTgtId) {\n elm(externalFltTgtId).appendChild(inp);\n } else {\n container.appendChild(inp);\n }\n\n this.fltIds.push(inp.id);\n\n addEvt(inp, 'keypress', (evt) => this.detectKey(evt));\n addEvt(inp, 'keydown', () => this.onKeyDown());\n addEvt(inp, 'keyup', (evt) => this.onKeyUp(evt));\n addEvt(inp, 'blur', () => this.onInpBlur());\n }\n\n /**\n * Build submit button\n * @param {Number} colIndex Column index\n * @param {DOMElement} container Container DOM element\n */\n _buildSubmitButton(colIndex, container) {\n let externalFltTgtId = this.isExternalFlt ?\n this.externalFltTgtIds[colIndex] : null;\n let btn = createElm(INPUT,\n ['id', this.prfxValButton + colIndex + '_' + this.id],\n ['type', 'button'], ['value', this.btnText]);\n btn.className = this.btnCssClass;\n\n //filter is appended in custom element\n if (externalFltTgtId) {\n elm(externalFltTgtId).appendChild(btn);\n } else {\n container.appendChild(btn);\n }\n\n addEvt(btn, 'click', () => this.filter());\n }\n\n /**\n * Return a feature instance for a given name\n * @param {String} name Name of the feature\n * @return {Object}\n */\n feature(name) {\n return this.Mod[name];\n }\n\n /**\n * Initialise all the extensions defined in the configuration object\n */\n initExtensions() {\n let exts = this.extensions;\n // Set config's publicPath dynamically for Webpack...\n __webpack_public_path__ = this.basePath;\n\n this.emitter.emit('before-loading-extensions', this);\n for (let i = 0, len = exts.length; i < len; i++) {\n let ext = exts[i];\n if (!this.ExtRegistry[ext.name]) {\n this.loadExtension(ext);\n }\n }\n this.emitter.emit('after-loading-extensions', this);\n }\n\n /**\n * Load an extension module\n * @param {Object} ext Extension config object\n */\n loadExtension(ext) {\n if (!ext || !ext.name) {\n return;\n }\n\n let name = ext.name;\n let path = ext.path;\n let modulePath;\n\n if (name && path) {\n modulePath = ext.path + name;\n } else {\n name = name.replace('.js', '');\n modulePath = 'extensions/{}/{}'.replace(/{}/g, name);\n }\n\n // Require pattern for Webpack\n require(['./' + modulePath], (mod) => {\n /* eslint-disable */\n let inst = new mod.default(this, ext);\n /* eslint-enable */\n inst.init();\n this.ExtRegistry[name] = inst;\n });\n }\n\n /**\n * Get an extension instance\n * @param {String} name Name of the extension\n * @return {Object} Extension instance\n */\n extension(name) {\n return this.ExtRegistry[name];\n }\n\n /**\n * Check passed extension name exists\n * @param {String} name Name of the extension\n * @return {Boolean}\n */\n hasExtension(name) {\n return !isEmpty(this.ExtRegistry[name]);\n }\n\n /**\n * Destroy all the extensions defined in the configuration object\n */\n destroyExtensions() {\n let exts = this.extensions;\n\n for (let i = 0, len = exts.length; i < len; i++) {\n let ext = exts[i];\n let extInstance = this.ExtRegistry[ext.name];\n if (extInstance) {\n extInstance.destroy();\n this.ExtRegistry[ext.name] = undefined;\n }\n }\n }\n\n /**\n * Load themes defined in the configuration object\n */\n loadThemes() {\n let themes = this.themes;\n this.emitter.emit('before-loading-themes', this);\n\n //Default theme config\n if (this.enableDefaultTheme) {\n let defaultTheme = { name: 'default' };\n this.themes.push(defaultTheme);\n }\n if (isArray(themes)) {\n for (let i = 0, len = themes.length; i < len; i++) {\n let theme = themes[i];\n let name = theme.name;\n let path = theme.path;\n let styleId = this.prfxTf + name;\n if (name && !path) {\n path = this.themesPath + name + '/' + name + '.css';\n }\n else if (!name && theme.path) {\n name = 'theme{0}'.replace('{0}', i);\n }\n\n if (!this.isImported(path, 'link')) {\n this.import(styleId, path, null, 'link');\n }\n }\n }\n\n // Enable loader indicator\n this.loader = true;\n\n this.emitter.emit('after-loading-themes', this);\n }\n\n /**\n * Return stylesheet DOM element for a given theme name\n * @return {DOMElement} stylesheet element\n */\n getStylesheet(name = 'default') {\n return elm(this.prfxTf + name);\n }\n\n /**\n * Destroy filter grid\n */\n destroy() {\n if (!this.initialized) {\n return;\n }\n\n let Mod = this.Mod;\n let emitter = this.emitter;\n\n if (this.isExternalFlt && !this.popupFilters) {\n this.removeExternalFlts();\n }\n if (this.infDiv) {\n this.removeToolbar();\n }\n if (this.markActiveColumns) {\n this.clearActiveColumns();\n emitter.off(['before-filtering'], () => this.clearActiveColumns());\n emitter.off(['cell-processed'],\n (tf, colIndex) => this.markActiveColumn(colIndex));\n }\n if (this.hasExtensions) {\n this.destroyExtensions();\n }\n\n this.validateAllRows();\n\n if (this.fltGrid && !this.gridLayout) {\n this.tbl.deleteRow(this.filtersRowIndex);\n }\n\n // broadcast destroy event\n emitter.emit('destroy', this);\n\n // Destroy modules\n // TODO: subcribe modules to destroy event instead\n Object.keys(Mod).forEach(function (key) {\n let feature = Mod[key];\n if (feature && isFn(feature.destroy)) {\n feature.destroy();\n }\n });\n\n // unsubscribe to events\n if (this.hasVisibleRows) {\n emitter.off(['after-filtering'], () => this.enforceVisibility());\n }\n if (this.linkedFilters) {\n emitter.off(['after-filtering'], () => this.linkFilters());\n }\n this.emitter.off(['filter-focus'],\n (tf, filter) => this.setActiveFilterId(filter.id));\n\n removeClass(this.tbl, this.prfxTf);\n removeClass(this.tbl, this.prfxResponsive);\n\n this.nbHiddenRows = 0;\n this.validRowsIndex = [];\n this.fltIds = [];\n this.initialized = false;\n }\n\n /**\n * Generate container element for paging, reset button, rows counter etc.\n */\n setToolbar() {\n if (this.infDiv) {\n return;\n }\n\n /*** container div ***/\n let infdiv = createElm('div', ['id', this.prfxInfDiv + this.id]);\n infdiv.className = this.infDivCssClass;\n\n //custom container\n if (this.toolBarTgtId) {\n elm(this.toolBarTgtId).appendChild(infdiv);\n }\n //grid-layout\n else if (this.gridLayout) {\n let gridLayout = this.Mod.gridLayout;\n gridLayout.tblMainCont.appendChild(infdiv);\n infdiv.className = gridLayout.infDivCssClass;\n }\n //default location: just above the table\n else {\n let cont = createElm('caption');\n cont.appendChild(infdiv);\n this.tbl.insertBefore(cont, this.tbl.firstChild);\n }\n this.infDiv = elm(this.prfxInfDiv + this.id);\n\n /*** left div containing rows # displayer ***/\n let ldiv = createElm('div', ['id', this.prfxLDiv + this.id]);\n ldiv.className = this.lDivCssClass;\n infdiv.appendChild(ldiv);\n this.lDiv = elm(this.prfxLDiv + this.id);\n\n /*** right div containing reset button\n + nb results per page select ***/\n let rdiv = createElm('div', ['id', this.prfxRDiv + this.id]);\n rdiv.className = this.rDivCssClass;\n infdiv.appendChild(rdiv);\n this.rDiv = elm(this.prfxRDiv + this.id);\n\n /*** mid div containing paging elements ***/\n let mdiv = createElm('div', ['id', this.prfxMDiv + this.id]);\n mdiv.className = this.mDivCssClass;\n infdiv.appendChild(mdiv);\n this.mDiv = elm(this.prfxMDiv + this.id);\n\n // emit help initialisation only if undefined\n if (isUndef(this.help)) {\n // explicitily set enabled field to true to initialise help by\n // default, only if setting is undefined\n this.Mod.help.enabled = true;\n this.emitter.emit('init-help', this);\n }\n }\n\n /**\n * Remove toolbar container element\n */\n removeToolbar() {\n if (!this.infDiv) {\n return;\n }\n removeElm(this.infDiv);\n this.infDiv = null;\n\n let tbl = this.tbl;\n let captions = tag(tbl, 'caption');\n if (captions.length > 0) {\n [].forEach.call(captions, (elm) => tbl.removeChild(elm));\n }\n }\n\n /**\n * Remove all the external column filters\n */\n removeExternalFlts() {\n if (!this.isExternalFlt) {\n return;\n }\n let ids = this.externalFltTgtIds,\n len = ids.length;\n for (let ct = 0; ct < len; ct++) {\n let externalFltTgtId = ids[ct],\n externalFlt = elm(externalFltTgtId);\n if (externalFlt) {\n externalFlt.innerHTML = '';\n }\n }\n }\n\n /**\n * Check if given column implements a filter with custom options\n * @param {Number} colIndex Column's index\n * @return {Boolean}\n */\n isCustomOptions(colIndex) {\n return this.hasCustomOptions &&\n this.customOptions.cols.indexOf(colIndex) !== -1;\n }\n\n /**\n * Returns an array [[value0, value1 ...],[text0, text1 ...]] with the\n * custom options values and texts\n * @param {Number} colIndex Column's index\n * @return {Array}\n */\n getCustomOptions(colIndex) {\n if (isEmpty(colIndex) || !this.isCustomOptions(colIndex)) {\n return;\n }\n\n let customOptions = this.customOptions;\n let cols = customOptions.cols;\n let optTxt = [], optArray = [];\n let index = cols.indexOf(colIndex);\n let slcValues = customOptions.values[index];\n let slcTexts = customOptions.texts[index];\n let slcSort = customOptions.sorts[index];\n\n for (let r = 0, len = slcValues.length; r < len; r++) {\n optArray.push(slcValues[r]);\n if (slcTexts[r]) {\n optTxt.push(slcTexts[r]);\n } else {\n optTxt.push(slcValues[r]);\n }\n }\n if (slcSort) {\n optArray.sort();\n optTxt.sort();\n }\n return [optArray, optTxt];\n }\n\n /**\n * Filter the table by retrieving the data from each cell in every single\n * row and comparing it to the search term for current column. A row is\n * hidden when all the search terms are not found in inspected row.\n */\n filter() {\n if (!this.fltGrid || !this.initialized) {\n return;\n }\n //invoke onbefore callback\n if (this.onBeforeFilter) {\n this.onBeforeFilter.call(null, this);\n }\n this.emitter.emit('before-filtering', this);\n\n let row = this.tbl.rows,\n nbRows = this.getRowsNb(true),\n hiddenRows = 0;\n\n this.validRowsIndex = [];\n // search args re-init\n let searchArgs = this.getFiltersValue();\n\n let numCellData;\n let nbFormat;\n let re_le = new RegExp(this.leOperator),\n re_ge = new RegExp(this.geOperator),\n re_l = new RegExp(this.lwOperator),\n re_g = new RegExp(this.grOperator),\n re_d = new RegExp(this.dfOperator),\n re_lk = new RegExp(rgxEsc(this.lkOperator)),\n re_eq = new RegExp(this.eqOperator),\n re_st = new RegExp(this.stOperator),\n re_en = new RegExp(this.enOperator),\n // re_an = new RegExp(this.anOperator),\n // re_cr = new RegExp(this.curExp),\n re_em = this.emOperator,\n re_nm = this.nmOperator,\n re_re = new RegExp(rgxEsc(this.rgxOperator));\n\n //keyword highlighting\n function highlight(str, ok, cell) {\n /*jshint validthis:true */\n if (this.highlightKeywords && ok) {\n str = str.replace(re_lk, '');\n str = str.replace(re_eq, '');\n str = str.replace(re_st, '');\n str = str.replace(re_en, '');\n let w = str;\n if (re_le.test(str) || re_ge.test(str) || re_l.test(str) ||\n re_g.test(str) || re_d.test(str)) {\n w = getText(cell);\n }\n if (w !== '') {\n this.emitter.emit('highlight-keyword', this, cell, w);\n }\n }\n }\n\n //looks for search argument in current row\n function hasArg(sA, cellData, j) {\n sA = matchCase(sA, this.caseSensitive);\n\n let occurence;\n let dtType = this.hasColDateType ?\n this.colDateType[j] : this.defaultDateType;\n\n //Search arg operator tests\n let hasLO = re_l.test(sA),\n hasLE = re_le.test(sA),\n hasGR = re_g.test(sA),\n hasGE = re_ge.test(sA),\n hasDF = re_d.test(sA),\n hasEQ = re_eq.test(sA),\n hasLK = re_lk.test(sA),\n // hasAN = re_an.test(sA),\n hasST = re_st.test(sA),\n hasEN = re_en.test(sA),\n hasEM = (re_em === sA),\n hasNM = (re_nm === sA),\n hasRE = re_re.test(sA);\n\n //Search arg dates tests\n let isLDate = hasLO && isValidDate(sA.replace(re_l, ''), dtType);\n let isLEDate = hasLE && isValidDate(sA.replace(re_le, ''), dtType);\n let isGDate = hasGR && isValidDate(sA.replace(re_g, ''), dtType);\n let isGEDate = hasGE && isValidDate(sA.replace(re_ge, ''), dtType);\n let isDFDate = hasDF && isValidDate(sA.replace(re_d, ''), dtType);\n let isEQDate = hasEQ && isValidDate(sA.replace(re_eq, ''), dtType);\n\n let dte1, dte2;\n //dates\n if (isValidDate(cellData, dtType)) {\n dte1 = formatDate(cellData, dtType);\n // lower date\n if (isLDate) {\n dte2 = formatDate(sA.replace(re_l, ''), dtType);\n occurence = dte1 < dte2;\n }\n // lower equal date\n else if (isLEDate) {\n dte2 = formatDate(sA.replace(re_le, ''), dtType);\n occurence = dte1 <= dte2;\n }\n // greater equal date\n else if (isGEDate) {\n dte2 = formatDate(sA.replace(re_ge, ''), dtType);\n occurence = dte1 >= dte2;\n }\n // greater date\n else if (isGDate) {\n dte2 = formatDate(sA.replace(re_g, ''), dtType);\n occurence = dte1 > dte2;\n }\n // different date\n else if (isDFDate) {\n dte2 = formatDate(sA.replace(re_d, ''), dtType);\n occurence = dte1.toString() !== dte2.toString();\n }\n // equal date\n else if (isEQDate) {\n dte2 = formatDate(sA.replace(re_eq, ''), dtType);\n occurence = dte1.toString() === dte2.toString();\n }\n // searched keyword with * operator doesn't have to be a date\n else if (re_lk.test(sA)) {// like date\n occurence = contains(sA.replace(re_lk, ''), cellData,\n false, this.caseSensitive);\n }\n else if (isValidDate(sA, dtType)) {\n dte2 = formatDate(sA, dtType);\n occurence = dte1.toString() === dte2.toString();\n }\n //empty\n else if (hasEM) {\n occurence = isEmptyString(cellData);\n }\n //non-empty\n else if (hasNM) {\n occurence = !isEmptyString(cellData);\n } else {\n occurence = contains(sA, cellData, this.isExactMatch(j),\n this.caseSensitive);\n }\n }\n\n else {\n //first numbers need to be formated\n if (this.hasColNbFormat && this.colNbFormat[j]) {\n numCellData = removeNbFormat(cellData, this.colNbFormat[j]);\n nbFormat = this.colNbFormat[j];\n } else {\n if (this.thousandsSeparator === ',' &&\n this.decimalSeparator === '.') {\n numCellData = removeNbFormat(cellData, 'us');\n nbFormat = 'us';\n } else {\n numCellData = removeNbFormat(cellData, 'eu');\n nbFormat = 'eu';\n }\n }\n\n // first checks if there is any operator (<,>,<=,>=,!,*,=,{,},\n // rgx:)\n // lower equal\n if (hasLE) {\n occurence = numCellData <= removeNbFormat(\n sA.replace(re_le, ''), nbFormat);\n }\n //greater equal\n else if (hasGE) {\n occurence = numCellData >= removeNbFormat(\n sA.replace(re_ge, ''), nbFormat);\n }\n //lower\n else if (hasLO) {\n occurence = numCellData < removeNbFormat(\n sA.replace(re_l, ''), nbFormat);\n }\n //greater\n else if (hasGR) {\n occurence = numCellData > removeNbFormat(\n sA.replace(re_g, ''), nbFormat);\n }\n //different\n else if (hasDF) {\n occurence = contains(sA.replace(re_d, ''), cellData,\n false, this.caseSensitive) ? false : true;\n }\n //like\n else if (hasLK) {\n occurence = contains(sA.replace(re_lk, ''), cellData,\n false, this.caseSensitive);\n }\n //equal\n else if (hasEQ) {\n occurence = contains(sA.replace(re_eq, ''), cellData,\n true, this.caseSensitive);\n }\n //starts with\n else if (hasST) {\n occurence = cellData.indexOf(sA.replace(re_st, '')) === 0 ?\n true : false;\n }\n //ends with\n else if (hasEN) {\n let searchArg = sA.replace(re_en, '');\n occurence =\n cellData.lastIndexOf(searchArg, cellData.length - 1) ===\n (cellData.length - 1) - (searchArg.length - 1) &&\n cellData.lastIndexOf(searchArg, cellData.length - 1)\n > -1 ? true : false;\n }\n //empty\n else if (hasEM) {\n occurence = isEmptyString(cellData);\n }\n //non-empty\n else if (hasNM) {\n occurence = !isEmptyString(cellData);\n }\n //regexp\n else if (hasRE) {\n //in case regexp fires an exception\n try {\n //operator is removed\n let srchArg = sA.replace(re_re, '');\n let rgx = new RegExp(srchArg);\n occurence = rgx.test(cellData);\n } catch (ex) {\n occurence = false;\n }\n } else {\n // If numeric type data, perform a strict equality test and\n // fallback to unformatted number string comparison\n if (numCellData && this.hasColNbFormat &&\n this.colNbFormat[j] && !this.singleSearchFlt) {\n // removeNbFormat can return 0 for strings which are not\n // formatted numbers, in that case return the original\n // string. TODO: handle this in removeNbFormat\n sA = removeNbFormat(sA, nbFormat) || sA;\n occurence = numCellData === sA ||\n contains(sA.toString(), numCellData.toString(),\n this.isExactMatch(j), this.caseSensitive);\n } else {\n // Finally test search term is contained in cell data\n occurence = contains(sA, cellData, this.isExactMatch(j),\n this.caseSensitive);\n }\n }\n\n }//else\n return occurence;\n }//fn\n\n for (let k = this.refRow; k < nbRows; k++) {\n // already filtered rows display re-init\n row[k].style.display = '';\n\n let cells = row[k].cells;\n let nchilds = cells.length;\n\n // checks if row has exact cell #\n if (nchilds !== this.nbCells) {\n continue;\n }\n\n let occurence = [],\n isRowValid = true,\n //only for single filter search\n singleFltRowValid = false;\n\n // this loop retrieves cell data\n for (let j = 0; j < nchilds; j++) {\n //searched keyword\n let sA = searchArgs[this.singleSearchFlt ? 0 : j];\n\n if (sA === '') {\n continue;\n }\n\n let cellData = matchCase(this.getCellData(cells[j]),\n this.caseSensitive);\n\n //multiple search parameter operator ||\n let sAOrSplit = sA.toString().split(this.orOperator),\n //multiple search || parameter boolean\n hasMultiOrSA = sAOrSplit.length > 1,\n //multiple search parameter operator &&\n sAAndSplit = sA.toString().split(this.anOperator),\n //multiple search && parameter boolean\n hasMultiAndSA = sAAndSplit.length > 1;\n\n //detect operators or array query\n if (isArray(sA) || hasMultiOrSA || hasMultiAndSA) {\n let cS,\n s,\n occur = false;\n if (isArray(sA)) {\n s = sA;\n } else {\n s = hasMultiOrSA ? sAOrSplit : sAAndSplit;\n }\n // TODO: improve clarity/readability of this block\n for (let w = 0, len = s.length; w < len; w++) {\n cS = trim(s[w]);\n occur = hasArg.call(this, cS, cellData, j);\n highlight.call(this, cS, occur, cells[j]);\n if ((hasMultiOrSA && occur) ||\n (hasMultiAndSA && !occur)) {\n break;\n }\n if (isArray(sA) && occur) {\n break;\n }\n }\n occurence[j] = occur;\n\n }\n //single search parameter\n else {\n occurence[j] = hasArg.call(this, trim(sA), cellData, j);\n highlight.call(this, sA, occurence[j], cells[j]);\n }//else single param\n\n if (!occurence[j]) {\n isRowValid = false;\n }\n if (this.singleSearchFlt && occurence[j]) {\n singleFltRowValid = true;\n }\n\n this.emitter.emit('cell-processed', this, j, cells[j]);\n }//for j\n\n if (this.singleSearchFlt && singleFltRowValid) {\n isRowValid = true;\n }\n\n if (!isRowValid) {\n this.validateRow(k, false);\n hiddenRows++;\n } else {\n this.validateRow(k, true);\n }\n\n this.emitter.emit('row-processed', this, k,\n this.validRowsIndex.length, isRowValid);\n }// for k\n\n this.nbHiddenRows = hiddenRows;\n\n //invokes onafterfilter callback\n if (this.onAfterFilter) {\n this.onAfterFilter.call(null, this);\n }\n\n this.emitter.emit('after-filtering', this, searchArgs);\n }\n\n /**\n * Return the data of a specified column\n * @param {Number} colIndex Column index\n * @param {Boolean} includeHeaders Optional: include headers row\n * @param {Boolean} num Optional: return unformatted number\n * @param {Array} exclude Optional: list of row indexes to be excluded\n * @return {Array} Flat list of data for a column\n */\n getColValues(colIndex, includeHeaders = false, num = false, exclude = []) {\n if (!this.fltGrid) {\n return;\n }\n let row = this.tbl.rows;\n let nbRows = this.getRowsNb(true);\n let colValues = [];\n\n if (includeHeaders) {\n colValues.push(this.getHeadersText()[colIndex]);\n }\n\n for (let i = this.refRow; i < nbRows; i++) {\n let isExludedRow = false;\n // checks if current row index appears in exclude array\n if (exclude.length > 0) {\n isExludedRow = exclude.indexOf(i) !== -1;\n }\n let cell = row[i].cells,\n nchilds = cell.length;\n\n // checks if row has exact cell # and is not excluded\n if (nchilds === this.nbCells && !isExludedRow) {\n // this loop retrieves cell data\n for (let j = 0; j < nchilds; j++) {\n if (j !== colIndex || row[i].style.display !== '') {\n continue;\n }\n let cellData = this.getCellData(cell[j]),\n nbFormat = this.colNbFormat ?\n this.colNbFormat[colIndex] : undefined,\n data = num ? removeNbFormat(cellData, nbFormat) :\n cellData;\n colValues.push(data);\n }\n }\n }\n return colValues;\n }\n\n /**\n * Return the filter's value of a specified column\n * @param {Number} index Column index\n * @return {String} Filter value\n */\n getFilterValue(index) {\n if (!this.fltGrid) {\n return;\n }\n let fltValue = '';\n let flt = this.getFilterElement(index);\n if (!flt) {\n return fltValue;\n }\n\n let fltColType = this.getFilterType(index);\n if (fltColType !== MULTIPLE && fltColType !== CHECKLIST) {\n fltValue = flt.value;\n }\n //mutiple select\n else if (fltColType === MULTIPLE) {\n fltValue = this.feature('dropdown').getValues(index);\n }\n //checklist\n else if (fltColType === CHECKLIST) {\n fltValue = this.feature('checkList').getValues(index);\n }\n //return an empty string if collection is empty or contains a single\n //empty string\n if (isArray(fltValue) && fltValue.length === 0 ||\n (fltValue.length === 1 && fltValue[0] === '')) {\n fltValue = '';\n }\n\n return fltValue;\n }\n\n /**\n * Return the filters' values\n * @return {Array} List of filters' values\n */\n getFiltersValue() {\n if (!this.fltGrid) {\n return;\n }\n let searchArgs = [];\n for (let i = 0, len = this.fltIds.length; i < len; i++) {\n let fltValue = this.getFilterValue(i);\n if (isArray(fltValue)) {\n searchArgs.push(fltValue);\n } else {\n searchArgs.push(trim(fltValue));\n }\n }\n return searchArgs;\n }\n\n /**\n * Return the ID of a specified column's filter\n * @param {Number} index Column's index\n * @return {String} ID of the filter element\n */\n getFilterId(index) {\n if (!this.fltGrid) {\n return;\n }\n return this.fltIds[index];\n }\n\n /**\n * Return the list of ids of filters matching a specified type.\n * Note: hidden filters are also returned\n *\n * @param {String} type Filter type string ('input', 'select', 'multiple',\n * 'checklist')\n * @param {Boolean} bool If true returns columns indexes instead of IDs\n * @return {[type]} List of element IDs or column indexes\n */\n getFiltersByType(type, bool) {\n if (!this.fltGrid) {\n return;\n }\n let arr = [];\n for (let i = 0, len = this.fltIds.length; i < len; i++) {\n let fltType = this.getFilterType(i);\n if (fltType === type.toLowerCase()) {\n let a = bool ? i : this.fltIds[i];\n arr.push(a);\n }\n }\n return arr;\n }\n\n /**\n * Return the filter's DOM element for a given column\n * @param {Number} index Column's index\n * @return {DOMElement}\n */\n getFilterElement(index) {\n let fltId = this.fltIds[index];\n return elm(fltId);\n }\n\n /**\n * Return the number of cells for a given row index\n * @param {Number} rowIndex Index of the row\n * @return {Number} Number of cells\n */\n getCellsNb(rowIndex = 0) {\n let tr = this.tbl.rows[rowIndex];\n return tr.cells.length;\n }\n\n /**\n * Return the number of filterable rows starting from reference row if\n * defined\n * @param {Boolean} includeHeaders Include the headers row\n * @return {Number} Number of filterable rows\n */\n getRowsNb(includeHeaders) {\n let s = isUndef(this.refRow) ? 0 : this.refRow;\n let ntrs = this.tbl.rows.length;\n if (includeHeaders) {\n s = 0;\n }\n return parseInt(ntrs - s, 10);\n }\n\n /**\n * Return the data of a given cell\n * @param {DOMElement} cell Cell's DOM object\n * @return {String}\n */\n getCellData(cell) {\n let idx = cell.cellIndex;\n //Check for customCellData callback\n if (this.customCellData &&\n this.customCellDataCols.indexOf(idx) !== -1) {\n return this.customCellData.call(null, this, cell, idx);\n } else {\n return getText(cell);\n }\n }\n\n /**\n * Return the table data with following format:\n * [\n * [rowIndex, [value0, value1...]],\n * [rowIndex, [value0, value1...]]\n * ]\n * @param {Boolean} includeHeaders Optional: include headers row\n * @param {Boolean} excludeHiddenCols Optional: exclude hidden columns\n * @return {Array}\n *\n * TODO: provide an API returning data in JSON format\n */\n getTableData(includeHeaders = false, excludeHiddenCols = false) {\n let rows = this.tbl.rows;\n let nbRows = this.getRowsNb(true);\n let tblData = [];\n if (includeHeaders) {\n let headers = this.getHeadersText(excludeHiddenCols);\n tblData.push([this.getHeadersRowIndex(), headers]);\n }\n for (let k = this.refRow; k < nbRows; k++) {\n let rowData = [k, []];\n let cells = rows[k].cells;\n for (let j = 0, len = cells.length; j < len; j++) {\n if (excludeHiddenCols && this.hasExtension('colsVisibility')) {\n if (this.extension('colsVisibility').isColHidden(j)) {\n continue;\n }\n }\n let cellData = this.getCellData(cells[j]);\n rowData[1].push(cellData);\n }\n tblData.push(rowData);\n }\n return tblData;\n }\n\n /**\n * Return the filtered data with following format:\n * [\n * [rowIndex, [value0, value1...]],\n * [rowIndex, [value0, value1...]]\n * ]\n * @param {Boolean} includeHeaders Optional: include headers row\n * @param {Boolean} excludeHiddenCols Optional: exclude hidden columns\n * @return {Array}\n *\n * TODO: provide an API returning data in JSON format\n */\n getFilteredData(includeHeaders = false, excludeHiddenCols = false) {\n if (!this.validRowsIndex) {\n return [];\n }\n let rows = this.tbl.rows,\n filteredData = [];\n if (includeHeaders) {\n let headers = this.getHeadersText(excludeHiddenCols);\n filteredData.push([this.getHeadersRowIndex(), headers]);\n }\n\n let validRows = this.getValidRows(true);\n for (let i = 0; i < validRows.length; i++) {\n let rData = [this.validRowsIndex[i], []],\n cells = rows[this.validRowsIndex[i]].cells;\n for (let k = 0; k < cells.length; k++) {\n if (excludeHiddenCols && this.hasExtension('colsVisibility')) {\n if (this.extension('colsVisibility').isColHidden(k)) {\n continue;\n }\n }\n let cellData = this.getCellData(cells[k]);\n rData[1].push(cellData);\n }\n filteredData.push(rData);\n }\n return filteredData;\n }\n\n /**\n * Return the filtered data for a given column index\n * @param {Number} colIndex Colmun's index\n * @param {Boolean} includeHeaders Optional: include headers row\n * @return {Array} Flat list of values ['val0','val1','val2'...]\n *\n * TODO: provide an API returning data in JSON format\n */\n getFilteredDataCol(colIndex, includeHeaders = false) {\n if (isUndef(colIndex)) {\n return [];\n }\n let data = this.getFilteredData(),\n colData = [];\n if (includeHeaders) {\n colData.push(this.getHeadersText()[colIndex]);\n }\n for (let i = 0, len = data.length; i < len; i++) {\n let r = data[i],\n //cols values of current row\n d = r[1],\n //data of searched column\n c = d[colIndex];\n colData.push(c);\n }\n return colData;\n }\n\n /**\n * Get the display value of a row\n * @param {HTMLTableRowElement} row DOM element of the row\n * @return {String} Usually 'none' or ''\n */\n getRowDisplay(row) {\n return row.style.display;\n }\n\n /**\n * Validate/invalidate row by setting the 'validRow' attribute on the row\n * @param {Number} rowIndex Index of the row\n * @param {Boolean} isValid\n */\n validateRow(rowIndex, isValid) {\n let row = this.tbl.rows[rowIndex];\n if (!row || typeof isValid !== 'boolean') {\n return;\n }\n\n // always visible rows are valid\n if (this.hasVisibleRows && this.visibleRows.indexOf(rowIndex) !== -1) {\n isValid = true;\n }\n\n let displayFlag = isValid ? '' : NONE,\n validFlag = isValid ? 'true' : 'false';\n row.style.display = displayFlag;\n\n if (this.paging) {\n row.setAttribute('validRow', validFlag);\n }\n\n if (isValid) {\n if (this.validRowsIndex.indexOf(rowIndex) === -1) {\n this.validRowsIndex.push(rowIndex);\n }\n\n if (this.onRowValidated) {\n this.onRowValidated.call(null, this, rowIndex);\n }\n\n this.emitter.emit('row-validated', this, rowIndex);\n }\n }\n\n /**\n * Validate all filterable rows\n */\n validateAllRows() {\n if (!this.initialized) {\n return;\n }\n this.validRowsIndex = [];\n for (let k = this.refRow; k < this.nbFilterableRows; k++) {\n this.validateRow(k, true);\n }\n }\n\n /**\n * Set search value to a given filter\n * @param {Number} index Column's index\n * @param {String or Array} query searcharg Search term\n */\n setFilterValue(index, query = '') {\n if (!this.fltGrid) {\n return;\n }\n let slc = this.getFilterElement(index),\n fltColType = this.getFilterType(index);\n\n if (fltColType !== MULTIPLE && fltColType !== CHECKLIST) {\n if (this.loadFltOnDemand && !this.initialized) {\n this.emitter.emit('build-select-filter', this, index,\n this.linkedFilters, this.isExternalFlt);\n }\n slc.value = query;\n }\n //multiple selects\n else if (fltColType === MULTIPLE) {\n let values = isArray(query) ? query :\n query.split(' ' + this.orOperator + ' ');\n\n if (this.loadFltOnDemand && !this.initialized) {\n this.emitter.emit('build-select-filter', this, index,\n this.linkedFilters, this.isExternalFlt);\n }\n\n this.emitter.emit('select-options', this, index, values);\n }\n //checklist\n else if (fltColType === CHECKLIST) {\n let values = [];\n if (this.loadFltOnDemand && !this.initialized) {\n this.emitter.emit('build-checklist-filter', this, index,\n this.isExternalFlt);\n }\n if (isArray(query)) {\n values = query;\n } else {\n query = matchCase(query, this.caseSensitive);\n values = query.split(' ' + this.orOperator + ' ');\n }\n\n this.emitter.emit('select-checklist-options', this, index, values);\n }\n }\n\n /**\n * Set them columns' widths as per configuration\n * @param {Element} tbl DOM element\n */\n setColWidths(tbl) {\n if (!this.hasColWidths) {\n return;\n }\n tbl = tbl || this.tbl;\n\n let nbCols = this.nbCells;\n let colWidths = this.colWidths;\n let colTags = tag(tbl, 'col');\n let tblHasColTag = colTags.length > 0;\n let frag = !tblHasColTag ? doc.createDocumentFragment() : null;\n for (let k = 0; k < nbCols; k++) {\n let col;\n if (tblHasColTag) {\n col = colTags[k];\n } else {\n col = createElm('col', ['id', this.id + '_col_' + k]);\n frag.appendChild(col);\n }\n col.style.width = colWidths[k];\n }\n if (!tblHasColTag) {\n tbl.insertBefore(frag, tbl.firstChild);\n }\n }\n\n /**\n * Makes defined rows always visible\n */\n enforceVisibility() {\n if (!this.hasVisibleRows) {\n return;\n }\n let nbRows = this.getRowsNb(true);\n for (let i = 0, len = this.visibleRows.length; i < len; i++) {\n let row = this.visibleRows[i];\n //row index cannot be > nrows\n if (row <= nbRows) {\n this.validateRow(row, true);\n }\n }\n }\n\n /**\n * Clear all the filters' values\n */\n clearFilters() {\n if (!this.fltGrid) {\n return;\n }\n\n this.emitter.emit('before-clearing-filters', this);\n\n if (this.onBeforeReset) {\n this.onBeforeReset.call(null, this, this.getFiltersValue());\n }\n for (let i = 0, len = this.fltIds.length; i < len; i++) {\n this.setFilterValue(i, '');\n }\n\n this.filter();\n\n if (this.onAfterReset) {\n this.onAfterReset.call(null, this);\n }\n this.emitter.emit('after-clearing-filters', this);\n }\n\n /**\n * Clears filtered columns visual indicator (background color)\n */\n clearActiveColumns() {\n for (let i = 0, len = this.getCellsNb(this.headersRow); i < len; i++) {\n removeClass(this.getHeaderElement(i), this.activeColumnsCssClass);\n }\n }\n\n /**\n * Mark currently filtered column\n * @param {Number} colIndex Column index\n */\n markActiveColumn(colIndex) {\n let header = this.getHeaderElement(colIndex);\n if (hasClass(header, this.activeColumnsCssClass)) {\n return;\n }\n if (this.onBeforeActiveColumn) {\n this.onBeforeActiveColumn.call(null, this, colIndex);\n }\n addClass(header, this.activeColumnsCssClass);\n if (this.onAfterActiveColumn) {\n this.onAfterActiveColumn.call(null, this, colIndex);\n }\n }\n\n /**\n * Return the ID of the current active filter\n * @returns {String}\n */\n getActiveFilterId() {\n return this.activeFilterId;\n }\n\n /**\n * Set the ID of the current active filter\n * @param {String} filterId Element ID\n */\n setActiveFilterId(filterId) {\n this.activeFilterId = filterId;\n }\n\n /**\n * Return the column index for a given filter ID\n * @param {string} [filterId=''] Filter ID\n * @returns {Number} Column index\n */\n getColumnIndexFromFilterId(filterId = '') {\n let idx = filterId.split('_')[0];\n idx = idx.split(this.prfxFlt)[1];\n return parseInt(idx, 10);\n }\n\n /**\n * Make specified column's filter active\n * @param colIndex Index of a column\n */\n activateFilter(colIndex) {\n if (isUndef(colIndex)) {\n return;\n }\n this.setActiveFilterId(this.getFilterId(colIndex));\n }\n\n /**\n * Refresh the filters subject to linking ('select', 'multiple',\n * 'checklist' type)\n */\n linkFilters() {\n if (!this.linkedFilters || !this.activeFilterId) {\n return;\n }\n let slcA1 = this.getFiltersByType(SELECT, true),\n slcA2 = this.getFiltersByType(MULTIPLE, true),\n slcA3 = this.getFiltersByType(CHECKLIST, true),\n slcIndex = slcA1.concat(slcA2);\n slcIndex = slcIndex.concat(slcA3);\n\n let activeIdx = this.getColumnIndexFromFilterId(this.activeFilterId);\n\n for (let i = 0, len = slcIndex.length; i < len; i++) {\n let curSlc = elm(this.fltIds[slcIndex[i]]);\n let slcSelectedValue = this.getFilterValue(slcIndex[i]);\n\n // Welcome to cyclomatic complexity hell :)\n // TODO: simplify/refactor if statement\n if (activeIdx !== slcIndex[i] ||\n (this.paging && slcA1.indexOf(slcIndex[i]) !== -1 &&\n activeIdx === slcIndex[i]) ||\n (!this.paging && (slcA3.indexOf(slcIndex[i]) !== -1 ||\n slcA2.indexOf(slcIndex[i]) !== -1)) ||\n slcSelectedValue === this.displayAllText) {\n\n //1st option needs to be inserted\n if (this.loadFltOnDemand) {\n let opt0 = createOpt(this.displayAllText, '');\n curSlc.innerHTML = '';\n curSlc.appendChild(opt0);\n }\n\n if (slcA3.indexOf(slcIndex[i]) !== -1) {\n this.emitter.emit('build-checklist-filter', this,\n slcIndex[i]);\n } else {\n this.emitter.emit('build-select-filter', this, slcIndex[i],\n true);\n }\n\n this.setFilterValue(slcIndex[i], slcSelectedValue);\n }\n }\n }\n\n /**\n * Determines if passed filter column implements exact query match\n * @param {Number} colIndex [description]\n * @return {Boolean} [description]\n */\n isExactMatch(colIndex) {\n let fltType = this.getFilterType(colIndex);\n return this.exactMatchByCol[colIndex] || this.exactMatch ||\n fltType !== INPUT;\n }\n\n /**\n * Check if passed script or stylesheet is already imported\n * @param {String} filePath Ressource path\n * @param {String} type Possible values: 'script' or 'link'\n * @return {Boolean}\n */\n isImported(filePath, type = 'script') {\n let imported = false,\n attr = type === 'script' ? 'src' : 'href',\n files = tag(doc, type);\n for (let i = 0, len = files.length; i < len; i++) {\n if (isUndef(files[i][attr])) {\n continue;\n }\n if (files[i][attr].match(filePath)) {\n imported = true;\n break;\n }\n }\n return imported;\n }\n\n /**\n * Import script or stylesheet\n * @param {String} fileId Ressource ID\n * @param {String} filePath Ressource path\n * @param {Function} callback Callback\n * @param {String} type Possible values: 'script' or 'link'\n */\n import(fileId, filePath, callback, type = 'script') {\n if (this.isImported(filePath, type)) {\n return;\n }\n let o = this,\n isLoaded = false,\n file,\n head = tag(doc, 'head')[0];\n\n if (type.toLowerCase() === 'link') {\n file = createElm('link',\n ['id', fileId], ['type', 'text/css'],\n ['rel', 'stylesheet'], ['href', filePath]\n );\n } else {\n file = createElm('script',\n ['id', fileId],\n ['type', 'text/javascript'], ['src', filePath]\n );\n }\n\n //Browser <> IE onload event works only for scripts, not for stylesheets\n file.onload = file.onreadystatechange = () => {\n if (!isLoaded &&\n (!this.readyState || this.readyState === 'loaded' ||\n this.readyState === 'complete')) {\n isLoaded = true;\n if (typeof callback === 'function') {\n callback.call(null, o);\n }\n }\n };\n file.onerror = function () {\n throw new Error(`TableFilter could not load: ${filePath}`);\n };\n head.appendChild(file);\n }\n\n /**\n * Check if table has filters grid\n * @return {Boolean}\n */\n isInitialized() {\n return this.initialized;\n }\n\n /**\n * Get list of filter IDs\n * @return {[type]} [description]\n */\n getFiltersId() {\n return this.fltIds || [];\n }\n\n /**\n * Get filtered (valid) rows indexes\n * @param {Boolean} reCalc Force calculation of filtered rows list\n * @return {Array} List of row indexes\n */\n getValidRows(reCalc) {\n if (!reCalc) {\n return this.validRowsIndex;\n }\n\n let nbRows = this.getRowsNb(true);\n this.validRowsIndex = [];\n for (let k = this.refRow; k < nbRows; k++) {\n let r = this.tbl.rows[k];\n if (!this.paging) {\n if (this.getRowDisplay(r) !== NONE) {\n this.validRowsIndex.push(r.rowIndex);\n }\n } else {\n if (r.getAttribute('validRow') === 'true' ||\n r.getAttribute('validRow') === null) {\n this.validRowsIndex.push(r.rowIndex);\n }\n }\n }\n return this.validRowsIndex;\n }\n\n /**\n * Get the index of the row containing the filters\n * @return {Number}\n */\n getFiltersRowIndex() {\n return this.filtersRowIndex;\n }\n\n /**\n * Get the index of the headers row\n * @return {Number}\n */\n getHeadersRowIndex() {\n return this.headersRow;\n }\n\n /**\n * Get the row index from where the filtering process start (1st filterable\n * row)\n * @return {Number}\n */\n getStartRowIndex() {\n return this.refRow;\n }\n\n /**\n * Get the index of the last row\n * @return {Number}\n */\n getLastRowIndex() {\n let nbRows = this.getRowsNb(true);\n return (nbRows - 1);\n }\n\n /**\n * Get the header DOM element for a given column index\n * @param {Number} colIndex Column index\n * @return {Element}\n */\n getHeaderElement(colIndex) {\n let table = this.gridLayout ? this.Mod.gridLayout.headTbl : this.tbl;\n let tHead = tag(table, 'thead');\n let headersRow = this.headersRow;\n let header;\n for (let i = 0; i < this.nbCells; i++) {\n if (i !== colIndex) {\n continue;\n }\n if (tHead.length === 0) {\n header = table.rows[headersRow].cells[i];\n }\n if (tHead.length === 1) {\n header = tHead[0].rows[headersRow].cells[i];\n }\n break;\n }\n return header;\n }\n\n /**\n * Return the list of headers' text\n * @param {Boolean} excludeHiddenCols Optional: exclude hidden columns\n * @return {Array} list of headers' text\n */\n getHeadersText(excludeHiddenCols = false) {\n let headers = [];\n for (let j = 0; j < this.nbCells; j++) {\n if (excludeHiddenCols && this.hasExtension('colsVisibility')) {\n if (this.extension('colsVisibility').isColHidden(j)) {\n continue;\n }\n }\n let header = this.getHeaderElement(j);\n let headerText = getFirstTextNode(header);\n headers.push(headerText);\n }\n return headers;\n }\n\n /**\n * Return the filter type for a specified column\n * @param {Number} colIndex Column's index\n * @return {String}\n */\n getFilterType(colIndex) {\n let colType = this.cfg['col_' + colIndex];\n return !colType ? INPUT : colType.toLowerCase();\n }\n\n /**\n * Get the total number of filterable rows\n * @return {Number}\n */\n getFilterableRowsNb() {\n return this.getRowsNb(false);\n }\n\n /**\n * Return the total number of valid rows\n * @param {Boolean} [reCalc=false] Forces calculation of filtered rows\n * @returns {Number}\n */\n getValidRowsNb(reCalc = false) {\n return this.getValidRows(reCalc).length;\n }\n\n /**\n * Get the configuration object (literal object)\n * @return {Object}\n */\n config() {\n return this.cfg;\n }\n}\n"
},
{
- "__docId__": 760,
+ "__docId__": 761,
"kind": "variable",
"static": true,
"variation": null,
@@ -15979,7 +16017,7 @@
}
},
{
- "__docId__": 761,
+ "__docId__": 762,
"kind": "class",
"static": true,
"variation": null,
@@ -16005,7 +16043,7 @@
"interface": false
},
{
- "__docId__": 762,
+ "__docId__": 763,
"kind": "constructor",
"static": false,
"variation": null,
@@ -16060,7 +16098,7 @@
"generator": false
},
{
- "__docId__": 763,
+ "__docId__": 764,
"kind": "member",
"static": false,
"variation": null,
@@ -16080,7 +16118,7 @@
}
},
{
- "__docId__": 764,
+ "__docId__": 765,
"kind": "member",
"static": false,
"variation": null,
@@ -16100,7 +16138,7 @@
}
},
{
- "__docId__": 765,
+ "__docId__": 766,
"kind": "member",
"static": false,
"variation": null,
@@ -16120,7 +16158,7 @@
}
},
{
- "__docId__": 766,
+ "__docId__": 767,
"kind": "member",
"static": false,
"variation": null,
@@ -16140,7 +16178,7 @@
}
},
{
- "__docId__": 767,
+ "__docId__": 768,
"kind": "member",
"static": false,
"variation": null,
@@ -16160,7 +16198,7 @@
}
},
{
- "__docId__": 768,
+ "__docId__": 769,
"kind": "member",
"static": false,
"variation": null,
@@ -16180,7 +16218,7 @@
}
},
{
- "__docId__": 769,
+ "__docId__": 770,
"kind": "member",
"static": false,
"variation": null,
@@ -16200,7 +16238,7 @@
}
},
{
- "__docId__": 770,
+ "__docId__": 771,
"kind": "member",
"static": false,
"variation": null,
@@ -16220,7 +16258,7 @@
}
},
{
- "__docId__": 771,
+ "__docId__": 772,
"kind": "member",
"static": false,
"variation": null,
@@ -16240,7 +16278,7 @@
}
},
{
- "__docId__": 772,
+ "__docId__": 773,
"kind": "member",
"static": false,
"variation": null,
@@ -16258,7 +16296,7 @@
}
},
{
- "__docId__": 773,
+ "__docId__": 774,
"kind": "member",
"static": false,
"variation": null,
@@ -16276,7 +16314,7 @@
}
},
{
- "__docId__": 774,
+ "__docId__": 775,
"kind": "member",
"static": false,
"variation": null,
@@ -16294,7 +16332,7 @@
}
},
{
- "__docId__": 775,
+ "__docId__": 776,
"kind": "member",
"static": false,
"variation": null,
@@ -16312,7 +16350,7 @@
}
},
{
- "__docId__": 776,
+ "__docId__": 777,
"kind": "member",
"static": false,
"variation": null,
@@ -16330,7 +16368,7 @@
}
},
{
- "__docId__": 777,
+ "__docId__": 778,
"kind": "member",
"static": false,
"variation": null,
@@ -16350,7 +16388,7 @@
}
},
{
- "__docId__": 778,
+ "__docId__": 779,
"kind": "member",
"static": false,
"variation": null,
@@ -16368,7 +16406,7 @@
}
},
{
- "__docId__": 779,
+ "__docId__": 780,
"kind": "member",
"static": false,
"variation": null,
@@ -16386,7 +16424,7 @@
}
},
{
- "__docId__": 780,
+ "__docId__": 781,
"kind": "member",
"static": false,
"variation": null,
@@ -16404,7 +16442,7 @@
}
},
{
- "__docId__": 781,
+ "__docId__": 782,
"kind": "member",
"static": false,
"variation": null,
@@ -16424,7 +16462,7 @@
}
},
{
- "__docId__": 782,
+ "__docId__": 783,
"kind": "member",
"static": false,
"variation": null,
@@ -16444,7 +16482,7 @@
}
},
{
- "__docId__": 783,
+ "__docId__": 784,
"kind": "member",
"static": false,
"variation": null,
@@ -16464,7 +16502,7 @@
}
},
{
- "__docId__": 784,
+ "__docId__": 785,
"kind": "member",
"static": false,
"variation": null,
@@ -16484,7 +16522,7 @@
}
},
{
- "__docId__": 785,
+ "__docId__": 786,
"kind": "member",
"static": false,
"variation": null,
@@ -16504,7 +16542,7 @@
}
},
{
- "__docId__": 786,
+ "__docId__": 787,
"kind": "member",
"static": false,
"variation": null,
@@ -16524,7 +16562,7 @@
}
},
{
- "__docId__": 787,
+ "__docId__": 788,
"kind": "member",
"static": false,
"variation": null,
@@ -16544,7 +16582,7 @@
}
},
{
- "__docId__": 788,
+ "__docId__": 789,
"kind": "member",
"static": false,
"variation": null,
@@ -16564,7 +16602,7 @@
}
},
{
- "__docId__": 789,
+ "__docId__": 790,
"kind": "member",
"static": false,
"variation": null,
@@ -16584,7 +16622,7 @@
}
},
{
- "__docId__": 790,
+ "__docId__": 791,
"kind": "member",
"static": false,
"variation": null,
@@ -16604,7 +16642,7 @@
}
},
{
- "__docId__": 791,
+ "__docId__": 792,
"kind": "member",
"static": false,
"variation": null,
@@ -16624,7 +16662,7 @@
}
},
{
- "__docId__": 792,
+ "__docId__": 793,
"kind": "member",
"static": false,
"variation": null,
@@ -16644,7 +16682,7 @@
}
},
{
- "__docId__": 793,
+ "__docId__": 794,
"kind": "member",
"static": false,
"variation": null,
@@ -16664,7 +16702,7 @@
}
},
{
- "__docId__": 794,
+ "__docId__": 795,
"kind": "member",
"static": false,
"variation": null,
@@ -16684,7 +16722,7 @@
}
},
{
- "__docId__": 795,
+ "__docId__": 796,
"kind": "member",
"static": false,
"variation": null,
@@ -16704,7 +16742,7 @@
}
},
{
- "__docId__": 796,
+ "__docId__": 797,
"kind": "member",
"static": false,
"variation": null,
@@ -16724,7 +16762,7 @@
}
},
{
- "__docId__": 797,
+ "__docId__": 798,
"kind": "member",
"static": false,
"variation": null,
@@ -16744,7 +16782,7 @@
}
},
{
- "__docId__": 798,
+ "__docId__": 799,
"kind": "member",
"static": false,
"variation": null,
@@ -16764,7 +16802,7 @@
}
},
{
- "__docId__": 799,
+ "__docId__": 800,
"kind": "member",
"static": false,
"variation": null,
@@ -16784,7 +16822,7 @@
}
},
{
- "__docId__": 800,
+ "__docId__": 801,
"kind": "member",
"static": false,
"variation": null,
@@ -16804,7 +16842,7 @@
}
},
{
- "__docId__": 801,
+ "__docId__": 802,
"kind": "member",
"static": false,
"variation": null,
@@ -16824,7 +16862,7 @@
}
},
{
- "__docId__": 802,
+ "__docId__": 803,
"kind": "member",
"static": false,
"variation": null,
@@ -16844,7 +16882,7 @@
}
},
{
- "__docId__": 803,
+ "__docId__": 804,
"kind": "member",
"static": false,
"variation": null,
@@ -16864,7 +16902,7 @@
}
},
{
- "__docId__": 804,
+ "__docId__": 805,
"kind": "member",
"static": false,
"variation": null,
@@ -16884,7 +16922,7 @@
}
},
{
- "__docId__": 805,
+ "__docId__": 806,
"kind": "member",
"static": false,
"variation": null,
@@ -16904,7 +16942,7 @@
}
},
{
- "__docId__": 806,
+ "__docId__": 807,
"kind": "member",
"static": false,
"variation": null,
@@ -16924,7 +16962,7 @@
}
},
{
- "__docId__": 807,
+ "__docId__": 808,
"kind": "member",
"static": false,
"variation": null,
@@ -16944,7 +16982,7 @@
}
},
{
- "__docId__": 808,
+ "__docId__": 809,
"kind": "member",
"static": false,
"variation": null,
@@ -16964,7 +17002,7 @@
}
},
{
- "__docId__": 809,
+ "__docId__": 810,
"kind": "member",
"static": false,
"variation": null,
@@ -16984,7 +17022,7 @@
}
},
{
- "__docId__": 810,
+ "__docId__": 811,
"kind": "member",
"static": false,
"variation": null,
@@ -17004,7 +17042,7 @@
}
},
{
- "__docId__": 811,
+ "__docId__": 812,
"kind": "member",
"static": false,
"variation": null,
@@ -17024,7 +17062,7 @@
}
},
{
- "__docId__": 812,
+ "__docId__": 813,
"kind": "member",
"static": false,
"variation": null,
@@ -17044,7 +17082,7 @@
}
},
{
- "__docId__": 813,
+ "__docId__": 814,
"kind": "member",
"static": false,
"variation": null,
@@ -17064,7 +17102,7 @@
}
},
{
- "__docId__": 814,
+ "__docId__": 815,
"kind": "member",
"static": false,
"variation": null,
@@ -17084,7 +17122,7 @@
}
},
{
- "__docId__": 815,
+ "__docId__": 816,
"kind": "member",
"static": false,
"variation": null,
@@ -17104,7 +17142,7 @@
}
},
{
- "__docId__": 816,
+ "__docId__": 817,
"kind": "member",
"static": false,
"variation": null,
@@ -17124,7 +17162,7 @@
}
},
{
- "__docId__": 817,
+ "__docId__": 818,
"kind": "member",
"static": false,
"variation": null,
@@ -17144,7 +17182,7 @@
}
},
{
- "__docId__": 818,
+ "__docId__": 819,
"kind": "member",
"static": false,
"variation": null,
@@ -17164,7 +17202,7 @@
}
},
{
- "__docId__": 819,
+ "__docId__": 820,
"kind": "member",
"static": false,
"variation": null,
@@ -17184,7 +17222,7 @@
}
},
{
- "__docId__": 820,
+ "__docId__": 821,
"kind": "member",
"static": false,
"variation": null,
@@ -17204,7 +17242,7 @@
}
},
{
- "__docId__": 821,
+ "__docId__": 822,
"kind": "member",
"static": false,
"variation": null,
@@ -17224,7 +17262,7 @@
}
},
{
- "__docId__": 822,
+ "__docId__": 823,
"kind": "member",
"static": false,
"variation": null,
@@ -17244,7 +17282,7 @@
}
},
{
- "__docId__": 823,
+ "__docId__": 824,
"kind": "member",
"static": false,
"variation": null,
@@ -17264,7 +17302,7 @@
}
},
{
- "__docId__": 824,
+ "__docId__": 825,
"kind": "member",
"static": false,
"variation": null,
@@ -17284,7 +17322,7 @@
}
},
{
- "__docId__": 825,
+ "__docId__": 826,
"kind": "member",
"static": false,
"variation": null,
@@ -17304,7 +17342,7 @@
}
},
{
- "__docId__": 826,
+ "__docId__": 827,
"kind": "member",
"static": false,
"variation": null,
@@ -17324,7 +17362,7 @@
}
},
{
- "__docId__": 827,
+ "__docId__": 828,
"kind": "member",
"static": false,
"variation": null,
@@ -17344,7 +17382,7 @@
}
},
{
- "__docId__": 828,
+ "__docId__": 829,
"kind": "member",
"static": false,
"variation": null,
@@ -17365,7 +17403,7 @@
}
},
{
- "__docId__": 829,
+ "__docId__": 830,
"kind": "member",
"static": false,
"variation": null,
@@ -17385,7 +17423,7 @@
}
},
{
- "__docId__": 830,
+ "__docId__": 831,
"kind": "member",
"static": false,
"variation": null,
@@ -17405,7 +17443,7 @@
}
},
{
- "__docId__": 831,
+ "__docId__": 832,
"kind": "member",
"static": false,
"variation": null,
@@ -17425,7 +17463,7 @@
}
},
{
- "__docId__": 832,
+ "__docId__": 833,
"kind": "member",
"static": false,
"variation": null,
@@ -17445,7 +17483,7 @@
}
},
{
- "__docId__": 833,
+ "__docId__": 834,
"kind": "member",
"static": false,
"variation": null,
@@ -17465,7 +17503,7 @@
}
},
{
- "__docId__": 834,
+ "__docId__": 835,
"kind": "member",
"static": false,
"variation": null,
@@ -17485,7 +17523,7 @@
}
},
{
- "__docId__": 835,
+ "__docId__": 836,
"kind": "member",
"static": false,
"variation": null,
@@ -17505,7 +17543,7 @@
}
},
{
- "__docId__": 836,
+ "__docId__": 837,
"kind": "member",
"static": false,
"variation": null,
@@ -17525,7 +17563,7 @@
}
},
{
- "__docId__": 837,
+ "__docId__": 838,
"kind": "member",
"static": false,
"variation": null,
@@ -17545,7 +17583,7 @@
}
},
{
- "__docId__": 838,
+ "__docId__": 839,
"kind": "member",
"static": false,
"variation": null,
@@ -17565,7 +17603,7 @@
}
},
{
- "__docId__": 839,
+ "__docId__": 840,
"kind": "member",
"static": false,
"variation": null,
@@ -17585,7 +17623,7 @@
}
},
{
- "__docId__": 840,
+ "__docId__": 841,
"kind": "member",
"static": false,
"variation": null,
@@ -17605,7 +17643,7 @@
}
},
{
- "__docId__": 841,
+ "__docId__": 842,
"kind": "member",
"static": false,
"variation": null,
@@ -17625,7 +17663,7 @@
}
},
{
- "__docId__": 842,
+ "__docId__": 843,
"kind": "member",
"static": false,
"variation": null,
@@ -17645,7 +17683,7 @@
}
},
{
- "__docId__": 843,
+ "__docId__": 844,
"kind": "member",
"static": false,
"variation": null,
@@ -17665,7 +17703,7 @@
}
},
{
- "__docId__": 844,
+ "__docId__": 845,
"kind": "member",
"static": false,
"variation": null,
@@ -17685,7 +17723,7 @@
}
},
{
- "__docId__": 845,
+ "__docId__": 846,
"kind": "member",
"static": false,
"variation": null,
@@ -17705,7 +17743,7 @@
}
},
{
- "__docId__": 846,
+ "__docId__": 847,
"kind": "member",
"static": false,
"variation": null,
@@ -17725,7 +17763,7 @@
}
},
{
- "__docId__": 847,
+ "__docId__": 848,
"kind": "member",
"static": false,
"variation": null,
@@ -17745,7 +17783,7 @@
}
},
{
- "__docId__": 848,
+ "__docId__": 849,
"kind": "member",
"static": false,
"variation": null,
@@ -17765,7 +17803,7 @@
}
},
{
- "__docId__": 849,
+ "__docId__": 850,
"kind": "member",
"static": false,
"variation": null,
@@ -17785,7 +17823,7 @@
}
},
{
- "__docId__": 850,
+ "__docId__": 851,
"kind": "member",
"static": false,
"variation": null,
@@ -17805,7 +17843,7 @@
}
},
{
- "__docId__": 851,
+ "__docId__": 852,
"kind": "member",
"static": false,
"variation": null,
@@ -17825,7 +17863,7 @@
}
},
{
- "__docId__": 852,
+ "__docId__": 853,
"kind": "member",
"static": false,
"variation": null,
@@ -17845,7 +17883,7 @@
}
},
{
- "__docId__": 853,
+ "__docId__": 854,
"kind": "member",
"static": false,
"variation": null,
@@ -17865,7 +17903,7 @@
}
},
{
- "__docId__": 854,
+ "__docId__": 855,
"kind": "member",
"static": false,
"variation": null,
@@ -17885,7 +17923,7 @@
}
},
{
- "__docId__": 855,
+ "__docId__": 856,
"kind": "member",
"static": false,
"variation": null,
@@ -17905,7 +17943,7 @@
}
},
{
- "__docId__": 856,
+ "__docId__": 857,
"kind": "member",
"static": false,
"variation": null,
@@ -17925,7 +17963,7 @@
}
},
{
- "__docId__": 857,
+ "__docId__": 858,
"kind": "member",
"static": false,
"variation": null,
@@ -17945,7 +17983,7 @@
}
},
{
- "__docId__": 858,
+ "__docId__": 859,
"kind": "member",
"static": false,
"variation": null,
@@ -17965,7 +18003,7 @@
}
},
{
- "__docId__": 859,
+ "__docId__": 860,
"kind": "member",
"static": false,
"variation": null,
@@ -17985,7 +18023,7 @@
}
},
{
- "__docId__": 860,
+ "__docId__": 861,
"kind": "member",
"static": false,
"variation": null,
@@ -18005,7 +18043,7 @@
}
},
{
- "__docId__": 861,
+ "__docId__": 862,
"kind": "member",
"static": false,
"variation": null,
@@ -18025,7 +18063,7 @@
}
},
{
- "__docId__": 862,
+ "__docId__": 863,
"kind": "member",
"static": false,
"variation": null,
@@ -18045,7 +18083,7 @@
}
},
{
- "__docId__": 863,
+ "__docId__": 864,
"kind": "member",
"static": false,
"variation": null,
@@ -18065,7 +18103,7 @@
}
},
{
- "__docId__": 864,
+ "__docId__": 865,
"kind": "member",
"static": false,
"variation": null,
@@ -18085,7 +18123,7 @@
}
},
{
- "__docId__": 865,
+ "__docId__": 866,
"kind": "member",
"static": false,
"variation": null,
@@ -18105,7 +18143,7 @@
}
},
{
- "__docId__": 866,
+ "__docId__": 867,
"kind": "member",
"static": false,
"variation": null,
@@ -18125,7 +18163,7 @@
}
},
{
- "__docId__": 867,
+ "__docId__": 868,
"kind": "member",
"static": false,
"variation": null,
@@ -18145,7 +18183,7 @@
}
},
{
- "__docId__": 868,
+ "__docId__": 869,
"kind": "member",
"static": false,
"variation": null,
@@ -18165,7 +18203,7 @@
}
},
{
- "__docId__": 869,
+ "__docId__": 870,
"kind": "member",
"static": false,
"variation": null,
@@ -18185,7 +18223,7 @@
}
},
{
- "__docId__": 870,
+ "__docId__": 871,
"kind": "member",
"static": false,
"variation": null,
@@ -18205,7 +18243,7 @@
}
},
{
- "__docId__": 871,
+ "__docId__": 872,
"kind": "member",
"static": false,
"variation": null,
@@ -18225,7 +18263,7 @@
}
},
{
- "__docId__": 872,
+ "__docId__": 873,
"kind": "member",
"static": false,
"variation": null,
@@ -18244,26 +18282,6 @@
"description": null
}
},
- {
- "__docId__": 873,
- "kind": "member",
- "static": false,
- "variation": null,
- "name": "btnResetCssClass",
- "memberof": "src/tablefilter.js~TableFilter",
- "longname": "src/tablefilter.js~TableFilter#btnResetCssClass",
- "access": null,
- "description": "Css class for reset button",
- "lineNumber": 771,
- "type": {
- "nullable": null,
- "types": [
- "String"
- ],
- "spread": false,
- "description": null
- }
- },
{
"__docId__": 874,
"kind": "member",
@@ -18274,7 +18292,7 @@
"longname": "src/tablefilter.js~TableFilter#onBeforeReset",
"access": null,
"description": "Callback fired before filters are cleared",
- "lineNumber": 777,
+ "lineNumber": 771,
"type": {
"nullable": null,
"types": [
@@ -18294,7 +18312,7 @@
"longname": "src/tablefilter.js~TableFilter#onAfterReset",
"access": null,
"description": "Callback fired after filters are cleared",
- "lineNumber": 784,
+ "lineNumber": 778,
"type": {
"nullable": null,
"types": [
@@ -18314,7 +18332,7 @@
"longname": "src/tablefilter.js~TableFilter#paging",
"access": null,
"description": "Enable paging component",
- "lineNumber": 790,
+ "lineNumber": 784,
"type": {
"nullable": null,
"types": [
@@ -18334,7 +18352,7 @@
"longname": "src/tablefilter.js~TableFilter#nbHiddenRows",
"access": "private",
"description": "Number of hidden rows",
- "lineNumber": 797,
+ "lineNumber": 791,
"type": {
"nullable": null,
"types": [
@@ -18354,7 +18372,7 @@
"longname": "src/tablefilter.js~TableFilter#autoFilter",
"access": null,
"description": "Enable auto-filter behaviour, table is filtered when a user\nstops typing",
- "lineNumber": 804,
+ "lineNumber": 798,
"type": {
"nullable": null,
"types": [
@@ -18374,7 +18392,7 @@
"longname": "src/tablefilter.js~TableFilter#autoFilterDelay",
"access": null,
"description": "Auto-filter delay in msecs",
- "lineNumber": 810,
+ "lineNumber": 804,
"type": {
"nullable": null,
"types": [
@@ -18394,7 +18412,7 @@
"longname": "src/tablefilter.js~TableFilter#isUserTyping",
"access": "private",
"description": "Indicate whether user is typing",
- "lineNumber": 818,
+ "lineNumber": 812,
"type": {
"nullable": null,
"types": [
@@ -18414,7 +18432,7 @@
"longname": "src/tablefilter.js~TableFilter#autoFilterTimer",
"access": "private",
"description": "Auto-filter interval ID",
- "lineNumber": 825,
+ "lineNumber": 819,
"type": {
"nullable": null,
"types": [
@@ -18434,7 +18452,7 @@
"longname": "src/tablefilter.js~TableFilter#highlightKeywords",
"access": null,
"description": "Enable keyword highlighting behaviour",
- "lineNumber": 831,
+ "lineNumber": 825,
"type": {
"nullable": null,
"types": [
@@ -18454,7 +18472,7 @@
"longname": "src/tablefilter.js~TableFilter#noResults",
"access": null,
"description": "Enable no results message UI component",
- "lineNumber": 837,
+ "lineNumber": 831,
"type": {
"nullable": null,
"types": [
@@ -18474,7 +18492,7 @@
"longname": "src/tablefilter.js~TableFilter#state",
"access": null,
"description": "Enable state persistence",
- "lineNumber": 844,
+ "lineNumber": 838,
"type": {
"nullable": null,
"types": [
@@ -18494,7 +18512,7 @@
"longname": "src/tablefilter.js~TableFilter#defaultDateType",
"access": null,
"description": "Define default date type (DMY)",
- "lineNumber": 851,
+ "lineNumber": 845,
"type": {
"nullable": null,
"types": [
@@ -18514,7 +18532,7 @@
"longname": "src/tablefilter.js~TableFilter#thousandsSeparator",
"access": null,
"description": "Define thousands separator ',' or '.', defaults to ','",
- "lineNumber": 857,
+ "lineNumber": 851,
"type": {
"nullable": null,
"types": [
@@ -18534,7 +18552,7 @@
"longname": "src/tablefilter.js~TableFilter#decimalSeparator",
"access": null,
"description": "Define decimal separator ',' or '.', defaults to '.'",
- "lineNumber": 863,
+ "lineNumber": 857,
"type": {
"nullable": null,
"types": [
@@ -18554,7 +18572,7 @@
"longname": "src/tablefilter.js~TableFilter#hasColNbFormat",
"access": "private",
"description": "Determine whether table has columns with numeric formats",
- "lineNumber": 870,
+ "lineNumber": 864,
"type": {
"nullable": null,
"types": [
@@ -18574,7 +18592,7 @@
"longname": "src/tablefilter.js~TableFilter#colNbFormat",
"access": null,
"description": "Define numeric format on a column basis, two possible values 'EU' and\n'US', ie:\ncol_number_format : [null, 'US', 'EU', null]",
- "lineNumber": 878,
+ "lineNumber": 872,
"type": {
"nullable": null,
"types": [
@@ -18594,7 +18612,7 @@
"longname": "src/tablefilter.js~TableFilter#hasColDateType",
"access": "private",
"description": "Determine whether table has columns with date types",
- "lineNumber": 885,
+ "lineNumber": 879,
"type": {
"nullable": null,
"types": [
@@ -18614,7 +18632,7 @@
"longname": "src/tablefilter.js~TableFilter#colDateType",
"access": null,
"description": "Define date format on a column basis, possible values 'DMY', 'MDY',\n'YMD', 'DDMMMYYYY', ie:\ncol_date_type : [null, 'DMY', 'MDY', 'YMD', null, 'DDMMMYYYY']",
- "lineNumber": 893,
+ "lineNumber": 887,
"type": {
"nullable": null,
"types": [
@@ -18634,7 +18652,7 @@
"longname": "src/tablefilter.js~TableFilter#prfxTf",
"access": "private",
"description": "Main prefix",
- "lineNumber": 900,
+ "lineNumber": 894,
"type": {
"types": [
"string"
@@ -18651,7 +18669,7 @@
"longname": "src/tablefilter.js~TableFilter#prfxFlt",
"access": "private",
"description": "Filter's ID prefix (inputs - selects)",
- "lineNumber": 906,
+ "lineNumber": 900,
"type": {
"types": [
"string"
@@ -18668,7 +18686,7 @@
"longname": "src/tablefilter.js~TableFilter#prfxValButton",
"access": "private",
"description": "Button's ID prefix",
- "lineNumber": 912,
+ "lineNumber": 906,
"type": {
"types": [
"string"
@@ -18685,7 +18703,7 @@
"longname": "src/tablefilter.js~TableFilter#prfxInfDiv",
"access": "private",
"description": "Toolbar container ID prefix",
- "lineNumber": 918,
+ "lineNumber": 912,
"type": {
"types": [
"string"
@@ -18702,7 +18720,7 @@
"longname": "src/tablefilter.js~TableFilter#prfxLDiv",
"access": "private",
"description": "Toolbar left element ID prefix",
- "lineNumber": 924,
+ "lineNumber": 918,
"type": {
"types": [
"string"
@@ -18719,7 +18737,7 @@
"longname": "src/tablefilter.js~TableFilter#prfxRDiv",
"access": "private",
"description": "Toolbar right element ID prefix",
- "lineNumber": 930,
+ "lineNumber": 924,
"type": {
"types": [
"string"
@@ -18736,7 +18754,7 @@
"longname": "src/tablefilter.js~TableFilter#prfxMDiv",
"access": "private",
"description": "Toolbar middle element ID prefix",
- "lineNumber": 936,
+ "lineNumber": 930,
"type": {
"types": [
"string"
@@ -18753,7 +18771,7 @@
"longname": "src/tablefilter.js~TableFilter#prfxResponsive",
"access": "private",
"description": "Responsive Css class",
- "lineNumber": 942,
+ "lineNumber": 936,
"type": {
"types": [
"string"
@@ -18770,7 +18788,7 @@
"longname": "src/tablefilter.js~TableFilter#extensions",
"access": "private",
"description": "List of loaded extensions",
- "lineNumber": 950,
+ "lineNumber": 944,
"type": {
"nullable": null,
"types": [
@@ -18790,7 +18808,7 @@
"longname": "src/tablefilter.js~TableFilter#hasExtensions",
"access": "private",
"description": "Determine whether extensions are loaded",
- "lineNumber": 957,
+ "lineNumber": 951,
"type": {
"nullable": null,
"types": [
@@ -18810,7 +18828,7 @@
"longname": "src/tablefilter.js~TableFilter#enableDefaultTheme",
"access": null,
"description": "Enable default theme",
- "lineNumber": 964,
+ "lineNumber": 958,
"type": {
"nullable": null,
"types": [
@@ -18830,7 +18848,7 @@
"longname": "src/tablefilter.js~TableFilter#hasThemes",
"access": "private",
"description": "Determine whether themes are enables",
- "lineNumber": 971,
+ "lineNumber": 965,
"type": {
"nullable": null,
"types": [
@@ -18850,7 +18868,7 @@
"longname": "src/tablefilter.js~TableFilter#themes",
"access": null,
"description": "List of themes, ie:\nthemes: [{ name: 'skyblue' }]",
- "lineNumber": 978,
+ "lineNumber": 972,
"type": {
"nullable": null,
"types": [
@@ -18870,7 +18888,7 @@
"longname": "src/tablefilter.js~TableFilter#themesPath",
"access": null,
"description": "Define path to themes assets, defaults to\n'tablefilter/style/themes/'. Usage:\nthemes: [{ name: 'skyblue' }]",
- "lineNumber": 986,
+ "lineNumber": 980,
"type": {
"nullable": null,
"types": [
@@ -18890,7 +18908,7 @@
"longname": "src/tablefilter.js~TableFilter#responsive",
"access": null,
"description": "Enable responsive layout",
- "lineNumber": 992,
+ "lineNumber": 986,
"type": {
"nullable": null,
"types": [
@@ -18910,7 +18928,7 @@
"longname": "src/tablefilter.js~TableFilter#Mod",
"access": "private",
"description": "Features registry",
- "lineNumber": 998,
+ "lineNumber": 992,
"type": {
"types": [
"*"
@@ -18927,7 +18945,7 @@
"longname": "src/tablefilter.js~TableFilter#ExtRegistry",
"access": "private",
"description": "Extensions registry",
- "lineNumber": 1004,
+ "lineNumber": 998,
"type": {
"types": [
"*"
@@ -18944,7 +18962,7 @@
"longname": "src/tablefilter.js~TableFilter#init",
"access": null,
"description": "Initialise features and layout",
- "lineNumber": 1010,
+ "lineNumber": 1004,
"params": [],
"generator": false
},
@@ -18958,7 +18976,7 @@
"longname": "src/tablefilter.js~TableFilter#nbFilterableRows",
"access": null,
"description": null,
- "lineNumber": 1074,
+ "lineNumber": 1068,
"undocument": true,
"type": {
"types": [
@@ -18976,7 +18994,7 @@
"longname": "src/tablefilter.js~TableFilter#initialized",
"access": null,
"description": "",
- "lineNumber": 1196,
+ "lineNumber": 1190,
"unknown": [
{
"tagName": "@inherited",
@@ -18999,7 +19017,7 @@
"longname": "src/tablefilter.js~TableFilter#detectKey",
"access": null,
"description": "Detect key",
- "lineNumber": 1208,
+ "lineNumber": 1202,
"params": [
{
"nullable": null,
@@ -19024,7 +19042,7 @@
"longname": "src/tablefilter.js~TableFilter#isUserTyping",
"access": null,
"description": null,
- "lineNumber": 1219,
+ "lineNumber": 1213,
"undocument": true,
"type": {
"types": [
@@ -19042,7 +19060,7 @@
"longname": "src/tablefilter.js~TableFilter#autoFilterTimer",
"access": null,
"description": null,
- "lineNumber": 1221,
+ "lineNumber": 1215,
"undocument": true,
"type": {
"types": [
@@ -19060,7 +19078,7 @@
"longname": "src/tablefilter.js~TableFilter#onKeyUp",
"access": null,
"description": "Filter's keyup event: if auto-filter on, detect user is typing and filter\ncolumns",
- "lineNumber": 1231,
+ "lineNumber": 1225,
"params": [
{
"nullable": null,
@@ -19085,7 +19103,7 @@
"longname": "src/tablefilter.js~TableFilter#isUserTyping",
"access": null,
"description": null,
- "lineNumber": 1236,
+ "lineNumber": 1230,
"undocument": true,
"type": {
"types": [
@@ -19103,7 +19121,7 @@
"longname": "src/tablefilter.js~TableFilter#autoFilterTimer",
"access": null,
"description": null,
- "lineNumber": 1240,
+ "lineNumber": 1234,
"undocument": true,
"type": {
"types": [
@@ -19121,7 +19139,7 @@
"longname": "src/tablefilter.js~TableFilter#isUserTyping",
"access": null,
"description": null,
- "lineNumber": 1243,
+ "lineNumber": 1237,
"undocument": true,
"type": {
"types": [
@@ -19139,7 +19157,7 @@
"longname": "src/tablefilter.js~TableFilter#autoFilterTimer",
"access": null,
"description": null,
- "lineNumber": 1250,
+ "lineNumber": 1244,
"undocument": true,
"type": {
"types": [
@@ -19157,7 +19175,7 @@
"longname": "src/tablefilter.js~TableFilter#autoFilterTimer",
"access": null,
"description": null,
- "lineNumber": 1255,
+ "lineNumber": 1249,
"undocument": true,
"type": {
"types": [
@@ -19175,7 +19193,7 @@
"longname": "src/tablefilter.js~TableFilter#onKeyDown",
"access": null,
"description": "Filter's keydown event: if auto-filter on, detect user is typing",
- "lineNumber": 1262,
+ "lineNumber": 1256,
"params": [],
"generator": false
},
@@ -19189,7 +19207,7 @@
"longname": "src/tablefilter.js~TableFilter#isUserTyping",
"access": null,
"description": null,
- "lineNumber": 1264,
+ "lineNumber": 1258,
"undocument": true,
"type": {
"types": [
@@ -19207,7 +19225,7 @@
"longname": "src/tablefilter.js~TableFilter#onInpFocus",
"access": null,
"description": "Filter's focus event",
- "lineNumber": 1272,
+ "lineNumber": 1266,
"params": [
{
"nullable": null,
@@ -19232,7 +19250,7 @@
"longname": "src/tablefilter.js~TableFilter#onInpBlur",
"access": null,
"description": "Filter's blur event: if auto-filter on, clear interval on filter blur",
- "lineNumber": 1280,
+ "lineNumber": 1274,
"params": [],
"generator": false
},
@@ -19246,7 +19264,7 @@
"longname": "src/tablefilter.js~TableFilter#isUserTyping",
"access": null,
"description": null,
- "lineNumber": 1282,
+ "lineNumber": 1276,
"undocument": true,
"type": {
"types": [
@@ -19264,7 +19282,7 @@
"longname": "src/tablefilter.js~TableFilter#_insertFiltersRow",
"access": null,
"description": "Insert filters row at initialization",
- "lineNumber": 1291,
+ "lineNumber": 1285,
"params": [],
"return": {
"types": [
@@ -19283,7 +19301,7 @@
"longname": "src/tablefilter.js~TableFilter#_initNoFilters",
"access": null,
"description": "Initialize filtersless table",
- "lineNumber": 1317,
+ "lineNumber": 1311,
"params": [],
"generator": false
},
@@ -19297,7 +19315,7 @@
"longname": "src/tablefilter.js~TableFilter#refRow",
"access": null,
"description": null,
- "lineNumber": 1321,
+ "lineNumber": 1315,
"undocument": true,
"type": {
"types": [
@@ -19315,7 +19333,7 @@
"longname": "src/tablefilter.js~TableFilter#nbFilterableRows",
"access": null,
"description": null,
- "lineNumber": 1322,
+ "lineNumber": 1316,
"undocument": true,
"type": {
"types": [
@@ -19333,7 +19351,7 @@
"longname": "src/tablefilter.js~TableFilter#_buildInputFilter",
"access": null,
"description": "Build input filter type",
- "lineNumber": 1331,
+ "lineNumber": 1325,
"params": [
{
"nullable": null,
@@ -19378,7 +19396,7 @@
"longname": "src/tablefilter.js~TableFilter#_buildSubmitButton",
"access": null,
"description": "Build submit button",
- "lineNumber": 1369,
+ "lineNumber": 1363,
"params": [
{
"nullable": null,
@@ -19413,7 +19431,7 @@
"longname": "src/tablefilter.js~TableFilter#feature",
"access": null,
"description": "Return a feature instance for a given name",
- "lineNumber": 1392,
+ "lineNumber": 1386,
"params": [
{
"nullable": null,
@@ -19446,7 +19464,7 @@
"longname": "src/tablefilter.js~TableFilter#initExtensions",
"access": null,
"description": "Initialise all the extensions defined in the configuration object",
- "lineNumber": 1399,
+ "lineNumber": 1393,
"params": [],
"generator": false
},
@@ -19460,7 +19478,7 @@
"longname": "src/tablefilter.js~TableFilter#loadExtension",
"access": null,
"description": "Load an extension module",
- "lineNumber": 1418,
+ "lineNumber": 1412,
"params": [
{
"nullable": null,
@@ -19485,7 +19503,7 @@
"longname": "src/tablefilter.js~TableFilter#extension",
"access": null,
"description": "Get an extension instance",
- "lineNumber": 1449,
+ "lineNumber": 1443,
"params": [
{
"nullable": null,
@@ -19518,7 +19536,7 @@
"longname": "src/tablefilter.js~TableFilter#hasExtension",
"access": null,
"description": "Check passed extension name exists",
- "lineNumber": 1458,
+ "lineNumber": 1452,
"params": [
{
"nullable": null,
@@ -19551,7 +19569,7 @@
"longname": "src/tablefilter.js~TableFilter#destroyExtensions",
"access": null,
"description": "Destroy all the extensions defined in the configuration object",
- "lineNumber": 1465,
+ "lineNumber": 1459,
"params": [],
"generator": false
},
@@ -19565,7 +19583,7 @@
"longname": "src/tablefilter.js~TableFilter#loadThemes",
"access": null,
"description": "Load themes defined in the configuration object",
- "lineNumber": 1481,
+ "lineNumber": 1475,
"params": [],
"generator": false
},
@@ -19579,7 +19597,7 @@
"longname": "src/tablefilter.js~TableFilter#loader",
"access": null,
"description": null,
- "lineNumber": 1510,
+ "lineNumber": 1504,
"undocument": true,
"type": {
"types": [
@@ -19597,7 +19615,7 @@
"longname": "src/tablefilter.js~TableFilter#getStylesheet",
"access": null,
"description": "Return stylesheet DOM element for a given theme name",
- "lineNumber": 1519,
+ "lineNumber": 1513,
"params": [
{
"name": "name",
@@ -19629,7 +19647,7 @@
"longname": "src/tablefilter.js~TableFilter#destroy",
"access": null,
"description": "Destroy filter grid",
- "lineNumber": 1526,
+ "lineNumber": 1520,
"params": [],
"generator": false
},
@@ -19643,7 +19661,7 @@
"longname": "src/tablefilter.js~TableFilter#nbHiddenRows",
"access": null,
"description": null,
- "lineNumber": 1581,
+ "lineNumber": 1575,
"undocument": true,
"type": {
"types": [
@@ -19661,7 +19679,7 @@
"longname": "src/tablefilter.js~TableFilter#validRowsIndex",
"access": null,
"description": null,
- "lineNumber": 1582,
+ "lineNumber": 1576,
"undocument": true,
"type": {
"types": [
@@ -19679,7 +19697,7 @@
"longname": "src/tablefilter.js~TableFilter#fltIds",
"access": null,
"description": null,
- "lineNumber": 1583,
+ "lineNumber": 1577,
"undocument": true,
"type": {
"types": [
@@ -19697,7 +19715,7 @@
"longname": "src/tablefilter.js~TableFilter#initialized",
"access": null,
"description": null,
- "lineNumber": 1584,
+ "lineNumber": 1578,
"undocument": true,
"type": {
"types": [
@@ -19715,7 +19733,7 @@
"longname": "src/tablefilter.js~TableFilter#setToolbar",
"access": null,
"description": "Generate container element for paging, reset button, rows counter etc.",
- "lineNumber": 1590,
+ "lineNumber": 1584,
"params": [],
"generator": false
},
@@ -19729,7 +19747,7 @@
"longname": "src/tablefilter.js~TableFilter#infDiv",
"access": null,
"description": null,
- "lineNumber": 1615,
+ "lineNumber": 1609,
"undocument": true,
"type": {
"types": [
@@ -19747,7 +19765,7 @@
"longname": "src/tablefilter.js~TableFilter#lDiv",
"access": null,
"description": null,
- "lineNumber": 1621,
+ "lineNumber": 1615,
"undocument": true,
"type": {
"types": [
@@ -19765,7 +19783,7 @@
"longname": "src/tablefilter.js~TableFilter#rDiv",
"access": null,
"description": null,
- "lineNumber": 1628,
+ "lineNumber": 1622,
"undocument": true,
"type": {
"types": [
@@ -19783,7 +19801,7 @@
"longname": "src/tablefilter.js~TableFilter#mDiv",
"access": null,
"description": null,
- "lineNumber": 1634,
+ "lineNumber": 1628,
"undocument": true,
"type": {
"types": [
@@ -19801,7 +19819,7 @@
"longname": "src/tablefilter.js~TableFilter#removeToolbar",
"access": null,
"description": "Remove toolbar container element",
- "lineNumber": 1648,
+ "lineNumber": 1642,
"params": [],
"generator": false
},
@@ -19815,7 +19833,7 @@
"longname": "src/tablefilter.js~TableFilter#infDiv",
"access": null,
"description": null,
- "lineNumber": 1653,
+ "lineNumber": 1647,
"undocument": true,
"type": {
"types": [
@@ -19833,7 +19851,7 @@
"longname": "src/tablefilter.js~TableFilter#removeExternalFlts",
"access": null,
"description": "Remove all the external column filters",
- "lineNumber": 1665,
+ "lineNumber": 1659,
"params": [],
"generator": false
},
@@ -19847,7 +19865,7 @@
"longname": "src/tablefilter.js~TableFilter#isCustomOptions",
"access": null,
"description": "Check if given column implements a filter with custom options",
- "lineNumber": 1685,
+ "lineNumber": 1679,
"params": [
{
"nullable": null,
@@ -19880,7 +19898,7 @@
"longname": "src/tablefilter.js~TableFilter#getCustomOptions",
"access": null,
"description": "Returns an array [[value0, value1 ...],[text0, text1 ...]] with the\ncustom options values and texts",
- "lineNumber": 1696,
+ "lineNumber": 1690,
"params": [
{
"nullable": null,
@@ -19913,7 +19931,7 @@
"longname": "src/tablefilter.js~TableFilter#filter",
"access": null,
"description": "Filter the table by retrieving the data from each cell in every single\nrow and comparing it to the search term for current column. A row is\nhidden when all the search terms are not found in inspected row.",
- "lineNumber": 1729,
+ "lineNumber": 1723,
"params": [],
"generator": false
},
@@ -19927,7 +19945,7 @@
"longname": "src/tablefilter.js~TableFilter#validRowsIndex",
"access": null,
"description": null,
- "lineNumber": 1743,
+ "lineNumber": 1737,
"undocument": true,
"type": {
"types": [
@@ -19945,7 +19963,7 @@
"longname": "src/tablefilter.js~TableFilter#nbHiddenRows",
"access": null,
"description": null,
- "lineNumber": 2074,
+ "lineNumber": 2068,
"undocument": true,
"type": {
"types": [
@@ -19963,7 +19981,7 @@
"longname": "src/tablefilter.js~TableFilter#getColValues",
"access": null,
"description": "Return the data of a specified column",
- "lineNumber": 2092,
+ "lineNumber": 2086,
"params": [
{
"nullable": null,
@@ -20026,7 +20044,7 @@
"longname": "src/tablefilter.js~TableFilter#getFilterValue",
"access": null,
"description": "Return the filter's value of a specified column",
- "lineNumber": 2137,
+ "lineNumber": 2131,
"params": [
{
"nullable": null,
@@ -20059,7 +20077,7 @@
"longname": "src/tablefilter.js~TableFilter#getFiltersValue",
"access": null,
"description": "Return the filters' values",
- "lineNumber": 2173,
+ "lineNumber": 2167,
"params": [],
"return": {
"nullable": null,
@@ -20081,7 +20099,7 @@
"longname": "src/tablefilter.js~TableFilter#getFilterId",
"access": null,
"description": "Return the ID of a specified column's filter",
- "lineNumber": 2194,
+ "lineNumber": 2188,
"params": [
{
"nullable": null,
@@ -20114,7 +20132,7 @@
"longname": "src/tablefilter.js~TableFilter#getFiltersByType",
"access": null,
"description": "Return the list of ids of filters matching a specified type.\nNote: hidden filters are also returned",
- "lineNumber": 2210,
+ "lineNumber": 2204,
"params": [
{
"nullable": null,
@@ -20157,7 +20175,7 @@
"longname": "src/tablefilter.js~TableFilter#getFilterElement",
"access": null,
"description": "Return the filter's DOM element for a given column",
- "lineNumber": 2230,
+ "lineNumber": 2224,
"params": [
{
"nullable": null,
@@ -20190,7 +20208,7 @@
"longname": "src/tablefilter.js~TableFilter#getCellsNb",
"access": null,
"description": "Return the number of cells for a given row index",
- "lineNumber": 2240,
+ "lineNumber": 2234,
"params": [
{
"nullable": null,
@@ -20223,7 +20241,7 @@
"longname": "src/tablefilter.js~TableFilter#getRowsNb",
"access": null,
"description": "Return the number of filterable rows starting from reference row if\ndefined",
- "lineNumber": 2251,
+ "lineNumber": 2245,
"params": [
{
"nullable": null,
@@ -20256,7 +20274,7 @@
"longname": "src/tablefilter.js~TableFilter#getCellData",
"access": null,
"description": "Return the data of a given cell",
- "lineNumber": 2265,
+ "lineNumber": 2259,
"params": [
{
"nullable": null,
@@ -20289,7 +20307,7 @@
"longname": "src/tablefilter.js~TableFilter#getTableData",
"access": null,
"description": "Return the table data with following format:\n[\n [rowIndex, [value0, value1...]],\n [rowIndex, [value0, value1...]]\n]",
- "lineNumber": 2288,
+ "lineNumber": 2282,
"params": [
{
"nullable": null,
@@ -20332,7 +20350,7 @@
"longname": "src/tablefilter.js~TableFilter#getFilteredData",
"access": null,
"description": "Return the filtered data with following format:\n[\n [rowIndex, [value0, value1...]],\n [rowIndex, [value0, value1...]]\n]",
- "lineNumber": 2325,
+ "lineNumber": 2319,
"params": [
{
"nullable": null,
@@ -20375,7 +20393,7 @@
"longname": "src/tablefilter.js~TableFilter#getFilteredDataCol",
"access": null,
"description": "Return the filtered data for a given column index",
- "lineNumber": 2362,
+ "lineNumber": 2356,
"params": [
{
"nullable": null,
@@ -20418,7 +20436,7 @@
"longname": "src/tablefilter.js~TableFilter#getRowDisplay",
"access": null,
"description": "Get the display value of a row",
- "lineNumber": 2387,
+ "lineNumber": 2381,
"params": [
{
"nullable": null,
@@ -20451,7 +20469,7 @@
"longname": "src/tablefilter.js~TableFilter#validateRow",
"access": null,
"description": "Validate/invalidate row by setting the 'validRow' attribute on the row",
- "lineNumber": 2396,
+ "lineNumber": 2390,
"params": [
{
"nullable": null,
@@ -20486,7 +20504,7 @@
"longname": "src/tablefilter.js~TableFilter#validateAllRows",
"access": null,
"description": "Validate all filterable rows",
- "lineNumber": 2431,
+ "lineNumber": 2425,
"params": [],
"generator": false
},
@@ -20500,7 +20518,7 @@
"longname": "src/tablefilter.js~TableFilter#validRowsIndex",
"access": null,
"description": null,
- "lineNumber": 2435,
+ "lineNumber": 2429,
"undocument": true,
"type": {
"types": [
@@ -20518,7 +20536,7 @@
"longname": "src/tablefilter.js~TableFilter#setFilterValue",
"access": null,
"description": "Set search value to a given filter",
- "lineNumber": 2446,
+ "lineNumber": 2440,
"params": [
{
"nullable": null,
@@ -20553,7 +20571,7 @@
"longname": "src/tablefilter.js~TableFilter#setColWidths",
"access": null,
"description": "Set them columns' widths as per configuration",
- "lineNumber": 2494,
+ "lineNumber": 2488,
"params": [
{
"nullable": null,
@@ -20578,7 +20596,7 @@
"longname": "src/tablefilter.js~TableFilter#enforceVisibility",
"access": null,
"description": "Makes defined rows always visible",
- "lineNumber": 2523,
+ "lineNumber": 2517,
"params": [],
"generator": false
},
@@ -20592,7 +20610,7 @@
"longname": "src/tablefilter.js~TableFilter#clearFilters",
"access": null,
"description": "Clear all the filters' values",
- "lineNumber": 2540,
+ "lineNumber": 2534,
"params": [],
"generator": false
},
@@ -20606,7 +20624,7 @@
"longname": "src/tablefilter.js~TableFilter#clearActiveColumns",
"access": null,
"description": "Clears filtered columns visual indicator (background color)",
- "lineNumber": 2565,
+ "lineNumber": 2559,
"params": [],
"generator": false
},
@@ -20620,7 +20638,7 @@
"longname": "src/tablefilter.js~TableFilter#markActiveColumn",
"access": null,
"description": "Mark currently filtered column",
- "lineNumber": 2575,
+ "lineNumber": 2569,
"params": [
{
"nullable": null,
@@ -20645,7 +20663,7 @@
"longname": "src/tablefilter.js~TableFilter#getActiveFilterId",
"access": null,
"description": "Return the ID of the current active filter",
- "lineNumber": 2593,
+ "lineNumber": 2587,
"unknown": [
{
"tagName": "@returns",
@@ -20673,7 +20691,7 @@
"longname": "src/tablefilter.js~TableFilter#setActiveFilterId",
"access": null,
"description": "Set the ID of the current active filter",
- "lineNumber": 2601,
+ "lineNumber": 2595,
"params": [
{
"nullable": null,
@@ -20698,7 +20716,7 @@
"longname": "src/tablefilter.js~TableFilter#activeFilterId",
"access": null,
"description": null,
- "lineNumber": 2602,
+ "lineNumber": 2596,
"undocument": true,
"type": {
"types": [
@@ -20716,7 +20734,7 @@
"longname": "src/tablefilter.js~TableFilter#getColumnIndexFromFilterId",
"access": null,
"description": "Return the column index for a given filter ID",
- "lineNumber": 2610,
+ "lineNumber": 2604,
"unknown": [
{
"tagName": "@returns",
@@ -20757,7 +20775,7 @@
"longname": "src/tablefilter.js~TableFilter#activateFilter",
"access": null,
"description": "Make specified column's filter active",
- "lineNumber": 2620,
+ "lineNumber": 2614,
"params": [
{
"nullable": null,
@@ -20782,7 +20800,7 @@
"longname": "src/tablefilter.js~TableFilter#linkFilters",
"access": null,
"description": "Refresh the filters subject to linking ('select', 'multiple',\n'checklist' type)",
- "lineNumber": 2631,
+ "lineNumber": 2625,
"params": [],
"generator": false
},
@@ -20796,7 +20814,7 @@
"longname": "src/tablefilter.js~TableFilter#isExactMatch",
"access": null,
"description": "Determines if passed filter column implements exact query match",
- "lineNumber": 2681,
+ "lineNumber": 2675,
"params": [
{
"nullable": null,
@@ -20829,7 +20847,7 @@
"longname": "src/tablefilter.js~TableFilter#isImported",
"access": null,
"description": "Check if passed script or stylesheet is already imported",
- "lineNumber": 2693,
+ "lineNumber": 2687,
"params": [
{
"nullable": null,
@@ -20872,7 +20890,7 @@
"longname": "src/tablefilter.js~TableFilter#import",
"access": null,
"description": "Import script or stylesheet",
- "lineNumber": 2716,
+ "lineNumber": 2710,
"params": [
{
"nullable": null,
@@ -20927,7 +20945,7 @@
"longname": "src/tablefilter.js~TableFilter#isInitialized",
"access": null,
"description": "Check if table has filters grid",
- "lineNumber": 2758,
+ "lineNumber": 2752,
"params": [],
"return": {
"nullable": null,
@@ -20949,7 +20967,7 @@
"longname": "src/tablefilter.js~TableFilter#getFiltersId",
"access": null,
"description": "Get list of filter IDs",
- "lineNumber": 2766,
+ "lineNumber": 2760,
"params": [],
"return": {
"nullable": null,
@@ -20971,7 +20989,7 @@
"longname": "src/tablefilter.js~TableFilter#getValidRows",
"access": null,
"description": "Get filtered (valid) rows indexes",
- "lineNumber": 2775,
+ "lineNumber": 2769,
"params": [
{
"nullable": null,
@@ -21004,7 +21022,7 @@
"longname": "src/tablefilter.js~TableFilter#validRowsIndex",
"access": null,
"description": null,
- "lineNumber": 2781,
+ "lineNumber": 2775,
"undocument": true,
"type": {
"types": [
@@ -21022,7 +21040,7 @@
"longname": "src/tablefilter.js~TableFilter#getFiltersRowIndex",
"access": null,
"description": "Get the index of the row containing the filters",
- "lineNumber": 2802,
+ "lineNumber": 2796,
"params": [],
"return": {
"nullable": null,
@@ -21044,7 +21062,7 @@
"longname": "src/tablefilter.js~TableFilter#getHeadersRowIndex",
"access": null,
"description": "Get the index of the headers row",
- "lineNumber": 2810,
+ "lineNumber": 2804,
"params": [],
"return": {
"nullable": null,
@@ -21066,7 +21084,7 @@
"longname": "src/tablefilter.js~TableFilter#getStartRowIndex",
"access": null,
"description": "Get the row index from where the filtering process start (1st filterable\nrow)",
- "lineNumber": 2819,
+ "lineNumber": 2813,
"params": [],
"return": {
"nullable": null,
@@ -21088,7 +21106,7 @@
"longname": "src/tablefilter.js~TableFilter#getLastRowIndex",
"access": null,
"description": "Get the index of the last row",
- "lineNumber": 2827,
+ "lineNumber": 2821,
"params": [],
"return": {
"nullable": null,
@@ -21110,7 +21128,7 @@
"longname": "src/tablefilter.js~TableFilter#getHeaderElement",
"access": null,
"description": "Get the header DOM element for a given column index",
- "lineNumber": 2837,
+ "lineNumber": 2831,
"params": [
{
"nullable": null,
@@ -21143,7 +21161,7 @@
"longname": "src/tablefilter.js~TableFilter#getHeadersText",
"access": null,
"description": "Return the list of headers' text",
- "lineNumber": 2862,
+ "lineNumber": 2856,
"params": [
{
"nullable": null,
@@ -21176,7 +21194,7 @@
"longname": "src/tablefilter.js~TableFilter#getFilterType",
"access": null,
"description": "Return the filter type for a specified column",
- "lineNumber": 2882,
+ "lineNumber": 2876,
"params": [
{
"nullable": null,
@@ -21209,7 +21227,7 @@
"longname": "src/tablefilter.js~TableFilter#getFilterableRowsNb",
"access": null,
"description": "Get the total number of filterable rows",
- "lineNumber": 2891,
+ "lineNumber": 2885,
"params": [],
"return": {
"nullable": null,
@@ -21231,7 +21249,7 @@
"longname": "src/tablefilter.js~TableFilter#getValidRowsNb",
"access": null,
"description": "Return the total number of valid rows",
- "lineNumber": 2900,
+ "lineNumber": 2894,
"unknown": [
{
"tagName": "@returns",
@@ -21272,7 +21290,7 @@
"longname": "src/tablefilter.js~TableFilter#config",
"access": null,
"description": "Get the configuration object (literal object)",
- "lineNumber": 2908,
+ "lineNumber": 2902,
"params": [],
"return": {
"nullable": null,
diff --git a/docs/file/src/array.js.html b/docs/file/src/array.js.html
index 69286e91..a80c7d66 100644
--- a/docs/file/src/array.js.html
+++ b/docs/file/src/array.js.html
@@ -3,7 +3,7 @@
- src/array.js | tablefilter v0.2.59 API Document
+ src/array.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/const.js.html b/docs/file/src/const.js.html
index 478669b1..492f9437 100644
--- a/docs/file/src/const.js.html
+++ b/docs/file/src/const.js.html
@@ -3,7 +3,7 @@
- src/const.js | tablefilter v0.2.59 API Document
+ src/const.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/cookie.js.html b/docs/file/src/cookie.js.html
index c93053fa..ada13ba0 100644
--- a/docs/file/src/cookie.js.html
+++ b/docs/file/src/cookie.js.html
@@ -3,7 +3,7 @@
- src/cookie.js | tablefilter v0.2.59 API Document
+ src/cookie.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/date.js.html b/docs/file/src/date.js.html
index 6c36a82c..880daa9c 100644
--- a/docs/file/src/date.js.html
+++ b/docs/file/src/date.js.html
@@ -3,7 +3,7 @@
- src/date.js | tablefilter v0.2.59 API Document
+ src/date.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/dom.js.html b/docs/file/src/dom.js.html
index 8d99db6c..c4689449 100644
--- a/docs/file/src/dom.js.html
+++ b/docs/file/src/dom.js.html
@@ -3,7 +3,7 @@
- src/dom.js | tablefilter v0.2.59 API Document
+ src/dom.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/emitter.js.html b/docs/file/src/emitter.js.html
index 3070c7b6..e72c1945 100644
--- a/docs/file/src/emitter.js.html
+++ b/docs/file/src/emitter.js.html
@@ -3,7 +3,7 @@
- src/emitter.js | tablefilter v0.2.59 API Document
+ src/emitter.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/event.js.html b/docs/file/src/event.js.html
index eac45b5e..37184dd5 100644
--- a/docs/file/src/event.js.html
+++ b/docs/file/src/event.js.html
@@ -3,7 +3,7 @@
- src/event.js | tablefilter v0.2.59 API Document
+ src/event.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/extensions/advancedGrid/adapterEzEditTable.js.html b/docs/file/src/extensions/advancedGrid/adapterEzEditTable.js.html
index 3d0fcbfc..49177f54 100644
--- a/docs/file/src/extensions/advancedGrid/adapterEzEditTable.js.html
+++ b/docs/file/src/extensions/advancedGrid/adapterEzEditTable.js.html
@@ -3,7 +3,7 @@
- src/extensions/advancedGrid/adapterEzEditTable.js | tablefilter v0.2.59 API Document
+ src/extensions/advancedGrid/adapterEzEditTable.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/extensions/advancedGrid/advancedGrid.js.html b/docs/file/src/extensions/advancedGrid/advancedGrid.js.html
index 386b90ea..a9ee3f80 100644
--- a/docs/file/src/extensions/advancedGrid/advancedGrid.js.html
+++ b/docs/file/src/extensions/advancedGrid/advancedGrid.js.html
@@ -3,7 +3,7 @@
- src/extensions/advancedGrid/advancedGrid.js | tablefilter v0.2.59 API Document
+ src/extensions/advancedGrid/advancedGrid.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/extensions/colOps/colOps.js.html b/docs/file/src/extensions/colOps/colOps.js.html
index d9dced17..ac571321 100644
--- a/docs/file/src/extensions/colOps/colOps.js.html
+++ b/docs/file/src/extensions/colOps/colOps.js.html
@@ -3,7 +3,7 @@
- src/extensions/colOps/colOps.js | tablefilter v0.2.59 API Document
+ src/extensions/colOps/colOps.js | tablefilter v0.2.60 API Document
@@ -119,34 +119,58 @@
import {createText, elm} from '../../dom';
import {isArray, isFn, isUndef} from '../../types';
+/**
+ * Column calculations extension
+ */
export default class ColOps extends Feature {
/**
- * Column calculations
- * @param {Object} tf TableFilter instance
+ * Creates an instance of ColOps
+ *
+ * @param {TableFilter} tf TableFilter instance
+ * @param {Object} opts Configuration object
*/
constructor(tf, opts) {
super(tf, opts.name);
- //calls function before col operation
+ /**
+ * Callback fired before columns operations start
+ * @type {Function}
+ */
this.onBeforeOperation = isFn(opts.on_before_operation) ?
opts.on_before_operation : null;
- //calls function after col operation
+
+ /**
+ * Callback fired after columns operations are completed
+ * @type {Function}
+ */
this.onAfterOperation = isFn(opts.on_after_operation) ?
opts.on_after_operation : null;
+ /**
+ * Configuration options
+ * @type {Object}
+ */
this.opts = opts;
+
this.enable();
}
+ /**
+ * Initializes ColOps instance
+ */
init() {
if (this.initialized) {
return;
}
// subscribe to events
- this.tf.emitter.on(['after-filtering'], () => this.calc());
+ this.emitter.on(['after-filtering'], () => this.calc());
this.calc();
+
+ /**
+ * @inherited
+ */
this.initialized = true;
}
@@ -167,16 +191,17 @@ export default class ColOps extends Feature {
* (2) added calculations for the median, lower and upper quartile.
*/
calc() {
- var tf = this.tf;
+ let tf = this.tf;
if (!tf.isInitialized()) {
return;
}
if (this.onBeforeOperation) {
- this.onBeforeOperation.call(null, tf);
+ this.onBeforeOperation.call(null, tf, this);
}
+ this.emitter.emit('before-column-operation', tf, this);
- var opts = this.opts,
+ let opts = this.opts,
labelId = opts.id,
colIndex = opts.col,
operation = opts.operation,
@@ -187,14 +212,14 @@ export default class ColOps extends Feature {
2 : opts.decimal_precision;
//nuovella: determine unique list of columns to operate on
- var ucolIndex = [],
+ let ucolIndex = [],
ucolMax = 0;
ucolIndex[ucolMax] = colIndex[0];
- for (var ii = 1; ii < colIndex.length; ii++) {
- var saved = 0;
+ for (let ii = 1; ii < colIndex.length; ii++) {
+ let saved = 0;
//see if colIndex[ii] is already in the list of unique indexes
- for (var jj = 0; jj <= ucolMax; jj++) {
+ for (let jj = 0; jj <= ucolMax; jj++) {
if (ucolIndex[jj] === colIndex[ii]) {
saved = 1;
}
@@ -207,10 +232,10 @@ export default class ColOps extends Feature {
}
if (isArray(labelId) && isArray(colIndex) && isArray(operation)) {
- var rows = tf.tbl.rows,
+ let rows = tf.tbl.rows,
colvalues = [];
- for (var ucol = 0; ucol <= ucolMax; ucol++) {
+ for (let ucol = 0; 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
@@ -218,7 +243,7 @@ export default class ColOps extends Feature {
tf.getColValues(ucolIndex[ucol], false, true, excludeRow));
//next: calculate all operations for this column
- var result,
+ let result,
nbvalues = 0,
temp,
meanValue = 0,
@@ -242,7 +267,7 @@ export default class ColOps extends Feature {
oTypeThisCol = [],
mThisCol = -1;
- for (var k = 0; k < colIndex.length; k++) {
+ for (let k = 0; k < colIndex.length; k++) {
if (colIndex[k] === ucolIndex[ucol]) {
mThisCol++;
opsThisCol[mThisCol] = operation[k].toLowerCase();
@@ -277,7 +302,7 @@ export default class ColOps extends Feature {
}
}
- for (var j = 0; j < colvalues[ucol].length; j++) {
+ for (let j = 0; 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) {
@@ -293,7 +318,7 @@ export default class ColOps extends Feature {
}
}
}
- var cvalue = parseFloat(colvalues[ucol][j]);
+ let cvalue = parseFloat(colvalues[ucol][j]);
theList[j] = parseFloat(cvalue);
if (!isNaN(cvalue)) {
@@ -323,7 +348,7 @@ export default class ColOps extends Feature {
meanValue = sumValue / nbvalues;
}
if (medFlag === 1) {
- var aux = 0;
+ let aux = 0;
if (nbvalues % 2 === 1) {
aux = Math.floor(nbvalues / 2);
medValue = theList[aux];
@@ -332,7 +357,7 @@ export default class ColOps extends Feature {
theList[((nbvalues / 2) - 1)]) / 2;
}
}
- var posa;
+ let posa;
if (q1Flag === 1) {
posa = 0.0;
posa = Math.floor(nbvalues / 4);
@@ -344,7 +369,7 @@ export default class ColOps extends Feature {
}
if (q3Flag === 1) {
posa = 0.0;
- var posb = 0.0;
+ let posb = 0.0;
posa = Math.floor(nbvalues / 4);
if (4 * posa === nbvalues) {
posb = 3 * posa;
@@ -354,7 +379,7 @@ export default class ColOps extends Feature {
}
}
- for (var i = 0; i <= mThisCol; i++) {
+ for (let i = 0; i <= mThisCol; i++) {
switch (opsThisCol[i]) {
case 'mean':
result = meanValue;
@@ -379,7 +404,7 @@ export default class ColOps extends Feature {
break;
}
- var precision = !isNaN(decThisCol[i]) ? decThisCol[i] : 2;
+ let precision = !isNaN(decThisCol[i]) ? decThisCol[i] : 2;
//if outputType is defined
if (oTypeThisCol && result) {
@@ -399,9 +424,9 @@ export default class ColOps extends Feature {
elm(labThisCol[i]).value = result;
break;
case 'createtextnode':
- var oldnode =
+ let oldnode =
elm(labThisCol[i]).firstChild;
- var txtnode = createText(result);
+ let txtnode = createText(result);
elm(labThisCol[i])
.replaceChild(txtnode, oldnode);
break;
@@ -421,7 +446,7 @@ export default class ColOps extends Feature {
}//for i
// row(s) with result are always visible
- var totRow = totRowIndex && totRowIndex[ucol] ?
+ let totRow = totRowIndex && totRowIndex[ucol] ?
rows[totRowIndex[ucol]] : null;
if (totRow) {
totRow.style.display = '';
@@ -430,16 +455,20 @@ export default class ColOps extends Feature {
}//if typeof
if (this.onAfterOperation) {
- this.onAfterOperation.call(null, tf);
+ this.onAfterOperation.call(null, tf, this);
}
+ this.emitter.emit('after-column-operation', tf, this);
}
+ /**
+ * Remove extension
+ */
destroy() {
if (!this.initialized) {
return;
}
// unsubscribe to events
- this.tf.emitter.off(['after-filtering'], () => this.calc());
+ this.emitter.off(['after-filtering'], () => this.calc());
this.initialized = false;
}
diff --git a/docs/file/src/extensions/colsVisibility/colsVisibility.js.html b/docs/file/src/extensions/colsVisibility/colsVisibility.js.html
index 33471fee..eaa04bc5 100644
--- a/docs/file/src/extensions/colsVisibility/colsVisibility.js.html
+++ b/docs/file/src/extensions/colsVisibility/colsVisibility.js.html
@@ -3,7 +3,7 @@
- src/extensions/colsVisibility/colsVisibility.js | tablefilter v0.2.59 API Document
+ src/extensions/colsVisibility/colsVisibility.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/extensions/filtersVisibility/filtersVisibility.js.html b/docs/file/src/extensions/filtersVisibility/filtersVisibility.js.html
index b24746e9..b2418664 100644
--- a/docs/file/src/extensions/filtersVisibility/filtersVisibility.js.html
+++ b/docs/file/src/extensions/filtersVisibility/filtersVisibility.js.html
@@ -3,7 +3,7 @@
- src/extensions/filtersVisibility/filtersVisibility.js | tablefilter v0.2.59 API Document
+ src/extensions/filtersVisibility/filtersVisibility.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/extensions/sort/adapterSortabletable.js.html b/docs/file/src/extensions/sort/adapterSortabletable.js.html
index 15a9f636..026ae165 100644
--- a/docs/file/src/extensions/sort/adapterSortabletable.js.html
+++ b/docs/file/src/extensions/sort/adapterSortabletable.js.html
@@ -3,7 +3,7 @@
- src/extensions/sort/adapterSortabletable.js | tablefilter v0.2.59 API Document
+ src/extensions/sort/adapterSortabletable.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/extensions/sort/sort.js.html b/docs/file/src/extensions/sort/sort.js.html
index 98bbd399..f6ceb049 100644
--- a/docs/file/src/extensions/sort/sort.js.html
+++ b/docs/file/src/extensions/sort/sort.js.html
@@ -3,7 +3,7 @@
- src/extensions/sort/sort.js | tablefilter v0.2.59 API Document
+ src/extensions/sort/sort.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/feature.js.html b/docs/file/src/feature.js.html
index aee0ad1a..4010f11d 100644
--- a/docs/file/src/feature.js.html
+++ b/docs/file/src/feature.js.html
@@ -3,7 +3,7 @@
- src/feature.js | tablefilter v0.2.59 API Document
+ src/feature.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/helpers.js.html b/docs/file/src/helpers.js.html
index b6df7885..2f28d890 100644
--- a/docs/file/src/helpers.js.html
+++ b/docs/file/src/helpers.js.html
@@ -3,7 +3,7 @@
- src/helpers.js | tablefilter v0.2.59 API Document
+ src/helpers.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/alternateRows.js.html b/docs/file/src/modules/alternateRows.js.html
index 25e5ff49..dc4499b5 100644
--- a/docs/file/src/modules/alternateRows.js.html
+++ b/docs/file/src/modules/alternateRows.js.html
@@ -3,7 +3,7 @@
- src/modules/alternateRows.js | tablefilter v0.2.59 API Document
+ src/modules/alternateRows.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/checkList.js.html b/docs/file/src/modules/checkList.js.html
index c464f66d..762f7e2e 100644
--- a/docs/file/src/modules/checkList.js.html
+++ b/docs/file/src/modules/checkList.js.html
@@ -3,7 +3,7 @@
- src/modules/checkList.js | tablefilter v0.2.59 API Document
+ src/modules/checkList.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/clearButton.js.html b/docs/file/src/modules/clearButton.js.html
index 388e8dc1..33000bda 100644
--- a/docs/file/src/modules/clearButton.js.html
+++ b/docs/file/src/modules/clearButton.js.html
@@ -3,7 +3,7 @@
- src/modules/clearButton.js | tablefilter v0.2.59 API Document
+ src/modules/clearButton.js | tablefilter v0.2.60 API Document
@@ -152,6 +152,12 @@ export class ClearButton extends Feature {
*/
this.text = f.btn_reset_text || 'Reset';
+ /**
+ * Css class for reset button
+ * @type {String}
+ */
+ this.cssClass = f.btn_reset_css_class || 'reset';
+
/**
* Tooltip text for the clear button
* @type {String}
@@ -164,7 +170,7 @@ export class ClearButton extends Feature {
*/
this.html = f.btn_reset_html ||
(!tf.enableIcons ? null :
- '<input type="button" value="" class="' + tf.btnResetCssClass +
+ '<input type="button" value="" class="' + this.cssClass +
'" ' + 'title="' + this.tooltip + '" />');
/**
@@ -207,7 +213,7 @@ export class ClearButton extends Feature {
if (!this.html) {
let fltreset = createElm('a', ['href', 'javascript:void(0);']);
- fltreset.className = tf.btnResetCssClass;
+ fltreset.className = this.cssClass;
fltreset.appendChild(createText(this.text));
resetspan.appendChild(fltreset);
addEvt(fltreset, 'click', () => this.onClick());
diff --git a/docs/file/src/modules/dropdown.js.html b/docs/file/src/modules/dropdown.js.html
index 0e9ffc4c..f0f127cd 100644
--- a/docs/file/src/modules/dropdown.js.html
+++ b/docs/file/src/modules/dropdown.js.html
@@ -3,7 +3,7 @@
- src/modules/dropdown.js | tablefilter v0.2.59 API Document
+ src/modules/dropdown.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/gridLayout.js.html b/docs/file/src/modules/gridLayout.js.html
index e2fc331a..cbe8b98e 100644
--- a/docs/file/src/modules/gridLayout.js.html
+++ b/docs/file/src/modules/gridLayout.js.html
@@ -3,7 +3,7 @@
- src/modules/gridLayout.js | tablefilter v0.2.59 API Document
+ src/modules/gridLayout.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/hash.js.html b/docs/file/src/modules/hash.js.html
index 7f91319a..ef6391cb 100644
--- a/docs/file/src/modules/hash.js.html
+++ b/docs/file/src/modules/hash.js.html
@@ -3,7 +3,7 @@
- src/modules/hash.js | tablefilter v0.2.59 API Document
+ src/modules/hash.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/help.js.html b/docs/file/src/modules/help.js.html
index 237eea65..73ed66be 100644
--- a/docs/file/src/modules/help.js.html
+++ b/docs/file/src/modules/help.js.html
@@ -3,7 +3,7 @@
- src/modules/help.js | tablefilter v0.2.59 API Document
+ src/modules/help.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/highlightKeywords.js.html b/docs/file/src/modules/highlightKeywords.js.html
index c6e9f092..ab1b061e 100644
--- a/docs/file/src/modules/highlightKeywords.js.html
+++ b/docs/file/src/modules/highlightKeywords.js.html
@@ -3,7 +3,7 @@
- src/modules/highlightKeywords.js | tablefilter v0.2.59 API Document
+ src/modules/highlightKeywords.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/loader.js.html b/docs/file/src/modules/loader.js.html
index d3d3cc8e..3f96e93e 100644
--- a/docs/file/src/modules/loader.js.html
+++ b/docs/file/src/modules/loader.js.html
@@ -3,7 +3,7 @@
- src/modules/loader.js | tablefilter v0.2.59 API Document
+ src/modules/loader.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/noResults.js.html b/docs/file/src/modules/noResults.js.html
index 073d2b45..510caa69 100644
--- a/docs/file/src/modules/noResults.js.html
+++ b/docs/file/src/modules/noResults.js.html
@@ -3,7 +3,7 @@
- src/modules/noResults.js | tablefilter v0.2.59 API Document
+ src/modules/noResults.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/paging.js.html b/docs/file/src/modules/paging.js.html
index 8e90968a..0db493da 100644
--- a/docs/file/src/modules/paging.js.html
+++ b/docs/file/src/modules/paging.js.html
@@ -3,7 +3,7 @@
- src/modules/paging.js | tablefilter v0.2.59 API Document
+ src/modules/paging.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/popupFilter.js.html b/docs/file/src/modules/popupFilter.js.html
index 8c6e8205..7a32e4e1 100644
--- a/docs/file/src/modules/popupFilter.js.html
+++ b/docs/file/src/modules/popupFilter.js.html
@@ -3,7 +3,7 @@
- src/modules/popupFilter.js | tablefilter v0.2.59 API Document
+ src/modules/popupFilter.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/rowsCounter.js.html b/docs/file/src/modules/rowsCounter.js.html
index bd0b26c1..1b419fe7 100644
--- a/docs/file/src/modules/rowsCounter.js.html
+++ b/docs/file/src/modules/rowsCounter.js.html
@@ -3,7 +3,7 @@
- src/modules/rowsCounter.js | tablefilter v0.2.59 API Document
+ src/modules/rowsCounter.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/state.js.html b/docs/file/src/modules/state.js.html
index b3220a12..a46744fb 100644
--- a/docs/file/src/modules/state.js.html
+++ b/docs/file/src/modules/state.js.html
@@ -3,7 +3,7 @@
- src/modules/state.js | tablefilter v0.2.59 API Document
+ src/modules/state.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/statusBar.js.html b/docs/file/src/modules/statusBar.js.html
index b6b002dc..48918cb1 100644
--- a/docs/file/src/modules/statusBar.js.html
+++ b/docs/file/src/modules/statusBar.js.html
@@ -3,7 +3,7 @@
- src/modules/statusBar.js | tablefilter v0.2.59 API Document
+ src/modules/statusBar.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/modules/storage.js.html b/docs/file/src/modules/storage.js.html
index a5dd28e7..534aed58 100644
--- a/docs/file/src/modules/storage.js.html
+++ b/docs/file/src/modules/storage.js.html
@@ -3,7 +3,7 @@
- src/modules/storage.js | tablefilter v0.2.59 API Document
+ src/modules/storage.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/root.js.html b/docs/file/src/root.js.html
index 04893e45..dbaac810 100644
--- a/docs/file/src/root.js.html
+++ b/docs/file/src/root.js.html
@@ -3,7 +3,7 @@
- src/root.js | tablefilter v0.2.59 API Document
+ src/root.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/sort.js.html b/docs/file/src/sort.js.html
index 3934c1fd..177b7ef7 100644
--- a/docs/file/src/sort.js.html
+++ b/docs/file/src/sort.js.html
@@ -3,7 +3,7 @@
- src/sort.js | tablefilter v0.2.59 API Document
+ src/sort.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/string.js.html b/docs/file/src/string.js.html
index 1de53d07..5dcec4fb 100644
--- a/docs/file/src/string.js.html
+++ b/docs/file/src/string.js.html
@@ -3,7 +3,7 @@
- src/string.js | tablefilter v0.2.59 API Document
+ src/string.js | tablefilter v0.2.60 API Document
diff --git a/docs/file/src/tablefilter.js.html b/docs/file/src/tablefilter.js.html
index 1afe7a15..31eda900 100644
--- a/docs/file/src/tablefilter.js.html
+++ b/docs/file/src/tablefilter.js.html
@@ -3,7 +3,7 @@
- src/tablefilter.js | tablefilter v0.2.59 API Document
+ src/tablefilter.js | tablefilter v0.2.60 API Document
@@ -881,12 +881,6 @@ export class TableFilter {
*/
this.btnReset = Boolean(f.btn_reset);
- /**
- * Css class for reset button
- * @type {String}
- */
- this.btnResetCssClass = f.btn_reset_css_class || 'reset';
-
/**
* Callback fired before filters are cleared
* @type {Function}
diff --git a/docs/file/src/types.js.html b/docs/file/src/types.js.html
index cc2254f0..cde2678a 100644
--- a/docs/file/src/types.js.html
+++ b/docs/file/src/types.js.html
@@ -3,7 +3,7 @@
- src/types.js | tablefilter v0.2.59 API Document
+ src/types.js | tablefilter v0.2.60 API Document
diff --git a/docs/identifiers.html b/docs/identifiers.html
index 6fa65de1..07746e3c 100644
--- a/docs/identifiers.html
+++ b/docs/identifiers.html
@@ -3,7 +3,7 @@
- Index | tablefilter v0.2.59 API Document
+ Index | tablefilter v0.2.60 API Document
@@ -264,7 +264,8 @@
-
+ Column calculations extension
+
|
diff --git a/docs/index.html b/docs/index.html
index 5e65893b..14d8cdde 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -3,7 +3,7 @@
- tablefilter v0.2.59 API Document
+ tablefilter v0.2.60 API Document
diff --git a/docs/package.json b/docs/package.json
index 1d07faaf..bec8f570 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -1,6 +1,6 @@
{
"name": "tablefilter",
- "version": "0.2.59",
+ "version": "0.2.60",
"description": "A Javascript library making HTML tables filterable and a bit more",
"license": "MIT",
"author": {
@@ -50,7 +50,7 @@
"script-loader": "^0.7.0",
"string-replace-webpack-plugin": "^0.0.3",
"webpack": "^1.13.2",
- "webpack-dev-server": "^1.15.0"
+ "webpack-dev-server": "^1.15.1"
},
"dependencies": {},
"bugs": {
diff --git a/docs/script/search_index.js b/docs/script/search_index.js
index 86710d14..6ab572db 100644
--- a/docs/script/search_index.js
+++ b/docs/script/search_index.js
@@ -1997,6 +1997,12 @@ window.esdocSearchIndex = [
"src/modules/clearButton.js~ClearButton#constructor",
"method"
],
+ [
+ "src/modules/clearbutton.js~clearbutton#cssclass",
+ "class/src/modules/clearButton.js~ClearButton.html#instance-member-cssClass",
+ "src/modules/clearButton.js~ClearButton#cssClass",
+ "member"
+ ],
[
"src/modules/clearbutton.js~clearbutton#destroy",
"class/src/modules/clearButton.js~ClearButton.html#instance-method-destroy",
@@ -3521,12 +3527,6 @@ window.esdocSearchIndex = [
"src/tablefilter.js~TableFilter#btnReset",
"member"
],
- [
- "src/tablefilter.js~tablefilter#btnresetcssclass",
- "class/src/tablefilter.js~TableFilter.html#instance-member-btnResetCssClass",
- "src/tablefilter.js~TableFilter#btnResetCssClass",
- "member"
- ],
[
"src/tablefilter.js~tablefilter#btntext",
"class/src/tablefilter.js~TableFilter.html#instance-member-btnText",
diff --git a/docs/source.html b/docs/source.html
index 3e6a6b1e..838f0f86 100644
--- a/docs/source.html
+++ b/docs/source.html
@@ -3,7 +3,7 @@
- Source | tablefilter v0.2.59 API Document
+ Source | tablefilter v0.2.60 API Document
@@ -114,7 +114,7 @@
-Source 535/652
+ Source 542/652
@@ -135,7 +135,7 @@
| 100 %1/1 |
545 byte |
22 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/const.js |
@@ -155,7 +155,7 @@
100 %13/13 |
1133 byte |
84 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/cookie.js |
@@ -163,7 +163,7 @@
- |
1412 byte |
57 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/date.js |
@@ -172,7 +172,7 @@
100 %2/2 |
5770 byte |
183 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/dom.js |
@@ -191,7 +191,7 @@
100 %12/12 |
4787 byte |
191 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/emitter.js |
@@ -199,7 +199,7 @@
100 %6/6 |
1323 byte |
53 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/event.js |
@@ -212,7 +212,7 @@
100 %6/6 |
2378 byte |
102 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/extensions/advancedGrid/adapterEzEditTable.js |
@@ -220,7 +220,7 @@
35 %5/14 |
18245 byte |
459 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/extensions/advancedGrid/advancedGrid.js |
@@ -228,15 +228,15 @@
- |
90 byte |
2 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
- | src/extensions/colOps/colOps.js |
+ src/extensions/colOps/colOps.js |
ColOps |
- 22 %2/9 |
- 12868 byte |
- 329 |
- 2016-08-04 11:19:31 (UTC) |
+ 100 %9/9 |
+ 13472 byte |
+ 358 |
+ 2016-09-06 03:41:41 (UTC) |
| src/extensions/colsVisibility/colsVisibility.js |
@@ -244,7 +244,7 @@
17 %10/57 |
18064 byte |
546 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/extensions/filtersVisibility/filtersVisibility.js |
@@ -252,7 +252,7 @@
18 %6/33 |
6337 byte |
202 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/extensions/sort/adapterSortabletable.js |
@@ -260,7 +260,7 @@
11 %3/26 |
14150 byte |
432 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/extensions/sort/sort.js |
@@ -268,7 +268,7 @@
- |
197 byte |
8 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/feature.js |
@@ -276,7 +276,7 @@
100 %14/14 |
1761 byte |
94 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/helpers.js |
@@ -284,7 +284,7 @@
100 %1/1 |
448 byte |
19 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/alternateRows.js |
@@ -292,7 +292,7 @@
100 %9/9 |
3527 byte |
140 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/checkList.js |
@@ -300,15 +300,15 @@
100 %21/21 |
18567 byte |
567 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/clearButton.js |
ClearButton |
- 100 %9/9 |
- 3090 byte |
- 127 |
- 2016-08-04 11:19:31 (UTC) |
+ 100 %10/10 |
+ 3225 byte |
+ 133 |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/dropdown.js |
@@ -316,7 +316,7 @@
100 %13/13 |
13641 byte |
432 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/gridLayout.js |
@@ -324,7 +324,7 @@
80 %16/20 |
14595 byte |
504 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/hash.js |
@@ -333,7 +333,7 @@
100 %10/10 |
2981 byte |
126 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/help.js |
@@ -341,7 +341,7 @@
100 %17/17 |
6347 byte |
217 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/highlightKeywords.js |
@@ -349,7 +349,7 @@
100 %10/10 |
4434 byte |
147 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/loader.js |
@@ -357,7 +357,7 @@
100 %14/14 |
5298 byte |
211 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/noResults.js |
@@ -365,7 +365,7 @@
100 %17/17 |
5178 byte |
215 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/paging.js |
@@ -373,7 +373,7 @@
100 %45/45 |
29379 byte |
955 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/popupFilter.js |
@@ -381,7 +381,7 @@
100 %21/21 |
10205 byte |
356 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/rowsCounter.js |
@@ -389,7 +389,7 @@
100 %13/13 |
6357 byte |
224 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/state.js |
@@ -397,7 +397,7 @@
100 %24/24 |
14771 byte |
541 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/statusBar.js |
@@ -405,7 +405,7 @@
100 %22/22 |
9553 byte |
333 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/modules/storage.js |
@@ -414,7 +414,7 @@
100 %10/10 |
3544 byte |
162 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/root.js |
@@ -422,7 +422,7 @@
100 %1/1 |
235 byte |
6 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/sort.js |
@@ -432,7 +432,7 @@
100 %3/3 |
930 byte |
33 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/string.js |
@@ -444,15 +444,15 @@
100 %5/5 |
1854 byte |
69 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
| src/tablefilter.js |
TableFilter |
- 100 %166/166 |
- 88640 byte |
- 2911 |
- 2016-08-04 11:19:31 (UTC) |
+ 100 %165/165 |
+ 88485 byte |
+ 2905 |
+ 2016-09-06 03:41:41 (UTC) |
| src/types.js |
@@ -467,7 +467,7 @@
100 %8/8 |
1451 byte |
67 |
- 2016-08-04 11:19:31 (UTC) |
+ 2016-09-06 03:41:41 (UTC) |
diff --git a/docs/variable/index.html b/docs/variable/index.html
index 9767496c..29029aea 100644
--- a/docs/variable/index.html
+++ b/docs/variable/index.html
@@ -3,7 +3,7 @@
- Variable | tablefilter v0.2.59 API Document
+ Variable | tablefilter v0.2.60 API Document
|