2015-05-30 14:23:33 +02:00
|
|
|
import Event from './event';
|
|
|
|
import Dom from './dom';
|
|
|
|
import Str from './string';
|
|
|
|
import Cookie from './cookie';
|
|
|
|
import Types from './types';
|
|
|
|
import Arr from './array';
|
|
|
|
import DateHelper from './date';
|
|
|
|
import Helpers from './helpers';
|
2015-12-27 12:08:14 +01:00
|
|
|
import {Emitter} from './emitter';
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-07-04 10:49:30 +02:00
|
|
|
// Features
|
2015-05-02 11:54:24 +02:00
|
|
|
import {Store} from './modules/store';
|
|
|
|
import {GridLayout} from './modules/gridLayout';
|
|
|
|
import {Loader} from './modules/loader';
|
|
|
|
import {HighlightKeyword} from './modules/highlightKeywords';
|
|
|
|
import {PopupFilter} from './modules/popupFilter';
|
|
|
|
import {Dropdown} from './modules/dropdown';
|
|
|
|
import {CheckList} from './modules/checkList';
|
|
|
|
import {RowsCounter} from './modules/rowsCounter';
|
|
|
|
import {StatusBar} from './modules/statusBar';
|
|
|
|
import {Paging} from './modules/paging';
|
|
|
|
import {ClearButton} from './modules/clearButton';
|
|
|
|
import {Help} from './modules/help';
|
|
|
|
import {AlternateRows} from './modules/alternateRows';
|
2015-12-08 12:53:12 +01:00
|
|
|
import {NoResults} from './modules/noResults';
|
2015-02-28 10:27:28 +01:00
|
|
|
|
2015-12-25 02:31:00 +01:00
|
|
|
let global = window,
|
2015-02-22 12:46:05 +01:00
|
|
|
doc = global.document;
|
|
|
|
|
2015-12-27 12:08:14 +01:00
|
|
|
export class TableFilter {
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
/**
|
2015-10-31 09:00:28 +01:00
|
|
|
* TableFilter object constructor
|
|
|
|
* requires `table` or `id` arguments, `row` and `configuration` optional
|
|
|
|
* @param {DOMElement} table Table DOM element
|
2015-02-22 12:46:05 +01:00
|
|
|
* @param {String} id Table id
|
|
|
|
* @param {Number} row index indicating the 1st row
|
|
|
|
* @param {Object} configuration object
|
|
|
|
*/
|
2015-10-31 09:00:28 +01:00
|
|
|
constructor(...args) {
|
|
|
|
if(args.length === 0){ return; }
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-10-31 09:00:28 +01:00
|
|
|
this.id = null;
|
2015-06-07 12:30:32 +02:00
|
|
|
this.version = '{VERSION}';
|
2015-02-22 12:46:05 +01:00
|
|
|
this.year = new Date().getFullYear();
|
2015-10-31 09:00:28 +01:00
|
|
|
this.tbl = null;
|
2015-02-22 12:46:05 +01:00
|
|
|
this.startRow = null;
|
|
|
|
this.refRow = null;
|
|
|
|
this.headersRow = null;
|
|
|
|
this.cfg = {};
|
|
|
|
this.nbFilterableRows = null;
|
|
|
|
this.nbRows = null;
|
|
|
|
this.nbCells = null;
|
|
|
|
this._hasGrid = false;
|
2015-10-31 09:00:28 +01:00
|
|
|
|
|
|
|
// TODO: use for-of with babel plug-in
|
|
|
|
args.forEach((arg)=> {
|
2015-12-27 12:08:14 +01:00
|
|
|
// for (let arg of args) {
|
2015-10-31 09:00:28 +01:00
|
|
|
let argtype = typeof arg;
|
|
|
|
if(argtype === 'object' && arg && arg.nodeName === 'TABLE'){
|
|
|
|
this.tbl = arg;
|
|
|
|
this.id = arg.id || `tf_${new Date().getTime()}_`;
|
|
|
|
} else if(argtype === 'string'){
|
|
|
|
this.id = arg;
|
|
|
|
this.tbl = Dom.id(arg);
|
|
|
|
} else if(argtype === 'number'){
|
|
|
|
this.startRow = arg;
|
|
|
|
} else if(argtype === 'object'){
|
|
|
|
this.cfg = arg;
|
|
|
|
}
|
2015-12-27 12:08:14 +01:00
|
|
|
// }
|
2015-10-31 09:00:28 +01:00
|
|
|
});
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-06-07 12:30:32 +02:00
|
|
|
if(!this.tbl || this.tbl.nodeName != 'TABLE' || this.getRowsNb() === 0){
|
2015-02-22 12:46:05 +01:00
|
|
|
throw new Error(
|
2015-07-04 10:49:30 +02:00
|
|
|
'Could not instantiate TableFilter: HTML table not found.');
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// configuration object
|
2015-05-30 14:23:33 +02:00
|
|
|
let f = this.cfg;
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-12-27 12:08:14 +01:00
|
|
|
this.emitter = new Emitter();
|
|
|
|
|
2015-02-22 12:46:05 +01:00
|
|
|
//Start row et cols nb
|
2015-10-31 09:00:28 +01:00
|
|
|
this.refRow = this.startRow === null ? 2 : (this.startRow+1);
|
2015-02-22 12:46:05 +01:00
|
|
|
try{ this.nbCells = this.getCellsNb(this.refRow); }
|
|
|
|
catch(e){ this.nbCells = this.getCellsNb(0); }
|
|
|
|
|
|
|
|
//default script base path
|
2015-05-15 12:37:27 +02:00
|
|
|
this.basePath = f.base_path || 'tablefilter/';
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
/*** filter types ***/
|
2015-05-17 11:35:49 +02:00
|
|
|
this.fltTypeInp = 'input';
|
|
|
|
this.fltTypeSlc = 'select';
|
|
|
|
this.fltTypeMulti = 'multiple';
|
|
|
|
this.fltTypeCheckList = 'checklist';
|
|
|
|
this.fltTypeNone = 'none';
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
/*** filters' grid properties ***/
|
|
|
|
|
|
|
|
//enables/disables filter grid
|
2015-10-31 09:00:28 +01:00
|
|
|
this.fltGrid = f.grid === false ? false : true;
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
//enables/disables grid layout (fixed headers)
|
2015-06-04 15:04:38 +02:00
|
|
|
this.gridLayout = Boolean(f.grid_layout);
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-08-11 13:28:26 +02:00
|
|
|
this.filtersRowIndex = isNaN(f.filters_row_index) ?
|
|
|
|
0 : f.filters_row_index;
|
|
|
|
this.headersRow = isNaN(f.headers_row_index) ?
|
2015-10-31 09:00:28 +01:00
|
|
|
(this.filtersRowIndex === 0 ? 1 : 0) : f.headers_row_index;
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
if(this.gridLayout){
|
|
|
|
if(this.headersRow > 1){
|
|
|
|
this.filtersRowIndex = this.headersRow+1;
|
|
|
|
} else {
|
|
|
|
this.filtersRowIndex = 1;
|
|
|
|
this.headersRow = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//defines tag of the cells containing filters (td/th)
|
|
|
|
this.fltCellTag = f.filters_cell_tag!=='th' ||
|
|
|
|
f.filters_cell_tag!=='td' ? 'td' : f.filters_cell_tag;
|
|
|
|
|
|
|
|
//stores filters ids
|
|
|
|
this.fltIds = [];
|
|
|
|
//stores filters DOM elements
|
|
|
|
this.fltElms = [];
|
|
|
|
//stores filters values
|
|
|
|
this.searchArgs = null;
|
|
|
|
//stores valid rows indexes (rows visible upon filtering)
|
2015-12-31 02:56:50 +01:00
|
|
|
this.validRowsIndex = [];
|
2015-02-22 12:46:05 +01:00
|
|
|
//stores filters row element
|
|
|
|
this.fltGridEl = null;
|
|
|
|
//is first load boolean
|
|
|
|
this.isFirstLoad = true;
|
|
|
|
//container div for paging elements, reset btn etc.
|
|
|
|
this.infDiv = null;
|
|
|
|
//div for rows counter
|
|
|
|
this.lDiv = null;
|
|
|
|
//div for reset button and results per page select
|
|
|
|
this.rDiv = null;
|
|
|
|
//div for paging elements
|
|
|
|
this.mDiv = null;
|
|
|
|
|
2015-05-15 16:26:21 +02:00
|
|
|
//defines css class for div containing paging elements, rows counter etc
|
2015-02-22 12:46:05 +01:00
|
|
|
this.infDivCssClass = f.inf_div_css_class || 'inf';
|
|
|
|
//defines css class for left div
|
|
|
|
this.lDivCssClass = f.left_div_css_class || 'ldiv';
|
|
|
|
//defines css class for right div
|
|
|
|
this.rDivCssClass = f.right_div_css_class || 'rdiv';
|
|
|
|
//defines css class for mid div
|
|
|
|
this.mDivCssClass = f.middle_div_css_class || 'mdiv';
|
|
|
|
//table container div css class
|
|
|
|
this.contDivCssClass = f.content_div_css_class || 'cont';
|
|
|
|
|
|
|
|
/*** filters' grid appearance ***/
|
|
|
|
//stylesheet file
|
2015-06-06 14:22:13 +02:00
|
|
|
this.stylePath = f.style_path || this.basePath + 'style/';
|
|
|
|
this.stylesheet = f.stylesheet || this.stylePath+'tablefilter.css';
|
2015-02-22 12:46:05 +01:00
|
|
|
this.stylesheetId = this.id + '_style';
|
|
|
|
//defines css class for filters row
|
|
|
|
this.fltsRowCssClass = f.flts_row_css_class || 'fltrow';
|
|
|
|
//enables/disables icons (paging, reset button)
|
|
|
|
this.enableIcons = f.enable_icons===false ? false : true;
|
|
|
|
//enables/disbles rows alternating bg colors
|
2015-11-14 16:14:13 +01:00
|
|
|
this.alternateRows = Boolean(f.alternate_rows);
|
2015-02-22 12:46:05 +01:00
|
|
|
//defines widths of columns
|
2015-05-30 14:23:33 +02:00
|
|
|
this.hasColWidths = Types.isArray(f.col_widths);
|
2015-05-28 15:44:23 +02:00
|
|
|
this.colWidths = this.hasColWidths ? f.col_widths : null;
|
2015-02-22 12:46:05 +01:00
|
|
|
//defines css class for filters
|
|
|
|
this.fltCssClass = f.flt_css_class || 'flt';
|
|
|
|
//defines css class for multiple selects filters
|
|
|
|
this.fltMultiCssClass = f.flt_multi_css_class || 'flt_multi';
|
|
|
|
//defines css class for filters
|
|
|
|
this.fltSmallCssClass = f.flt_small_css_class || 'flt_s';
|
|
|
|
//defines css class for single-filter
|
|
|
|
this.singleFltCssClass = f.single_flt_css_class || 'single_flt';
|
|
|
|
|
|
|
|
/*** filters' grid behaviours ***/
|
|
|
|
//enables/disables enter key
|
|
|
|
this.enterKey = f.enter_key===false ? false : true;
|
|
|
|
//calls function before filtering starts
|
2015-05-30 14:23:33 +02:00
|
|
|
this.onBeforeFilter = Types.isFn(f.on_before_filter) ?
|
2015-02-22 12:46:05 +01:00
|
|
|
f.on_before_filter : null;
|
|
|
|
//calls function after filtering
|
2015-05-30 14:23:33 +02:00
|
|
|
this.onAfterFilter = Types.isFn(f.on_after_filter) ?
|
2015-02-22 12:46:05 +01:00
|
|
|
f.on_after_filter : null;
|
|
|
|
//enables/disables case sensitivity
|
2015-06-04 15:04:38 +02:00
|
|
|
this.caseSensitive = Boolean(f.case_sensitive);
|
2015-10-13 15:15:18 +02:00
|
|
|
//has exact match per column
|
|
|
|
this.hasExactMatchByCol = Types.isArray(f.columns_exact_match);
|
|
|
|
this.exactMatchByCol = this.hasExactMatchByCol ?
|
|
|
|
f.columns_exact_match : [];
|
2015-02-22 12:46:05 +01:00
|
|
|
//enables/disbles exact match for search
|
2015-06-04 15:04:38 +02:00
|
|
|
this.exactMatch = Boolean(f.exact_match);
|
2015-02-22 12:46:05 +01:00
|
|
|
//refreshes drop-down lists upon validation
|
2015-06-04 15:04:38 +02:00
|
|
|
this.linkedFilters = Boolean(f.linked_filters);
|
2015-02-22 12:46:05 +01:00
|
|
|
//wheter excluded options are disabled
|
2015-06-04 15:04:38 +02:00
|
|
|
this.disableExcludedOptions = Boolean(f.disable_excluded_options);
|
2015-02-22 12:46:05 +01:00
|
|
|
//stores active filter element
|
|
|
|
this.activeFlt = null;
|
|
|
|
//id of active filter
|
|
|
|
this.activeFilterId = null;
|
|
|
|
//enables always visible rows
|
2015-06-04 15:04:38 +02:00
|
|
|
this.hasVisibleRows = Boolean(f.rows_always_visible);
|
2015-02-22 12:46:05 +01:00
|
|
|
//array containing always visible rows
|
|
|
|
this.visibleRows = this.hasVisibleRows ? f.rows_always_visible : [];
|
|
|
|
//enables/disables external filters generation
|
2015-06-04 15:04:38 +02:00
|
|
|
this.isExternalFlt = Boolean(f.external_flt_grid);
|
2015-02-22 12:46:05 +01:00
|
|
|
//array containing ids of external elements containing filters
|
|
|
|
this.externalFltTgtIds = f.external_flt_grid_ids || null;
|
|
|
|
//stores filters elements if isExternalFlt is true
|
|
|
|
this.externalFltEls = [];
|
|
|
|
//delays any filtering process if loader true
|
|
|
|
this.execDelay = !isNaN(f.exec_delay) ? parseInt(f.exec_delay,10) : 100;
|
|
|
|
//calls function when filters grid loaded
|
2015-05-30 14:23:33 +02:00
|
|
|
this.onFiltersLoaded = Types.isFn(f.on_filters_loaded) ?
|
2015-02-22 12:46:05 +01:00
|
|
|
f.on_filters_loaded : null;
|
|
|
|
//enables/disables single filter search
|
2015-08-11 13:28:26 +02:00
|
|
|
this.singleSearchFlt = Boolean(f.single_filter);
|
2015-02-22 12:46:05 +01:00
|
|
|
//calls function after row is validated
|
2015-05-30 14:23:33 +02:00
|
|
|
this.onRowValidated = Types.isFn(f.on_row_validated) ?
|
2015-02-22 12:46:05 +01:00
|
|
|
f.on_row_validated : null;
|
|
|
|
//array defining columns for customCellData event
|
|
|
|
this.customCellDataCols = f.custom_cell_data_cols ?
|
|
|
|
f.custom_cell_data_cols : [];
|
|
|
|
//calls custom function for retrieving cell data
|
2015-05-30 14:23:33 +02:00
|
|
|
this.customCellData = Types.isFn(f.custom_cell_data) ?
|
2015-02-22 12:46:05 +01:00
|
|
|
f.custom_cell_data : null;
|
|
|
|
//input watermark text array
|
|
|
|
this.watermark = f.watermark || '';
|
2015-05-30 14:23:33 +02:00
|
|
|
this.isWatermarkArray = Types.isArray(this.watermark);
|
2015-02-22 12:46:05 +01:00
|
|
|
//id of toolbar container element
|
|
|
|
this.toolBarTgtId = f.toolbar_target_id || null;
|
|
|
|
//enables/disables help div
|
2015-11-21 04:41:40 +01:00
|
|
|
this.help = Types.isUndef(f.help_instructions) ?
|
2015-06-05 15:10:25 +02:00
|
|
|
undefined : Boolean(f.help_instructions);
|
2015-02-22 12:46:05 +01:00
|
|
|
//popup filters
|
2015-11-21 04:41:40 +01:00
|
|
|
this.popupFilters = Boolean(f.popup_filters);
|
2015-02-22 12:46:05 +01:00
|
|
|
//active columns color
|
2015-06-04 15:04:38 +02:00
|
|
|
this.markActiveColumns = Boolean(f.mark_active_columns);
|
2015-02-22 12:46:05 +01:00
|
|
|
//defines css class for active column header
|
|
|
|
this.activeColumnsCssClass = f.active_columns_css_class ||
|
|
|
|
'activeHeader';
|
|
|
|
//calls function before active column header is marked
|
2015-05-30 14:23:33 +02:00
|
|
|
this.onBeforeActiveColumn = Types.isFn(f.on_before_active_column) ?
|
2015-02-22 12:46:05 +01:00
|
|
|
f.on_before_active_column : null;
|
|
|
|
//calls function after active column header is marked
|
2015-05-30 14:23:33 +02:00
|
|
|
this.onAfterActiveColumn = Types.isFn(f.on_after_active_column) ?
|
2015-02-22 12:46:05 +01:00
|
|
|
f.on_after_active_column : null;
|
|
|
|
|
|
|
|
/*** select filter's customisation and behaviours ***/
|
|
|
|
//defines 1st option text
|
2015-06-09 10:46:08 +02:00
|
|
|
this.displayAllText = f.display_all_text || 'Clear';
|
2015-02-22 12:46:05 +01:00
|
|
|
//enables/disables empty option in combo-box filters
|
2015-06-04 15:04:38 +02:00
|
|
|
this.enableEmptyOption = Boolean(f.enable_empty_option);
|
2015-02-22 12:46:05 +01:00
|
|
|
//defines empty option text
|
|
|
|
this.emptyText = f.empty_text || '(Empty)';
|
|
|
|
//enables/disables non empty option in combo-box filters
|
2015-06-04 15:04:38 +02:00
|
|
|
this.enableNonEmptyOption = Boolean(f.enable_non_empty_option);
|
2015-02-22 12:46:05 +01:00
|
|
|
//defines empty option text
|
|
|
|
this.nonEmptyText = f.non_empty_text || '(Non empty)';
|
|
|
|
//enables/disables onChange event on combo-box
|
|
|
|
this.onSlcChange = f.on_change===false ? false : true;
|
|
|
|
//enables/disables select options sorting
|
|
|
|
this.sortSlc = f.sort_select===false ? false : true;
|
|
|
|
//enables/disables ascending numeric options sorting
|
2015-06-04 15:04:38 +02:00
|
|
|
this.isSortNumAsc = Boolean(f.sort_num_asc);
|
2015-02-22 12:46:05 +01:00
|
|
|
this.sortNumAsc = this.isSortNumAsc ? f.sort_num_asc : null;
|
|
|
|
//enables/disables descending numeric options sorting
|
2015-06-04 15:04:38 +02:00
|
|
|
this.isSortNumDesc = Boolean(f.sort_num_desc);
|
2015-02-22 12:46:05 +01:00
|
|
|
this.sortNumDesc = this.isSortNumDesc ? f.sort_num_desc : null;
|
2015-09-20 10:42:00 +02:00
|
|
|
//Select filters are populated on demand
|
|
|
|
this.loadFltOnDemand = Boolean(f.load_filters_on_demand);
|
2015-06-02 09:33:16 +02:00
|
|
|
this.hasCustomOptions = Types.isObj(f.custom_options);
|
|
|
|
this.customOptions = f.custom_options;
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
/*** Filter operators ***/
|
|
|
|
this.rgxOperator = f.regexp_operator || 'rgx:';
|
|
|
|
this.emOperator = f.empty_operator || '[empty]';
|
|
|
|
this.nmOperator = f.nonempty_operator || '[nonempty]';
|
|
|
|
this.orOperator = f.or_operator || '||';
|
|
|
|
this.anOperator = f.and_operator || '&&';
|
|
|
|
this.grOperator = f.greater_operator || '>';
|
|
|
|
this.lwOperator = f.lower_operator || '<';
|
|
|
|
this.leOperator = f.lower_equal_operator || '<=';
|
|
|
|
this.geOperator = f.greater_equal_operator || '>=';
|
|
|
|
this.dfOperator = f.different_operator || '!';
|
|
|
|
this.lkOperator = f.like_operator || '*';
|
|
|
|
this.eqOperator = f.equal_operator || '=';
|
|
|
|
this.stOperator = f.start_with_operator || '{';
|
|
|
|
this.enOperator = f.end_with_operator || '}';
|
|
|
|
this.curExp = f.cur_exp || '^[¥£€$]';
|
|
|
|
this.separator = f.separator || ',';
|
|
|
|
|
|
|
|
/*** rows counter ***/
|
|
|
|
//show/hides rows counter
|
2015-06-04 15:04:38 +02:00
|
|
|
this.rowsCounter = Boolean(f.rows_counter);
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
/*** status bar ***/
|
|
|
|
//show/hides status bar
|
2015-06-04 15:04:38 +02:00
|
|
|
this.statusBar = Boolean(f.status_bar);
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
/*** loader ***/
|
|
|
|
//enables/disables loader/spinner indicator
|
2015-06-04 15:04:38 +02:00
|
|
|
this.loader = Boolean(f.loader);
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
/*** validation - reset buttons/links ***/
|
|
|
|
//show/hides filter's validation button
|
2015-06-04 15:04:38 +02:00
|
|
|
this.displayBtn = Boolean(f.btn);
|
2015-02-22 12:46:05 +01:00
|
|
|
//defines validation button text
|
|
|
|
this.btnText = f.btn_text || (!this.enableIcons ? 'Go' : '');
|
|
|
|
//defines css class for validation button
|
|
|
|
this.btnCssClass = f.btn_css_class ||
|
|
|
|
(!this.enableIcons ? 'btnflt' : 'btnflt_icon');
|
|
|
|
//show/hides reset link
|
2015-06-04 15:04:38 +02:00
|
|
|
this.btnReset = Boolean(f.btn_reset);
|
2015-02-22 12:46:05 +01:00
|
|
|
//defines css class for reset button
|
|
|
|
this.btnResetCssClass = f.btn_reset_css_class || 'reset';
|
|
|
|
//callback function before filters are cleared
|
2015-05-30 14:23:33 +02:00
|
|
|
this.onBeforeReset = Types.isFn(f.on_before_reset) ?
|
2015-02-22 12:46:05 +01:00
|
|
|
f.on_before_reset : null;
|
|
|
|
//callback function after filters are cleared
|
2015-05-30 14:23:33 +02:00
|
|
|
this.onAfterReset = Types.isFn(f.on_after_reset) ?
|
2015-02-22 12:46:05 +01:00
|
|
|
f.on_after_reset : null;
|
|
|
|
|
|
|
|
/*** paging ***/
|
|
|
|
//enables/disables table paging
|
2015-06-04 15:04:38 +02:00
|
|
|
this.paging = Boolean(f.paging);
|
2015-02-22 12:46:05 +01:00
|
|
|
this.nbVisibleRows = 0; //nb visible rows
|
|
|
|
this.nbHiddenRows = 0; //nb hidden rows
|
|
|
|
|
2015-06-07 12:30:32 +02:00
|
|
|
/*** autofilter on typing ***/
|
2015-06-04 15:04:38 +02:00
|
|
|
//enables/disables auto filtering, table is filtered when user stops
|
2015-02-22 12:46:05 +01:00
|
|
|
//typing
|
2015-06-04 15:04:38 +02:00
|
|
|
this.autoFilter = Boolean(f.auto_filter);
|
2015-02-22 12:46:05 +01:00
|
|
|
//onkeyup delay timer (msecs)
|
2015-06-04 15:04:38 +02:00
|
|
|
this.autoFilterDelay = !isNaN(f.auto_filter_delay) ?
|
|
|
|
f.auto_filter_delay : 900;
|
|
|
|
//typing indicator
|
|
|
|
this.isUserTyping = null;
|
|
|
|
this.autoFilterTimer = null;
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
/*** keyword highlighting ***/
|
|
|
|
//enables/disables keyword highlighting
|
2015-06-04 15:04:38 +02:00
|
|
|
this.highlightKeywords = Boolean(f.highlight_keywords);
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-12-08 12:53:12 +01:00
|
|
|
/*** No results feature ***/
|
2015-12-08 13:13:18 +01:00
|
|
|
this.noResults = Types.isObj(f.no_results_message) ||
|
2015-12-08 12:53:12 +01:00
|
|
|
Boolean(f.no_results_message);
|
|
|
|
|
2015-02-22 12:46:05 +01:00
|
|
|
/*** data types ***/
|
|
|
|
//defines default date type (european DMY)
|
|
|
|
this.defaultDateType = f.default_date_type || 'DMY';
|
|
|
|
//defines default thousands separator
|
|
|
|
//US = ',' EU = '.'
|
|
|
|
this.thousandsSeparator = f.thousands_separator || ',';
|
|
|
|
//defines default decimal separator
|
|
|
|
//US & javascript = '.' EU = ','
|
|
|
|
this.decimalSeparator = f.decimal_separator || '.';
|
|
|
|
//enables number format per column
|
2015-06-08 12:21:50 +02:00
|
|
|
this.hasColNbFormat = Types.isArray(f.col_number_format);
|
2015-02-22 12:46:05 +01:00
|
|
|
//array containing columns nb formats
|
2015-06-08 12:21:50 +02:00
|
|
|
this.colNbFormat = this.hasColNbFormat ? f.col_number_format : null;
|
2015-02-22 12:46:05 +01:00
|
|
|
//enables date type per column
|
2015-06-04 15:04:38 +02:00
|
|
|
this.hasColDateType = Types.isArray(f.col_date_type);
|
2015-02-22 12:46:05 +01:00
|
|
|
//array containing columns date type
|
2015-06-04 15:04:38 +02:00
|
|
|
this.colDateType = this.hasColDateType ? f.col_date_type : null;
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
/*** status messages ***/
|
|
|
|
//filtering
|
|
|
|
this.msgFilter = f.msg_filter || 'Filtering data...';
|
|
|
|
//populating drop-downs
|
|
|
|
this.msgPopulate = f.msg_populate || 'Populating filter...';
|
|
|
|
//populating drop-downs
|
|
|
|
this.msgPopulateCheckList = f.msg_populate_checklist ||
|
|
|
|
'Populating list...';
|
|
|
|
//changing paging page
|
|
|
|
this.msgChangePage = f.msg_change_page || 'Collecting paging data...';
|
|
|
|
//clearing filters
|
|
|
|
this.msgClear = f.msg_clear || 'Clearing filters...';
|
|
|
|
//changing nb results/page
|
|
|
|
this.msgChangeResults = f.msg_change_results ||
|
|
|
|
'Changing results per page...';
|
|
|
|
//re-setting grid values
|
|
|
|
this.msgResetValues = f.msg_reset_grid_values ||
|
|
|
|
'Re-setting filters values...';
|
|
|
|
//re-setting page
|
|
|
|
this.msgResetPage = f.msg_reset_page || 'Re-setting page...';
|
|
|
|
//re-setting page length
|
|
|
|
this.msgResetPageLength = f.msg_reset_page_length ||
|
|
|
|
'Re-setting page length...';
|
|
|
|
//table sorting
|
|
|
|
this.msgSort = f.msg_sort || 'Sorting data...';
|
|
|
|
//extensions loading
|
|
|
|
this.msgLoadExtensions = f.msg_load_extensions ||
|
|
|
|
'Loading extensions...';
|
|
|
|
//themes loading
|
|
|
|
this.msgLoadThemes = f.msg_load_themes || 'Loading theme(s)...';
|
|
|
|
|
|
|
|
/*** ids prefixes ***/
|
|
|
|
//css class name added to table
|
|
|
|
this.prfxTf = 'TF';
|
|
|
|
//filters (inputs - selects)
|
|
|
|
this.prfxFlt = 'flt';
|
|
|
|
//validation button
|
|
|
|
this.prfxValButton = 'btn';
|
|
|
|
//container div for paging elements, rows counter etc.
|
|
|
|
this.prfxInfDiv = 'inf_';
|
|
|
|
//left div
|
|
|
|
this.prfxLDiv = 'ldiv_';
|
|
|
|
//right div
|
|
|
|
this.prfxRDiv = 'rdiv_';
|
|
|
|
//middle div
|
|
|
|
this.prfxMDiv = 'mdiv_';
|
|
|
|
//filter values cookie
|
|
|
|
this.prfxCookieFltsValues = 'tf_flts_';
|
|
|
|
//page nb cookie
|
|
|
|
this.prfxCookiePageNb = 'tf_pgnb_';
|
|
|
|
//page length cookie
|
|
|
|
this.prfxCookiePageLen = 'tf_pglen_';
|
|
|
|
|
|
|
|
/*** cookies ***/
|
|
|
|
this.hasStoredValues = false;
|
|
|
|
//remembers filters values on page load
|
2015-06-04 15:04:38 +02:00
|
|
|
this.rememberGridValues = Boolean(f.remember_grid_values);
|
2015-02-22 12:46:05 +01:00
|
|
|
//cookie storing filter values
|
|
|
|
this.fltsValuesCookie = this.prfxCookieFltsValues + this.id;
|
|
|
|
//remembers page nb on page load
|
2015-06-04 15:04:38 +02:00
|
|
|
this.rememberPageNb = this.paging && f.remember_page_number;
|
2015-02-22 12:46:05 +01:00
|
|
|
//cookie storing page nb
|
|
|
|
this.pgNbCookie = this.prfxCookiePageNb + this.id;
|
|
|
|
//remembers page length on page load
|
2015-06-04 15:04:38 +02:00
|
|
|
this.rememberPageLen = this.paging && f.remember_page_length;
|
2015-02-22 12:46:05 +01:00
|
|
|
//cookie storing page length
|
|
|
|
this.pgLenCookie = this.prfxCookiePageLen + this.id;
|
|
|
|
|
|
|
|
/*** extensions ***/
|
|
|
|
//imports external script
|
2015-04-19 13:05:33 +02:00
|
|
|
this.extensions = f.extensions;
|
2015-05-30 14:23:33 +02:00
|
|
|
this.hasExtensions = Types.isArray(this.extensions);
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
/*** themes ***/
|
2015-06-04 15:04:38 +02:00
|
|
|
this.enableDefaultTheme = Boolean(f.enable_default_theme);
|
2015-02-22 12:46:05 +01:00
|
|
|
//imports themes
|
2015-06-04 15:04:38 +02:00
|
|
|
this.hasThemes = (this.enableDefaultTheme || Types.isArray(f.themes));
|
2015-05-15 16:26:21 +02:00
|
|
|
this.themes = f.themes || [];
|
2015-02-22 12:46:05 +01:00
|
|
|
//themes path
|
2015-06-06 14:22:13 +02:00
|
|
|
this.themesPath = f.themes_path || this.stylePath + 'themes/';
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-03-01 11:44:39 +01:00
|
|
|
// Features registry
|
2015-06-08 12:21:50 +02:00
|
|
|
this.Mod = {};
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-03-01 11:44:39 +01:00
|
|
|
// Extensions registry
|
2015-06-05 15:10:25 +02:00
|
|
|
this.ExtRegistry = {};
|
2015-03-01 11:44:39 +01:00
|
|
|
|
2015-02-22 12:46:05 +01:00
|
|
|
/*** TF events ***/
|
|
|
|
this.Evt = {
|
|
|
|
name: {
|
|
|
|
filter: 'Filter',
|
2015-06-08 12:21:50 +02:00
|
|
|
dropdown: 'DropDown',
|
|
|
|
checklist: 'CheckList',
|
|
|
|
changepage: 'ChangePage',
|
2015-02-22 12:46:05 +01:00
|
|
|
clear: 'Clear',
|
2015-06-08 12:21:50 +02:00
|
|
|
changeresultsperpage: 'ChangeResults',
|
2015-02-22 12:46:05 +01:00
|
|
|
resetvalues: 'ResetValues',
|
2015-06-08 12:21:50 +02:00
|
|
|
resetpage: 'ResetPage',
|
|
|
|
resetpagelength: 'ResetPageLength',
|
2015-02-22 12:46:05 +01:00
|
|
|
loadextensions: 'LoadExtensions',
|
2015-06-08 12:21:50 +02:00
|
|
|
loadthemes: 'LoadThemes'
|
2015-02-22 12:46:05 +01:00
|
|
|
},
|
2015-04-06 11:21:49 +02:00
|
|
|
|
2015-06-27 16:47:13 +02:00
|
|
|
// Detect <enter> key
|
2015-05-23 10:55:51 +02:00
|
|
|
detectKey(e) {
|
2015-06-04 15:04:38 +02:00
|
|
|
if(!this.enterKey){ return; }
|
2015-05-30 14:23:33 +02:00
|
|
|
let _ev = e || global.event;
|
2015-05-24 11:16:09 +02:00
|
|
|
if(_ev){
|
2015-05-30 14:23:33 +02:00
|
|
|
let key = Event.keyCode(_ev);
|
2015-02-22 12:46:05 +01:00
|
|
|
if(key===13){
|
2015-06-04 15:04:38 +02:00
|
|
|
this.filter();
|
2015-05-30 14:23:33 +02:00
|
|
|
Event.cancel(_ev);
|
|
|
|
Event.stop(_ev);
|
2015-02-22 12:46:05 +01:00
|
|
|
} else {
|
2015-06-04 15:04:38 +02:00
|
|
|
this.isUserTyping = true;
|
|
|
|
global.clearInterval(this.autoFilterTimer);
|
|
|
|
this.autoFilterTimer = null;
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-05-24 11:16:09 +02:00
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
},
|
2015-06-27 16:47:13 +02:00
|
|
|
// if auto-filter on, detect user is typing and filter columns
|
2015-05-23 10:55:51 +02:00
|
|
|
onKeyUp(e) {
|
2015-06-04 15:04:38 +02:00
|
|
|
if(!this.autoFilter){
|
2015-02-22 12:46:05 +01:00
|
|
|
return;
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
let _ev = e || global.event;
|
|
|
|
let key = Event.keyCode(_ev);
|
2015-06-04 15:04:38 +02:00
|
|
|
this.isUserTyping = false;
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
function filter() {
|
2015-06-04 15:04:38 +02:00
|
|
|
/*jshint validthis:true */
|
|
|
|
global.clearInterval(this.autoFilterTimer);
|
|
|
|
this.autoFilterTimer = null;
|
|
|
|
if(!this.isUserTyping){
|
|
|
|
this.filter();
|
|
|
|
this.isUserTyping = null;
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(key!==13 && key!==9 && key!==27 && key!==38 && key!==40) {
|
2015-06-04 15:04:38 +02:00
|
|
|
if(this.autoFilterTimer === null){
|
|
|
|
this.autoFilterTimer = global.setInterval(
|
|
|
|
filter.bind(this), this.autoFilterDelay);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
} else {
|
2015-06-04 15:04:38 +02:00
|
|
|
global.clearInterval(this.autoFilterTimer);
|
|
|
|
this.autoFilterTimer = null;
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
},
|
2015-06-27 16:47:13 +02:00
|
|
|
// if auto-filter on, detect user is typing
|
2015-05-23 10:55:51 +02:00
|
|
|
onKeyDown() {
|
2015-06-04 15:04:38 +02:00
|
|
|
if(!this.autoFilter) { return; }
|
|
|
|
this.isUserTyping = true;
|
2015-02-22 12:46:05 +01:00
|
|
|
},
|
2015-06-27 16:47:13 +02:00
|
|
|
// if auto-filter on, clear interval on filter blur
|
2015-05-23 10:55:51 +02:00
|
|
|
onInpBlur() {
|
2015-06-04 15:04:38 +02:00
|
|
|
if(this.autoFilter){
|
|
|
|
this.isUserTyping = false;
|
|
|
|
global.clearInterval(this.autoFilterTimer);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-07-19 14:43:18 +02:00
|
|
|
// TODO: hack to prevent ezEditTable enter key event hijaking.
|
|
|
|
// Needs to be fixed in the vendor's library
|
|
|
|
if(this.hasExtension('advancedGrid')){
|
|
|
|
var advGrid = this.extension('advancedGrid');
|
|
|
|
var ezEditTable = advGrid._ezEditTable;
|
|
|
|
if(advGrid.cfg.editable){
|
|
|
|
ezEditTable.Editable.Set();
|
|
|
|
}
|
|
|
|
if(advGrid.cfg.selection){
|
|
|
|
ezEditTable.Selection.Set();
|
|
|
|
}
|
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
},
|
2015-06-27 16:47:13 +02:00
|
|
|
// set focused text-box filter as active
|
2015-05-23 10:55:51 +02:00
|
|
|
onInpFocus(e) {
|
2015-05-30 14:23:33 +02:00
|
|
|
let _ev = e || global.event;
|
2015-06-04 15:04:38 +02:00
|
|
|
let elm = Event.target(_ev);
|
|
|
|
this.activeFilterId = elm.getAttribute('id');
|
|
|
|
this.activeFlt = Dom.id(this.activeFilterId);
|
2015-11-21 04:41:40 +01:00
|
|
|
if(this.popupFilters){
|
2015-05-30 14:23:33 +02:00
|
|
|
Event.cancel(_ev);
|
|
|
|
Event.stop(_ev);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-07-19 14:43:18 +02:00
|
|
|
// TODO: hack to prevent ezEditTable enter key event hijaking.
|
|
|
|
// Needs to be fixed in the vendor's library
|
|
|
|
if(this.hasExtension('advancedGrid')){
|
|
|
|
var advGrid = this.extension('advancedGrid');
|
|
|
|
var ezEditTable = advGrid._ezEditTable;
|
|
|
|
if(advGrid.cfg.editable){
|
|
|
|
ezEditTable.Editable.Remove();
|
|
|
|
}
|
|
|
|
if(advGrid.cfg.selection){
|
|
|
|
ezEditTable.Selection.Remove();
|
|
|
|
}
|
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
},
|
2015-06-27 16:47:13 +02:00
|
|
|
// set focused drop-down filter as active
|
2015-05-23 10:55:51 +02:00
|
|
|
onSlcFocus(e) {
|
2015-05-30 14:23:33 +02:00
|
|
|
let _ev = e || global.event;
|
2015-06-04 15:04:38 +02:00
|
|
|
let elm = Event.target(_ev);
|
|
|
|
this.activeFilterId = elm.getAttribute('id');
|
|
|
|
this.activeFlt = Dom.id(this.activeFilterId);
|
2015-02-22 12:46:05 +01:00
|
|
|
// select is populated when element has focus
|
2015-09-20 10:42:00 +02:00
|
|
|
if(this.loadFltOnDemand && elm.getAttribute('filled') === '0'){
|
2015-06-04 15:04:38 +02:00
|
|
|
let ct = elm.getAttribute('ct');
|
2015-06-07 17:31:15 +02:00
|
|
|
this.Mod.dropdown._build(ct);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-11-21 04:41:40 +01:00
|
|
|
if(this.popupFilters){
|
2015-05-30 14:23:33 +02:00
|
|
|
Event.cancel(_ev);
|
|
|
|
Event.stop(_ev);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
},
|
2015-06-27 16:47:13 +02:00
|
|
|
// filter columns on drop-down filter change
|
2015-06-05 09:46:48 +02:00
|
|
|
onSlcChange(e) {
|
2015-06-04 15:04:38 +02:00
|
|
|
if(!this.activeFlt){ return; }
|
2015-05-30 14:23:33 +02:00
|
|
|
let _ev = e || global.event;
|
2015-11-21 04:41:40 +01:00
|
|
|
if(this.popupFilters){ Event.stop(_ev); }
|
2015-06-04 15:04:38 +02:00
|
|
|
if(this.onSlcChange){ this.filter(); }
|
2015-02-22 12:46:05 +01:00
|
|
|
},
|
2015-06-27 16:47:13 +02:00
|
|
|
// fill checklist filter on click if required
|
2015-06-04 15:04:38 +02:00
|
|
|
onCheckListClick(e) {
|
|
|
|
let _ev = e || global.event;
|
|
|
|
let elm = Event.target(_ev);
|
2015-09-20 10:42:00 +02:00
|
|
|
if(this.loadFltOnDemand && elm.getAttribute('filled') === '0'){
|
2015-06-04 15:04:38 +02:00
|
|
|
let ct = elm.getAttribute('ct');
|
2015-06-07 17:31:15 +02:00
|
|
|
this.Mod.checkList._build(ct);
|
|
|
|
this.Mod.checkList.checkListDiv[ct].onclick = null;
|
|
|
|
this.Mod.checkList.checkListDiv[ct].title = '';
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-04-06 11:21:49 +02:00
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2015-05-23 10:55:51 +02:00
|
|
|
/**
|
|
|
|
* Initialise filtering grid bar behaviours and layout
|
|
|
|
*
|
|
|
|
* TODO: decompose in smaller methods
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
init(){
|
|
|
|
if(this._hasGrid){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(!this.tbl){
|
2015-05-30 14:23:33 +02:00
|
|
|
this.tbl = Dom.id(this.id);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
if(this.gridLayout){
|
|
|
|
this.refRow = this.startRow===null ? 0 : this.startRow;
|
|
|
|
}
|
2015-11-21 04:41:40 +01:00
|
|
|
if(this.popupFilters &&
|
2015-02-22 12:46:05 +01:00
|
|
|
((this.filtersRowIndex === 0 && this.headersRow === 1) ||
|
|
|
|
this.gridLayout)){
|
|
|
|
this.headersRow = 0;
|
|
|
|
}
|
2015-06-07 17:31:15 +02:00
|
|
|
|
|
|
|
let Mod = this.Mod;
|
2015-06-05 15:10:25 +02:00
|
|
|
let n = this.singleSearchFlt ? 1 : this.nbCells,
|
2015-02-22 12:46:05 +01:00
|
|
|
inpclass;
|
|
|
|
|
|
|
|
//loads stylesheet if not imported
|
2015-05-15 16:26:21 +02:00
|
|
|
this.import(this.stylesheetId, this.stylesheet, null, 'link');
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
//loads theme
|
2015-04-27 16:26:59 +02:00
|
|
|
if(this.hasThemes){ this._loadThemes(); }
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
if(this.rememberGridValues || this.rememberPageNb ||
|
|
|
|
this.rememberPageLen){
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.store = new Store(this);
|
2015-12-28 07:53:03 +01:00
|
|
|
Mod.store.init();
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if(this.gridLayout){
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.gridLayout = new GridLayout(this);
|
|
|
|
Mod.gridLayout.init();
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if(this.loader){
|
2015-06-07 17:31:15 +02:00
|
|
|
if(!Mod.loader){
|
|
|
|
Mod.loader = new Loader(this);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-12-06 12:33:11 +01:00
|
|
|
Mod.loader.init();
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if(this.highlightKeywords){
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.highlightKeyword = new HighlightKeyword(this);
|
2015-12-29 07:13:08 +01:00
|
|
|
Mod.highlightKeyword.init();
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-11-21 04:41:40 +01:00
|
|
|
if(this.popupFilters){
|
2015-06-07 17:31:15 +02:00
|
|
|
if(!Mod.popupFilter){
|
|
|
|
Mod.popupFilter = new PopupFilter(this);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.popupFilter.init();
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//filters grid is not generated
|
|
|
|
if(!this.fltGrid){
|
|
|
|
this.refRow = this.refRow-1;
|
|
|
|
if(this.gridLayout){
|
|
|
|
this.refRow = 0;
|
|
|
|
}
|
|
|
|
this.nbFilterableRows = this.getRowsNb();
|
|
|
|
this.nbVisibleRows = this.nbFilterableRows;
|
|
|
|
this.nbRows = this.nbFilterableRows + this.refRow;
|
|
|
|
} else {
|
|
|
|
if(this.isFirstLoad){
|
2015-05-30 14:23:33 +02:00
|
|
|
let fltrow;
|
2015-02-22 12:46:05 +01:00
|
|
|
if(!this.gridLayout){
|
2015-05-30 14:23:33 +02:00
|
|
|
let thead = Dom.tag(this.tbl, 'thead');
|
2015-02-22 12:46:05 +01:00
|
|
|
if(thead.length > 0){
|
|
|
|
fltrow = thead[0].insertRow(this.filtersRowIndex);
|
|
|
|
} else {
|
|
|
|
fltrow = this.tbl.insertRow(this.filtersRowIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(this.headersRow > 1 &&
|
|
|
|
this.filtersRowIndex <= this.headersRow &&
|
2015-11-21 04:41:40 +01:00
|
|
|
!this.popupFilters){
|
2015-02-22 12:46:05 +01:00
|
|
|
this.headersRow++;
|
|
|
|
}
|
2015-11-21 04:41:40 +01:00
|
|
|
if(this.popupFilters){
|
2015-02-22 12:46:05 +01:00
|
|
|
this.headersRow++;
|
|
|
|
}
|
|
|
|
|
|
|
|
fltrow.className = this.fltsRowCssClass;
|
2015-10-11 02:36:28 +02:00
|
|
|
|
2015-11-21 04:41:40 +01:00
|
|
|
if(this.isExternalFlt || this.popupFilters){
|
2015-02-22 12:46:05 +01:00
|
|
|
fltrow.style.display = 'none';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.nbFilterableRows = this.getRowsNb();
|
|
|
|
this.nbVisibleRows = this.nbFilterableRows;
|
|
|
|
this.nbRows = this.tbl.rows.length;
|
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let i=0; i<n; i++){// this loop adds filters
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-11-21 04:41:40 +01:00
|
|
|
if(this.popupFilters){
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.popupFilter.build(i);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
let fltcell = Dom.create(this.fltCellTag),
|
2015-06-05 09:46:48 +02:00
|
|
|
col = this.getFilterType(i),
|
2015-02-22 12:46:05 +01:00
|
|
|
externalFltTgtId =
|
|
|
|
this.isExternalFlt && this.externalFltTgtIds ?
|
|
|
|
this.externalFltTgtIds[i] : null;
|
|
|
|
|
|
|
|
if(this.singleSearchFlt){
|
|
|
|
fltcell.colSpan = this.nbCells;
|
|
|
|
}
|
|
|
|
if(!this.gridLayout){
|
|
|
|
fltrow.appendChild(fltcell);
|
|
|
|
}
|
|
|
|
inpclass = (i==n-1 && this.displayBtn) ?
|
|
|
|
this.fltSmallCssClass : this.fltCssClass;
|
|
|
|
|
|
|
|
//only 1 input for single search
|
|
|
|
if(this.singleSearchFlt){
|
|
|
|
col = this.fltTypeInp;
|
|
|
|
inpclass = this.singleFltCssClass;
|
|
|
|
}
|
|
|
|
|
|
|
|
//drop-down filters
|
|
|
|
if(col===this.fltTypeSlc || col===this.fltTypeMulti){
|
2015-06-07 17:31:15 +02:00
|
|
|
if(!Mod.dropdown){
|
|
|
|
Mod.dropdown = new Dropdown(this);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-06-07 17:31:15 +02:00
|
|
|
let dropdown = Mod.dropdown;
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
let slc = Dom.create(this.fltTypeSlc,
|
2015-02-22 12:46:05 +01:00
|
|
|
['id', this.prfxFlt+i+'_'+this.id],
|
|
|
|
['ct', i], ['filled', '0']
|
|
|
|
);
|
|
|
|
|
|
|
|
if(col===this.fltTypeMulti){
|
|
|
|
slc.multiple = this.fltTypeMulti;
|
|
|
|
slc.title = dropdown.multipleSlcTooltip;
|
|
|
|
}
|
2015-12-05 14:37:59 +01:00
|
|
|
slc.className = Str.lower(col) === this.fltTypeSlc ?
|
|
|
|
inpclass : this.fltMultiCssClass;
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
//filter is appended in desired external element
|
|
|
|
if(externalFltTgtId){
|
2015-05-30 14:23:33 +02:00
|
|
|
Dom.id(externalFltTgtId).appendChild(slc);
|
2015-02-22 12:46:05 +01:00
|
|
|
this.externalFltEls.push(slc);
|
|
|
|
} else {
|
|
|
|
fltcell.appendChild(slc);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.fltIds.push(this.prfxFlt+i+'_'+this.id);
|
|
|
|
|
2015-09-20 10:42:00 +02:00
|
|
|
if(!this.loadFltOnDemand){
|
2015-02-22 12:46:05 +01:00
|
|
|
dropdown._build(i);
|
|
|
|
}
|
|
|
|
|
2015-06-04 15:04:38 +02:00
|
|
|
Event.add(slc, 'keypress',
|
|
|
|
this.Evt.detectKey.bind(this));
|
|
|
|
Event.add(slc, 'change',
|
|
|
|
this.Evt.onSlcChange.bind(this));
|
|
|
|
Event.add(slc, 'focus', this.Evt.onSlcFocus.bind(this));
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
//1st option is created here since dropdown.build isn't
|
|
|
|
//invoked
|
2015-09-20 10:42:00 +02:00
|
|
|
if(this.loadFltOnDemand){
|
2015-05-30 14:23:33 +02:00
|
|
|
let opt0 = Dom.createOpt(this.displayAllText, '');
|
2015-02-22 12:46:05 +01:00
|
|
|
slc.appendChild(opt0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// checklist
|
|
|
|
else if(col===this.fltTypeCheckList){
|
2015-05-30 14:23:33 +02:00
|
|
|
let checkList;
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.checkList = new CheckList(this);
|
|
|
|
checkList = Mod.checkList;
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
let divCont = Dom.create('div',
|
2015-04-12 09:52:19 +02:00
|
|
|
['id', checkList.prfxCheckListDiv+i+'_'+this.id],
|
|
|
|
['ct', i], ['filled', '0']);
|
|
|
|
divCont.className = checkList.checkListDivCssClass;
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
//filter is appended in desired element
|
|
|
|
if(externalFltTgtId){
|
2015-05-30 14:23:33 +02:00
|
|
|
Dom.id(externalFltTgtId).appendChild(divCont);
|
2015-02-22 12:46:05 +01:00
|
|
|
this.externalFltEls.push(divCont);
|
|
|
|
} else {
|
|
|
|
fltcell.appendChild(divCont);
|
|
|
|
}
|
|
|
|
|
2015-04-12 09:52:19 +02:00
|
|
|
checkList.checkListDiv[i] = divCont;
|
2015-02-22 12:46:05 +01:00
|
|
|
this.fltIds.push(this.prfxFlt+i+'_'+this.id);
|
2015-09-20 10:42:00 +02:00
|
|
|
if(!this.loadFltOnDemand){
|
2015-04-12 09:52:19 +02:00
|
|
|
checkList._build(i);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-09-20 10:42:00 +02:00
|
|
|
if(this.loadFltOnDemand){
|
2015-06-04 15:04:38 +02:00
|
|
|
Event.add(divCont, 'click',
|
|
|
|
this.Evt.onCheckListClick.bind(this));
|
2015-02-22 12:46:05 +01:00
|
|
|
divCont.appendChild(
|
2015-05-30 14:23:33 +02:00
|
|
|
Dom.text(checkList.activateCheckListTxt));
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else{
|
|
|
|
//show/hide input
|
2015-05-30 14:23:33 +02:00
|
|
|
let inptype = col===this.fltTypeInp ? 'text' : 'hidden';
|
|
|
|
let inp = Dom.create(this.fltTypeInp,
|
2015-02-22 12:46:05 +01:00
|
|
|
['id',this.prfxFlt+i+'_'+this.id],
|
2015-07-04 14:37:27 +02:00
|
|
|
['type',inptype], ['ct',i]);
|
2015-02-22 12:46:05 +01:00
|
|
|
if(inptype!=='hidden' && this.watermark){
|
|
|
|
inp.setAttribute(
|
|
|
|
'placeholder',
|
|
|
|
this.isWatermarkArray ?
|
2015-04-24 12:38:20 +02:00
|
|
|
(this.watermark[i] || '') : this.watermark
|
2015-02-22 12:46:05 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
inp.className = inpclass;
|
2015-06-04 15:04:38 +02:00
|
|
|
Event.add(inp, 'focus', this.Evt.onInpFocus.bind(this));
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
//filter is appended in desired element
|
|
|
|
if(externalFltTgtId){
|
2015-05-30 14:23:33 +02:00
|
|
|
Dom.id(externalFltTgtId).appendChild(inp);
|
2015-02-22 12:46:05 +01:00
|
|
|
this.externalFltEls.push(inp);
|
|
|
|
} else {
|
|
|
|
fltcell.appendChild(inp);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.fltIds.push(this.prfxFlt+i+'_'+this.id);
|
|
|
|
|
2015-06-04 15:04:38 +02:00
|
|
|
Event.add(inp, 'keypress',
|
|
|
|
this.Evt.detectKey.bind(this));
|
|
|
|
Event.add(inp, 'keydown',
|
|
|
|
this.Evt.onKeyDown.bind(this));
|
|
|
|
Event.add(inp, 'keyup', this.Evt.onKeyUp.bind(this));
|
|
|
|
Event.add(inp, 'blur', this.Evt.onInpBlur.bind(this));
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
if(this.rememberGridValues){
|
2015-06-07 17:31:15 +02:00
|
|
|
let flts_values = this.Mod.store.getFilterValues(
|
2015-02-22 12:46:05 +01:00
|
|
|
this.fltsValuesCookie);
|
|
|
|
if(flts_values[i]!=' '){
|
2015-05-24 11:16:09 +02:00
|
|
|
this.setFilterValue(i, flts_values[i], false);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// this adds submit button
|
|
|
|
if(i==n-1 && this.displayBtn){
|
2015-05-30 14:23:33 +02:00
|
|
|
let btn = Dom.create(this.fltTypeInp,
|
2015-11-29 01:46:20 +01:00
|
|
|
['id', this.prfxValButton+i+'_'+this.id],
|
|
|
|
['type', 'button'], ['value', this.btnText]);
|
2015-02-22 12:46:05 +01:00
|
|
|
btn.className = this.btnCssClass;
|
|
|
|
|
|
|
|
//filter is appended in desired element
|
|
|
|
if(externalFltTgtId){
|
2015-05-30 14:23:33 +02:00
|
|
|
Dom.id(externalFltTgtId).appendChild(btn);
|
2015-02-22 12:46:05 +01:00
|
|
|
} else{
|
|
|
|
fltcell.appendChild(btn);
|
|
|
|
}
|
|
|
|
|
2015-11-29 01:46:20 +01:00
|
|
|
Event.add(btn, 'click', ()=> this.filter());
|
2015-02-22 12:46:05 +01:00
|
|
|
}//if
|
|
|
|
|
|
|
|
}// for i
|
|
|
|
|
|
|
|
} else {
|
|
|
|
this._resetGrid();
|
|
|
|
}//if isFirstLoad
|
|
|
|
|
|
|
|
}//if this.fltGrid
|
|
|
|
|
2015-12-08 12:53:12 +01:00
|
|
|
/* Features */
|
2015-08-01 09:45:29 +02:00
|
|
|
if(this.hasVisibleRows){
|
2015-12-28 07:53:03 +01:00
|
|
|
this.emitter.on('after-filtering', ()=> this.enforceVisibility());
|
2015-08-01 09:45:29 +02:00
|
|
|
this.enforceVisibility();
|
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
if(this.rowsCounter){
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.rowsCounter = new RowsCounter(this);
|
|
|
|
Mod.rowsCounter.init();
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
if(this.statusBar){
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.statusBar = new StatusBar(this);
|
|
|
|
Mod.statusBar.init();
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-06-13 11:03:33 +02:00
|
|
|
if(this.paging || Mod.paging){
|
|
|
|
if(!Mod.paging){
|
|
|
|
Mod.paging = new Paging(this);
|
|
|
|
Mod.paging.init();
|
|
|
|
}
|
2015-11-21 08:52:33 +01:00
|
|
|
Mod.paging.reset();
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
if(this.btnReset){
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.clearButton = new ClearButton(this);
|
|
|
|
Mod.clearButton.init();
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-11-21 04:41:40 +01:00
|
|
|
if(this.help){
|
2015-06-07 17:31:15 +02:00
|
|
|
if(!Mod.help){
|
|
|
|
Mod.help = new Help(this);
|
2015-06-05 15:10:25 +02:00
|
|
|
}
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.help.init();
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-05-28 15:44:23 +02:00
|
|
|
if(this.hasColWidths && !this.gridLayout){
|
2015-02-22 12:46:05 +01:00
|
|
|
this.setColWidths();
|
|
|
|
}
|
2015-11-14 16:14:13 +01:00
|
|
|
if(this.alternateRows){
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.alternateRows = new AlternateRows(this);
|
|
|
|
Mod.alternateRows.init();
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-12-08 13:13:18 +01:00
|
|
|
if(this.noResults){
|
2015-12-08 12:53:12 +01:00
|
|
|
if(!Mod.noResults){
|
|
|
|
Mod.noResults = new NoResults(this);
|
|
|
|
}
|
|
|
|
Mod.noResults.init();
|
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
this.isFirstLoad = false;
|
|
|
|
this._hasGrid = true;
|
|
|
|
|
|
|
|
if(this.rememberGridValues || this.rememberPageLen ||
|
|
|
|
this.rememberPageNb){
|
|
|
|
this.resetValues();
|
|
|
|
}
|
|
|
|
|
|
|
|
//TF css class is added to table
|
|
|
|
if(!this.gridLayout){
|
2015-05-30 14:23:33 +02:00
|
|
|
Dom.addClass(this.tbl, this.prfxTf);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Loads extensions */
|
|
|
|
if(this.hasExtensions){
|
2015-05-10 13:12:31 +02:00
|
|
|
this.initExtensions();
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-12-30 06:56:44 +01:00
|
|
|
// Subscribe to events
|
|
|
|
if(this.markActiveColumns){
|
|
|
|
this.emitter.on('before-filtering', ()=> this.clearActiveColumns());
|
2016-01-02 04:43:00 +01:00
|
|
|
this.emitter.on('cell-processed',
|
|
|
|
(tf, colIndex)=> this.markActiveColumn(colIndex));
|
2015-12-30 06:56:44 +01:00
|
|
|
}
|
2015-12-28 07:53:03 +01:00
|
|
|
if(this.linkedFilters){
|
|
|
|
this.emitter.on('after-filtering', ()=> this.linkFilters());
|
|
|
|
}
|
|
|
|
|
2015-02-22 12:46:05 +01:00
|
|
|
if(this.onFiltersLoaded){
|
|
|
|
this.onFiltersLoaded.call(null, this);
|
|
|
|
}
|
2015-12-27 12:08:14 +01:00
|
|
|
|
|
|
|
this.emitter.emit('initialized', this);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-06-05 09:46:48 +02:00
|
|
|
/**
|
|
|
|
* Manages state messages
|
|
|
|
* @param {String} evt Event name
|
|
|
|
* @param {Object} cfg Config object
|
|
|
|
*/
|
2015-05-16 11:58:56 +02:00
|
|
|
EvtManager(evt,
|
|
|
|
cfg={ slcIndex: null, slcExternal: false, slcId: null, pgIndex: null }){
|
2015-05-30 14:23:33 +02:00
|
|
|
let slcIndex = cfg.slcIndex;
|
|
|
|
let slcExternal = cfg.slcExternal;
|
|
|
|
let slcId = cfg.slcId;
|
|
|
|
let pgIndex = cfg.pgIndex;
|
2015-06-07 17:31:15 +02:00
|
|
|
let cpt = this.Mod;
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
function efx(){
|
2015-05-16 11:58:56 +02:00
|
|
|
/*jshint validthis:true */
|
2015-05-30 14:23:33 +02:00
|
|
|
let ev = this.Evt.name;
|
2015-05-16 11:58:56 +02:00
|
|
|
|
2015-02-22 12:46:05 +01:00
|
|
|
switch(evt){
|
2015-05-16 11:58:56 +02:00
|
|
|
case ev.filter:
|
|
|
|
this._filter();
|
2015-02-22 12:46:05 +01:00
|
|
|
break;
|
2015-05-16 11:58:56 +02:00
|
|
|
case ev.dropdown:
|
|
|
|
if(this.linkedFilters){
|
|
|
|
cpt.dropdown._build(slcIndex, true);
|
2015-02-22 12:46:05 +01:00
|
|
|
} else {
|
2015-05-16 11:58:56 +02:00
|
|
|
cpt.dropdown._build(
|
2015-02-22 12:46:05 +01:00
|
|
|
slcIndex, false, slcExternal, slcId);
|
|
|
|
}
|
|
|
|
break;
|
2015-05-16 11:58:56 +02:00
|
|
|
case ev.checklist:
|
|
|
|
cpt.checkList._build(slcIndex, slcExternal, slcId);
|
2015-02-22 12:46:05 +01:00
|
|
|
break;
|
2015-05-16 11:58:56 +02:00
|
|
|
case ev.changepage:
|
|
|
|
cpt.paging._changePage(pgIndex);
|
2015-02-22 12:46:05 +01:00
|
|
|
break;
|
2015-05-16 11:58:56 +02:00
|
|
|
case ev.clear:
|
|
|
|
this._clearFilters();
|
|
|
|
this._filter();
|
2015-02-22 12:46:05 +01:00
|
|
|
break;
|
2015-05-16 11:58:56 +02:00
|
|
|
case ev.changeresultsperpage:
|
|
|
|
cpt.paging._changeResultsPerPage();
|
2015-02-22 12:46:05 +01:00
|
|
|
break;
|
2015-05-16 11:58:56 +02:00
|
|
|
case ev.resetvalues:
|
|
|
|
this._resetValues();
|
|
|
|
this._filter();
|
2015-02-22 12:46:05 +01:00
|
|
|
break;
|
2015-05-16 11:58:56 +02:00
|
|
|
case ev.resetpage:
|
|
|
|
cpt.paging._resetPage(this.pgNbCookie);
|
2015-02-22 12:46:05 +01:00
|
|
|
break;
|
2015-05-16 11:58:56 +02:00
|
|
|
case ev.resetpagelength:
|
|
|
|
cpt.paging._resetPageLength(this.pgLenCookie);
|
2015-02-22 12:46:05 +01:00
|
|
|
break;
|
2015-05-16 11:58:56 +02:00
|
|
|
case ev.loadextensions:
|
|
|
|
this._loadExtensions();
|
2015-02-22 12:46:05 +01:00
|
|
|
break;
|
2015-05-16 11:58:56 +02:00
|
|
|
case ev.loadthemes:
|
|
|
|
this._loadThemes();
|
2015-02-22 12:46:05 +01:00
|
|
|
break;
|
|
|
|
}
|
2015-05-16 11:58:56 +02:00
|
|
|
if(this.statusBar){
|
|
|
|
cpt.statusBar.message('');
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-05-16 11:58:56 +02:00
|
|
|
if(this.loader){
|
|
|
|
cpt.loader.show('none');
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-10 12:53:20 +02:00
|
|
|
if(!this.loader && !this.statusBar && !this.linkedFilters) {
|
2015-05-16 11:58:56 +02:00
|
|
|
efx.call(this);
|
2015-02-22 12:46:05 +01:00
|
|
|
} else {
|
2015-05-16 11:58:56 +02:00
|
|
|
if(this.loader){
|
|
|
|
cpt.loader.show('');
|
|
|
|
}
|
|
|
|
if(this.statusBar){
|
|
|
|
cpt.statusBar.message(this['msg'+evt]);
|
|
|
|
}
|
|
|
|
global.setTimeout(efx.bind(this), this.execDelay);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-07 17:31:15 +02:00
|
|
|
/**
|
|
|
|
* Return a feature instance for a given name
|
|
|
|
* @param {String} name Name of the feature
|
|
|
|
* @return {Object}
|
|
|
|
*/
|
|
|
|
feature(name){
|
|
|
|
return this.Mod[name];
|
|
|
|
}
|
|
|
|
|
2015-05-23 10:55:51 +02:00
|
|
|
/**
|
|
|
|
* Initialise all the extensions defined in the configuration object
|
|
|
|
*/
|
2015-05-10 13:12:31 +02:00
|
|
|
initExtensions(){
|
2015-05-30 14:23:33 +02:00
|
|
|
let exts = this.extensions;
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let i=0, len=exts.length; i<len; i++){
|
|
|
|
let ext = exts[i];
|
2015-05-28 12:09:34 +02:00
|
|
|
if(!this.ExtRegistry[ext.name]){
|
2015-04-27 16:26:59 +02:00
|
|
|
this.loadExtension(ext);
|
2015-04-19 13:05:33 +02:00
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-23 10:55:51 +02:00
|
|
|
/**
|
|
|
|
* Load an extension module
|
|
|
|
* @param {Object} ext Extension config object
|
|
|
|
*/
|
2015-04-27 16:26:59 +02:00
|
|
|
loadExtension(ext){
|
2015-05-10 13:12:31 +02:00
|
|
|
if(!ext || !ext.name){
|
2015-02-22 12:46:05 +01:00
|
|
|
return;
|
|
|
|
}
|
2015-04-19 13:05:33 +02:00
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
let name = ext.name;
|
|
|
|
let path = ext.path;
|
|
|
|
let modulePath;
|
2015-05-13 12:54:29 +02:00
|
|
|
|
|
|
|
if(name && path){
|
2015-05-15 16:26:21 +02:00
|
|
|
modulePath = ext.path + name;
|
2015-05-13 12:54:29 +02:00
|
|
|
} else {
|
|
|
|
name = name.replace('.js', '');
|
2015-07-04 16:34:07 +02:00
|
|
|
modulePath = 'extensions/{}/{}'.replace(/{}/g, name);
|
2015-05-13 12:54:29 +02:00
|
|
|
}
|
|
|
|
|
2015-10-17 10:49:38 +02:00
|
|
|
// Trick to set config's publicPath dynamically for Webpack...
|
2015-08-19 13:48:38 +02:00
|
|
|
__webpack_public_path__ = this.basePath;
|
|
|
|
|
2015-07-04 16:34:07 +02:00
|
|
|
require(['./' + modulePath], (mod)=> {
|
2015-12-25 15:33:04 +01:00
|
|
|
let inst = new mod.default(this, ext);
|
2015-05-13 12:54:29 +02:00
|
|
|
inst.init();
|
|
|
|
this.ExtRegistry[name] = inst;
|
2015-04-27 16:26:59 +02:00
|
|
|
});
|
|
|
|
}
|
2015-04-19 13:05:33 +02:00
|
|
|
|
2015-06-07 17:31:15 +02:00
|
|
|
/**
|
|
|
|
* Get an extension instance
|
|
|
|
* @param {String} name Name of the extension
|
|
|
|
* @return {Object} Extension instance
|
|
|
|
*/
|
2015-07-03 09:44:25 +02:00
|
|
|
extension(name){
|
2015-06-07 17:31:15 +02:00
|
|
|
return this.ExtRegistry[name];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check passed extension name exists
|
|
|
|
* @param {String} name Name of the extension
|
|
|
|
* @return {Boolean}
|
|
|
|
*/
|
|
|
|
hasExtension(name){
|
2015-06-14 04:44:02 +02:00
|
|
|
return !Types.isEmpty(this.ExtRegistry[name]);
|
2015-06-07 17:31:15 +02:00
|
|
|
}
|
|
|
|
|
2015-05-28 12:09:34 +02:00
|
|
|
/**
|
|
|
|
* Destroy all the extensions defined in the configuration object
|
|
|
|
*/
|
|
|
|
destroyExtensions(){
|
2015-05-30 14:23:33 +02:00
|
|
|
let exts = this.extensions;
|
2015-05-28 12:09:34 +02:00
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let i=0, len=exts.length; i<len; i++){
|
|
|
|
let ext = exts[i];
|
|
|
|
let extInstance = this.ExtRegistry[ext.name];
|
2015-05-28 12:09:34 +02:00
|
|
|
if(extInstance){
|
|
|
|
extInstance.destroy();
|
|
|
|
this.ExtRegistry[ext.name] = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-27 16:26:59 +02:00
|
|
|
loadThemes(){
|
2015-02-22 12:46:05 +01:00
|
|
|
this.EvtManager(this.Evt.name.loadthemes);
|
|
|
|
}
|
|
|
|
|
2015-05-23 10:55:51 +02:00
|
|
|
/**
|
|
|
|
* Load themes defined in the configuration object
|
|
|
|
*/
|
2015-04-27 16:26:59 +02:00
|
|
|
_loadThemes(){
|
2015-05-30 14:23:33 +02:00
|
|
|
let themes = this.themes;
|
2015-02-22 12:46:05 +01:00
|
|
|
//Default theme config
|
|
|
|
if(this.enableDefaultTheme){
|
2015-05-30 14:23:33 +02:00
|
|
|
let defaultTheme = { name: 'default' };
|
2015-05-15 16:26:21 +02:00
|
|
|
this.themes.push(defaultTheme);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
if(Types.isArray(themes)){
|
|
|
|
for(let i=0, len=themes.length; i<len; i++){
|
|
|
|
let theme = themes[i];
|
|
|
|
let name = theme.name;
|
|
|
|
let path = theme.path;
|
2015-06-27 16:47:13 +02:00
|
|
|
let styleId = this.prfxTf + name;
|
2015-05-15 16:26:21 +02:00
|
|
|
if(name && !path){
|
|
|
|
path = this.themesPath + name + '/' + name + '.css';
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-05-15 16:26:21 +02:00
|
|
|
else if(!name && theme.path){
|
|
|
|
name = 'theme{0}'.replace('{0}', i);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!this.isImported(path, 'link')){
|
2015-06-27 16:47:13 +02:00
|
|
|
this.import(styleId, path, null, 'link');
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-27 16:47:13 +02:00
|
|
|
//Some elements need to be overriden for default theme
|
2015-02-22 12:46:05 +01:00
|
|
|
//Reset button
|
|
|
|
this.btnResetText = null;
|
|
|
|
this.btnResetHtml = '<input type="button" value="" class="' +
|
|
|
|
this.btnResetCssClass+'" title="Clear filters" />';
|
|
|
|
|
|
|
|
//Paging buttons
|
|
|
|
this.btnPrevPageHtml = '<input type="button" value="" class="' +
|
|
|
|
this.btnPageCssClass+' previousPage" title="Previous page" />';
|
|
|
|
this.btnNextPageHtml = '<input type="button" value="" class="' +
|
|
|
|
this.btnPageCssClass+' nextPage" title="Next page" />';
|
|
|
|
this.btnFirstPageHtml = '<input type="button" value="" class="' +
|
|
|
|
this.btnPageCssClass+' firstPage" title="First page" />';
|
|
|
|
this.btnLastPageHtml = '<input type="button" value="" class="' +
|
|
|
|
this.btnPageCssClass+' lastPage" title="Last page" />';
|
|
|
|
|
|
|
|
//Loader
|
|
|
|
this.loader = true;
|
|
|
|
this.loaderHtml = '<div class="defaultLoader"></div>';
|
|
|
|
this.loaderText = null;
|
|
|
|
}
|
|
|
|
|
2015-06-27 16:47:13 +02:00
|
|
|
/**
|
|
|
|
* Return stylesheet DOM element for a given theme name
|
|
|
|
* @return {DOMElement} stylesheet element
|
|
|
|
*/
|
|
|
|
getStylesheet(name='default'){
|
|
|
|
return Dom.id(this.prfxTf + name);
|
|
|
|
}
|
|
|
|
|
2015-05-23 10:55:51 +02:00
|
|
|
/**
|
|
|
|
* Destroy filter grid
|
|
|
|
*/
|
|
|
|
destroy(){
|
|
|
|
if(!this._hasGrid){
|
|
|
|
return;
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
let rows = this.tbl.rows,
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod = this.Mod;
|
2015-06-06 12:06:15 +02:00
|
|
|
|
2015-11-21 08:31:32 +01:00
|
|
|
this._clearFilters();
|
|
|
|
|
2015-11-21 04:41:40 +01:00
|
|
|
if(this.isExternalFlt && !this.popupFilters){
|
2015-05-23 10:55:51 +02:00
|
|
|
this.removeExternalFlts();
|
|
|
|
}
|
|
|
|
if(this.infDiv){
|
|
|
|
this.removeToolbar();
|
|
|
|
}
|
|
|
|
if(this.highlightKeywords){
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.highlightKeyword.unhighlightAll();
|
2015-05-23 10:55:51 +02:00
|
|
|
}
|
|
|
|
if(this.markActiveColumns){
|
|
|
|
this.clearActiveColumns();
|
2015-12-30 06:56:44 +01:00
|
|
|
this.emitter.off('before-filtering',
|
|
|
|
()=> this.clearActiveColumns());
|
2016-01-02 04:43:00 +01:00
|
|
|
this.emitter.off('cell-processed',
|
|
|
|
(tf, colIndex)=> this.markActiveColumn(colIndex));
|
2015-05-23 10:55:51 +02:00
|
|
|
}
|
2015-05-28 12:09:34 +02:00
|
|
|
if(this.hasExtensions){
|
|
|
|
this.destroyExtensions();
|
2015-05-23 10:55:51 +02:00
|
|
|
}
|
2015-05-28 12:09:34 +02:00
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let j=this.refRow; j<this.nbRows; j++){
|
2015-11-21 08:31:32 +01:00
|
|
|
// validate row
|
|
|
|
this.validateRow(j, true);
|
2015-05-23 10:55:51 +02:00
|
|
|
|
|
|
|
//removes alternating colors
|
2015-11-14 16:14:13 +01:00
|
|
|
if(this.alternateRows){
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.alternateRows.removeRowBg(j);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-23 10:55:51 +02:00
|
|
|
}//for j
|
|
|
|
|
|
|
|
if(this.fltGrid && !this.gridLayout){
|
|
|
|
this.fltGridEl = rows[this.filtersRowIndex];
|
|
|
|
this.tbl.deleteRow(this.filtersRowIndex);
|
|
|
|
}
|
2015-06-06 12:06:15 +02:00
|
|
|
|
2015-06-27 16:47:13 +02:00
|
|
|
// Destroy modules
|
2015-12-28 07:53:03 +01:00
|
|
|
Object.keys(Mod).forEach(function(key){
|
2015-06-07 17:31:15 +02:00
|
|
|
var feature = Mod[key];
|
2015-06-05 15:10:25 +02:00
|
|
|
if(feature && Types.isFn(feature.destroy)){
|
|
|
|
feature.destroy();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-12-28 07:53:03 +01:00
|
|
|
// unsubscribe to events
|
|
|
|
if(this.hasVisibleRows){
|
|
|
|
this.emitter.off('after-filtering', ()=> this.enforceVisibility());
|
|
|
|
}
|
|
|
|
if(this.linkedFilters){
|
|
|
|
this.emitter.off('after-filtering', ()=> this.linkFilters());
|
|
|
|
}
|
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
Dom.removeClass(this.tbl, this.prfxTf);
|
2015-11-21 08:31:32 +01:00
|
|
|
this.nbHiddenRows = 0;
|
2015-12-31 02:56:50 +01:00
|
|
|
this.validRowsIndex = [];
|
2015-05-23 10:55:51 +02:00
|
|
|
this.activeFlt = null;
|
|
|
|
this._hasGrid = false;
|
|
|
|
this.tbl = null;
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-23 10:55:51 +02:00
|
|
|
/**
|
|
|
|
* Generate container element for paging, reset button, rows counter etc.
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
setToolbar(){
|
2015-05-16 11:58:56 +02:00
|
|
|
if(this.infDiv){
|
2015-02-22 12:46:05 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*** container div ***/
|
2015-05-30 14:23:33 +02:00
|
|
|
let infdiv = Dom.create('div', ['id', this.prfxInfDiv+this.id]);
|
2015-02-22 12:46:05 +01:00
|
|
|
infdiv.className = this.infDivCssClass;
|
|
|
|
|
|
|
|
//custom container
|
|
|
|
if(this.toolBarTgtId){
|
2015-05-30 14:23:33 +02:00
|
|
|
Dom.id(this.toolBarTgtId).appendChild(infdiv);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//grid-layout
|
|
|
|
else if(this.gridLayout){
|
2015-06-07 17:31:15 +02:00
|
|
|
let gridLayout = this.Mod.gridLayout;
|
2015-04-24 12:38:20 +02:00
|
|
|
gridLayout.tblMainCont.appendChild(infdiv);
|
|
|
|
infdiv.className = gridLayout.gridInfDivCssClass;
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//default location: just above the table
|
|
|
|
else{
|
2015-06-05 15:10:25 +02:00
|
|
|
var cont = Dom.create('caption');
|
|
|
|
cont.appendChild(infdiv);
|
|
|
|
this.tbl.insertBefore(cont, this.tbl.firstChild);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
this.infDiv = Dom.id(this.prfxInfDiv+this.id);
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
/*** left div containing rows # displayer ***/
|
2015-05-30 14:23:33 +02:00
|
|
|
let ldiv = Dom.create('div', ['id', this.prfxLDiv+this.id]);
|
2015-02-22 12:46:05 +01:00
|
|
|
ldiv.className = this.lDivCssClass;
|
|
|
|
infdiv.appendChild(ldiv);
|
2015-05-30 14:23:33 +02:00
|
|
|
this.lDiv = Dom.id(this.prfxLDiv+this.id);
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
/*** right div containing reset button
|
|
|
|
+ nb results per page select ***/
|
2015-05-30 14:23:33 +02:00
|
|
|
let rdiv = Dom.create('div', ['id', this.prfxRDiv+this.id]);
|
2015-02-22 12:46:05 +01:00
|
|
|
rdiv.className = this.rDivCssClass;
|
|
|
|
infdiv.appendChild(rdiv);
|
2015-05-30 14:23:33 +02:00
|
|
|
this.rDiv = Dom.id(this.prfxRDiv+this.id);
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
/*** mid div containing paging elements ***/
|
2015-05-30 14:23:33 +02:00
|
|
|
let mdiv = Dom.create('div', ['id', this.prfxMDiv+this.id]);
|
2015-02-22 12:46:05 +01:00
|
|
|
mdiv.className = this.mDivCssClass;
|
|
|
|
infdiv.appendChild(mdiv);
|
2015-05-30 14:23:33 +02:00
|
|
|
this.mDiv = Dom.id(this.prfxMDiv+this.id);
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-06-05 15:10:25 +02:00
|
|
|
// Enable help instructions by default if topbar is generated and not
|
|
|
|
// explicitely set to false
|
2015-11-21 04:41:40 +01:00
|
|
|
if(Types.isUndef(this.help)){
|
2015-06-07 17:31:15 +02:00
|
|
|
if(!this.Mod.help){
|
|
|
|
this.Mod.help = new Help(this);
|
2015-05-28 15:44:23 +02:00
|
|
|
}
|
2015-06-07 17:31:15 +02:00
|
|
|
this.Mod.help.init();
|
2015-11-21 04:41:40 +01:00
|
|
|
this.help = true;
|
2015-05-28 15:44:23 +02:00
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-23 10:55:51 +02:00
|
|
|
/**
|
|
|
|
* Remove toolbar container element
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
removeToolbar(){
|
|
|
|
if(!this.infDiv){
|
|
|
|
return;
|
|
|
|
}
|
2015-12-05 14:37:59 +01:00
|
|
|
Dom.remove(this.infDiv);
|
2015-02-22 12:46:05 +01:00
|
|
|
this.infDiv = null;
|
2015-06-06 12:06:15 +02:00
|
|
|
|
|
|
|
let tbl = this.tbl;
|
|
|
|
let captions = Dom.tag(tbl, 'caption');
|
|
|
|
if(captions.length > 0){
|
|
|
|
[].forEach.call(captions, function(elm) {
|
|
|
|
tbl.removeChild(elm);
|
|
|
|
});
|
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-23 10:55:51 +02:00
|
|
|
/**
|
|
|
|
* Remove all the external column filters
|
|
|
|
*/
|
2015-03-01 11:44:39 +01:00
|
|
|
removeExternalFlts(){
|
2015-05-23 10:55:51 +02:00
|
|
|
if(!this.isExternalFlt || !this.externalFltTgtIds){
|
2015-02-22 12:46:05 +01:00
|
|
|
return;
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
let ids = this.externalFltTgtIds,
|
2015-05-23 10:55:51 +02:00
|
|
|
len = ids.length;
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let ct=0; ct<len; ct++){
|
|
|
|
let externalFltTgtId = ids[ct],
|
|
|
|
externalFlt = Dom.id(externalFltTgtId);
|
2015-02-22 12:46:05 +01:00
|
|
|
if(externalFlt){
|
|
|
|
externalFlt.innerHTML = '';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-02 09:33:16 +02:00
|
|
|
/**
|
|
|
|
* Check if given column implements a filter with custom options
|
|
|
|
* @param {Number} colIndex Column's index
|
|
|
|
* @return {Boolean}
|
|
|
|
*/
|
|
|
|
isCustomOptions(colIndex) {
|
|
|
|
return this.hasCustomOptions &&
|
|
|
|
this.customOptions.cols.indexOf(colIndex) != -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an array [[value0, value1 ...],[text0, text1 ...]] with the
|
|
|
|
* custom options values and texts
|
|
|
|
* @param {Number} colIndex Column's index
|
|
|
|
* @return {Array}
|
|
|
|
*/
|
|
|
|
getCustomOptions(colIndex){
|
2015-09-22 15:04:36 +02:00
|
|
|
if(Types.isEmpty(colIndex) || !this.isCustomOptions(colIndex)){
|
2015-06-02 09:33:16 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let customOptions = this.customOptions;
|
|
|
|
let cols = customOptions.cols;
|
|
|
|
let optTxt = [], optArray = [];
|
2015-10-18 12:55:40 +02:00
|
|
|
let index = cols.indexOf(colIndex);
|
2015-06-02 09:33:16 +02:00
|
|
|
let slcValues = customOptions.values[index];
|
|
|
|
let slcTexts = customOptions.texts[index];
|
|
|
|
let slcSort = customOptions.sorts[index];
|
|
|
|
|
|
|
|
for(let r=0, len=slcValues.length; r<len; r++){
|
|
|
|
optArray.push(slcValues[r]);
|
|
|
|
if(slcTexts[r]){
|
|
|
|
optTxt.push(slcTexts[r]);
|
|
|
|
} else {
|
|
|
|
optTxt.push(slcValues[r]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(slcSort){
|
|
|
|
optArray.sort();
|
|
|
|
optTxt.sort();
|
|
|
|
}
|
|
|
|
return [optArray, optTxt];
|
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
resetValues(){
|
|
|
|
this.EvtManager(this.Evt.name.resetvalues);
|
|
|
|
}
|
|
|
|
|
2015-05-23 10:55:51 +02:00
|
|
|
/**
|
|
|
|
* Reset persisted filter values
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
_resetValues(){
|
2015-09-20 10:42:00 +02:00
|
|
|
//only loadFltOnDemand
|
|
|
|
if(this.rememberGridValues && this.loadFltOnDemand){
|
2015-05-23 10:55:51 +02:00
|
|
|
this._resetGridValues(this.fltsValuesCookie);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-06-07 17:31:15 +02:00
|
|
|
if(this.rememberPageLen && this.Mod.paging){
|
|
|
|
this.Mod.paging.resetPageLength(this.pgLenCookie);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-06-07 17:31:15 +02:00
|
|
|
if(this.rememberPageNb && this.Mod.paging){
|
|
|
|
this.Mod.paging.resetPage(this.pgNbCookie);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-23 10:55:51 +02:00
|
|
|
/**
|
|
|
|
* Reset persisted filter values when load filters on demand feature is
|
|
|
|
* enabled
|
|
|
|
* @param {String} name cookie name storing filter values
|
|
|
|
*/
|
|
|
|
_resetGridValues(name){
|
2015-09-20 10:42:00 +02:00
|
|
|
if(!this.loadFltOnDemand){
|
2015-02-22 12:46:05 +01:00
|
|
|
return;
|
|
|
|
}
|
2015-06-07 17:31:15 +02:00
|
|
|
let fltsValues = this.Mod.store.getFilterValues(name),
|
2015-02-22 12:46:05 +01:00
|
|
|
slcFltsIndex = this.getFiltersByType(this.fltTypeSlc, true),
|
|
|
|
multiFltsIndex = this.getFiltersByType(this.fltTypeMulti, true);
|
|
|
|
|
|
|
|
//if the number of columns is the same as before page reload
|
|
|
|
if(Number(fltsValues[(fltsValues.length-1)]) === this.fltIds.length){
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let i=0; i<(fltsValues.length - 1); i++){
|
2015-02-22 12:46:05 +01:00
|
|
|
if(fltsValues[i]===' '){
|
|
|
|
continue;
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
let s, opt;
|
2015-06-05 15:10:25 +02:00
|
|
|
let fltType = this.getFilterType(i);
|
2015-09-20 10:42:00 +02:00
|
|
|
// if loadFltOnDemand, drop-down needs to contain stored
|
2015-02-22 12:46:05 +01:00
|
|
|
// value(s) for filtering
|
2015-06-05 15:10:25 +02:00
|
|
|
if(fltType===this.fltTypeSlc || fltType===this.fltTypeMulti){
|
2015-05-30 14:23:33 +02:00
|
|
|
let slc = Dom.id( this.fltIds[i] );
|
2015-02-22 12:46:05 +01:00
|
|
|
slc.options[0].selected = false;
|
|
|
|
|
|
|
|
//selects
|
2015-10-19 14:41:09 +02:00
|
|
|
if(slcFltsIndex.indexOf(i) != -1){
|
2015-05-30 14:23:33 +02:00
|
|
|
opt = Dom.createOpt(fltsValues[i],fltsValues[i],true);
|
2015-02-22 12:46:05 +01:00
|
|
|
slc.appendChild(opt);
|
|
|
|
this.hasStoredValues = true;
|
|
|
|
}
|
|
|
|
//multiple select
|
2015-10-19 14:41:09 +02:00
|
|
|
if(multiFltsIndex.indexOf(i) != -1){
|
2015-02-22 12:46:05 +01:00
|
|
|
s = fltsValues[i].split(' '+this.orOperator+' ');
|
2015-06-02 09:45:24 +02:00
|
|
|
for(let j=0, len=s.length; j<len; j++){
|
2015-02-22 12:46:05 +01:00
|
|
|
if(s[j]===''){
|
|
|
|
continue;
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
opt = Dom.createOpt(s[j],s[j],true);
|
2015-02-22 12:46:05 +01:00
|
|
|
slc.appendChild(opt);
|
|
|
|
this.hasStoredValues = true;
|
|
|
|
}
|
|
|
|
}// if multiFltsIndex
|
|
|
|
}
|
2015-06-05 15:10:25 +02:00
|
|
|
else if(fltType===this.fltTypeCheckList){
|
2015-06-07 17:31:15 +02:00
|
|
|
let checkList = this.Mod.checkList;
|
2015-05-30 14:23:33 +02:00
|
|
|
let divChk = checkList.checkListDiv[i];
|
2015-02-22 12:46:05 +01:00
|
|
|
divChk.title = divChk.innerHTML;
|
|
|
|
divChk.innerHTML = '';
|
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
let ul = Dom.create(
|
2015-02-22 12:46:05 +01:00
|
|
|
'ul',['id',this.fltIds[i]],['colIndex',i]);
|
|
|
|
ul.className = checkList.checkListCssClass;
|
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
let li0 = Dom.createCheckItem(
|
2015-02-22 12:46:05 +01:00
|
|
|
this.fltIds[i]+'_0', '', this.displayAllText);
|
|
|
|
li0.className = checkList.checkListItemCssClass;
|
|
|
|
ul.appendChild(li0);
|
|
|
|
|
|
|
|
divChk.appendChild(ul);
|
|
|
|
|
|
|
|
s = fltsValues[i].split(' '+this.orOperator+' ');
|
2015-06-02 09:45:24 +02:00
|
|
|
for(let j=0, len=s.length; j<len; j++){
|
2015-02-22 12:46:05 +01:00
|
|
|
if(s[j]===''){
|
|
|
|
continue;
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
let li = Dom.createCheckItem(
|
2015-02-22 12:46:05 +01:00
|
|
|
this.fltIds[i]+'_'+(j+1), s[j], s[j]);
|
|
|
|
li.className = checkList.checkListItemCssClass;
|
|
|
|
ul.appendChild(li);
|
|
|
|
li.check.checked = true;
|
|
|
|
checkList.setCheckListValues(li.check);
|
|
|
|
this.hasStoredValues = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}//end for
|
|
|
|
|
|
|
|
if(!this.hasStoredValues && this.paging){
|
2015-06-07 17:31:15 +02:00
|
|
|
this.Mod.paging.setPagingInfo();
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}//end if
|
|
|
|
}
|
|
|
|
|
|
|
|
filter(){
|
|
|
|
this.EvtManager(this.Evt.name.filter);
|
|
|
|
}
|
2015-05-23 10:55:51 +02:00
|
|
|
|
|
|
|
/**
|
2015-05-24 11:16:09 +02:00
|
|
|
* Filter the table by retrieving the data from each cell in every single
|
|
|
|
* row and comparing it to the search term for current column. A row is
|
2015-06-05 09:46:48 +02:00
|
|
|
* hidden when all the search terms are not found in inspected row.
|
2015-06-08 12:21:50 +02:00
|
|
|
*
|
|
|
|
* TODO: Reduce complexity of this massive method
|
2015-05-23 10:55:51 +02:00
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
_filter(){
|
|
|
|
if(!this.fltGrid || (!this._hasGrid && !this.isFirstLoad)){
|
|
|
|
return;
|
|
|
|
}
|
2015-05-23 10:55:51 +02:00
|
|
|
//invoke onbefore callback
|
2015-02-22 12:46:05 +01:00
|
|
|
if(this.onBeforeFilter){
|
|
|
|
this.onBeforeFilter.call(null, this);
|
|
|
|
}
|
2015-12-27 12:08:14 +01:00
|
|
|
this.emitter.emit('before-filtering', this);
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
let row = this.tbl.rows,
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod = this.Mod,
|
2015-02-22 12:46:05 +01:00
|
|
|
hiddenrows = 0;
|
2015-05-28 15:44:23 +02:00
|
|
|
|
2015-02-22 12:46:05 +01:00
|
|
|
this.validRowsIndex = [];
|
|
|
|
// search args re-init
|
|
|
|
this.searchArgs = this.getFiltersValue();
|
|
|
|
|
2015-12-05 14:37:59 +01:00
|
|
|
var numCellData, nbFormat;
|
2015-05-31 13:48:29 +02:00
|
|
|
var re_le = new RegExp(this.leOperator),
|
2015-02-22 12:46:05 +01:00
|
|
|
re_ge = new RegExp(this.geOperator),
|
|
|
|
re_l = new RegExp(this.lwOperator),
|
|
|
|
re_g = new RegExp(this.grOperator),
|
|
|
|
re_d = new RegExp(this.dfOperator),
|
2015-05-30 14:23:33 +02:00
|
|
|
re_lk = new RegExp(Str.rgxEsc(this.lkOperator)),
|
2015-02-22 12:46:05 +01:00
|
|
|
re_eq = new RegExp(this.eqOperator),
|
|
|
|
re_st = new RegExp(this.stOperator),
|
|
|
|
re_en = new RegExp(this.enOperator),
|
2015-05-15 12:37:27 +02:00
|
|
|
// re_an = new RegExp(this.anOperator),
|
|
|
|
// re_cr = new RegExp(this.curExp),
|
2015-02-22 12:46:05 +01:00
|
|
|
re_em = this.emOperator,
|
|
|
|
re_nm = this.nmOperator,
|
2015-05-30 14:23:33 +02:00
|
|
|
re_re = new RegExp(Str.rgxEsc(this.rgxOperator));
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
//keyword highlighting
|
|
|
|
function highlight(str, ok, cell){
|
2015-05-23 10:55:51 +02:00
|
|
|
/*jshint validthis:true */
|
|
|
|
if(this.highlightKeywords && ok){
|
2015-05-31 13:48:29 +02:00
|
|
|
str = str.replace(re_lk, '');
|
|
|
|
str = str.replace(re_eq, '');
|
|
|
|
str = str.replace(re_st, '');
|
|
|
|
str = str.replace(re_en, '');
|
2015-05-30 14:23:33 +02:00
|
|
|
let w = str;
|
2015-02-22 12:46:05 +01:00
|
|
|
if(re_le.test(str) || re_ge.test(str) || re_l.test(str) ||
|
|
|
|
re_g.test(str) || re_d.test(str)){
|
2015-05-30 14:23:33 +02:00
|
|
|
w = Dom.getText(cell);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-05-23 10:55:51 +02:00
|
|
|
if(w !== ''){
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.highlightKeyword.highlight(
|
|
|
|
cell, w, Mod.highlightKeyword.highlightCssClass);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//looks for search argument in current row
|
2015-12-05 14:37:59 +01:00
|
|
|
function hasArg(sA, cellData, j){
|
2015-05-23 10:55:51 +02:00
|
|
|
/*jshint validthis:true */
|
2015-05-30 14:23:33 +02:00
|
|
|
let occurence,
|
|
|
|
removeNbFormat = Helpers.removeNbFormat;
|
2015-12-25 02:31:00 +01:00
|
|
|
|
2015-02-22 12:46:05 +01:00
|
|
|
//Search arg operator tests
|
2015-05-30 14:23:33 +02:00
|
|
|
let hasLO = re_l.test(sA),
|
2015-02-22 12:46:05 +01:00
|
|
|
hasLE = re_le.test(sA),
|
|
|
|
hasGR = re_g.test(sA),
|
|
|
|
hasGE = re_ge.test(sA),
|
|
|
|
hasDF = re_d.test(sA),
|
|
|
|
hasEQ = re_eq.test(sA),
|
|
|
|
hasLK = re_lk.test(sA),
|
2015-05-15 12:37:27 +02:00
|
|
|
// hasAN = re_an.test(sA),
|
2015-02-22 12:46:05 +01:00
|
|
|
hasST = re_st.test(sA),
|
|
|
|
hasEN = re_en.test(sA),
|
|
|
|
hasEM = (re_em === sA),
|
|
|
|
hasNM = (re_nm === sA),
|
|
|
|
hasRE = re_re.test(sA);
|
|
|
|
|
|
|
|
//Search arg dates tests
|
2015-12-25 02:31:00 +01:00
|
|
|
let isLDate = hasLO &&
|
|
|
|
DateHelper.isValid(sA.replace(re_l,''), dtType);
|
|
|
|
let isLEDate = hasLE &&
|
|
|
|
DateHelper.isValid(sA.replace(re_le,''), dtType);
|
|
|
|
let isGDate = hasGR &&
|
|
|
|
DateHelper.isValid(sA.replace(re_g,''), dtType);
|
|
|
|
let isGEDate = hasGE &&
|
|
|
|
DateHelper.isValid(sA.replace(re_ge,''), dtType);
|
|
|
|
let isDFDate = hasDF &&
|
|
|
|
DateHelper.isValid(sA.replace(re_d,''), dtType);
|
|
|
|
let isEQDate = hasEQ &&
|
|
|
|
DateHelper.isValid(sA.replace(re_eq,''), dtType);
|
2015-05-30 14:23:33 +02:00
|
|
|
|
|
|
|
let dte1, dte2;
|
2015-02-22 12:46:05 +01:00
|
|
|
//dates
|
2015-12-25 02:31:00 +01:00
|
|
|
if(DateHelper.isValid(cellData, dtType)){
|
|
|
|
dte1 = DateHelper.format(cellData, dtType);
|
2015-02-22 12:46:05 +01:00
|
|
|
// lower date
|
|
|
|
if(isLDate){
|
2015-12-25 02:31:00 +01:00
|
|
|
dte2 = DateHelper.format(sA.replace(re_l,''), dtType);
|
2015-02-22 12:46:05 +01:00
|
|
|
occurence = dte1 < dte2;
|
|
|
|
}
|
|
|
|
// lower equal date
|
|
|
|
else if(isLEDate){
|
2015-12-25 02:31:00 +01:00
|
|
|
dte2 = DateHelper.format(sA.replace(re_le,''), dtType);
|
2015-02-22 12:46:05 +01:00
|
|
|
occurence = dte1 <= dte2;
|
|
|
|
}
|
|
|
|
// greater equal date
|
|
|
|
else if(isGEDate){
|
2015-12-25 02:31:00 +01:00
|
|
|
dte2 = DateHelper.format(sA.replace(re_ge,''), dtType);
|
2015-02-22 12:46:05 +01:00
|
|
|
occurence = dte1 >= dte2;
|
|
|
|
}
|
|
|
|
// greater date
|
|
|
|
else if(isGDate){
|
2015-12-25 02:31:00 +01:00
|
|
|
dte2 = DateHelper.format(sA.replace(re_g,''), dtType);
|
2015-02-22 12:46:05 +01:00
|
|
|
occurence = dte1 > dte2;
|
|
|
|
}
|
|
|
|
// different date
|
|
|
|
else if(isDFDate){
|
2015-12-25 02:31:00 +01:00
|
|
|
dte2 = DateHelper.format(sA.replace(re_d,''), dtType);
|
2015-02-22 12:46:05 +01:00
|
|
|
occurence = dte1.toString() != dte2.toString();
|
|
|
|
}
|
|
|
|
// equal date
|
|
|
|
else if(isEQDate){
|
2015-12-25 02:31:00 +01:00
|
|
|
dte2 = DateHelper.format(sA.replace(re_eq,''), dtType);
|
2015-02-22 12:46:05 +01:00
|
|
|
occurence = dte1.toString() == dte2.toString();
|
|
|
|
}
|
|
|
|
// searched keyword with * operator doesn't have to be a date
|
|
|
|
else if(re_lk.test(sA)){// like date
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = Str.contains(sA.replace(re_lk,''), cellData,
|
|
|
|
false, this.caseSensitive);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-12-25 02:31:00 +01:00
|
|
|
else if(DateHelper.isValid(sA,dtType)){
|
|
|
|
dte2 = DateHelper.format(sA,dtType);
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = dte1.toString() === dte2.toString();
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//empty
|
|
|
|
else if(hasEM){
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = Str.isEmpty(cellData);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//non-empty
|
|
|
|
else if(hasNM){
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = !Str.isEmpty(cellData);
|
2015-12-21 07:25:25 +01:00
|
|
|
} else {
|
|
|
|
occurence = Str.contains(sA, cellData, this.isExactMatch(j),
|
|
|
|
this.caseSensitive);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else{
|
|
|
|
//first numbers need to be formated
|
2015-05-23 10:55:51 +02:00
|
|
|
if(this.hasColNbFormat && this.colNbFormat[j]){
|
2015-12-05 14:37:59 +01:00
|
|
|
numCellData = removeNbFormat(
|
|
|
|
cellData, this.colNbFormat[j]);
|
2015-05-23 10:55:51 +02:00
|
|
|
nbFormat = this.colNbFormat[j];
|
2015-02-22 12:46:05 +01:00
|
|
|
} else {
|
2015-05-23 10:55:51 +02:00
|
|
|
if(this.thousandsSeparator === ',' &&
|
|
|
|
this.decimalSeparator === '.'){
|
2015-12-05 14:37:59 +01:00
|
|
|
numCellData = removeNbFormat(cellData, 'us');
|
2015-02-22 12:46:05 +01:00
|
|
|
nbFormat = 'us';
|
|
|
|
} else {
|
2015-12-05 14:37:59 +01:00
|
|
|
numCellData = removeNbFormat(cellData, 'eu');
|
2015-02-22 12:46:05 +01:00
|
|
|
nbFormat = 'eu';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// first checks if there is any operator (<,>,<=,>=,!,*,=,{,},
|
|
|
|
// rgx:)
|
|
|
|
// lower equal
|
|
|
|
if(hasLE){
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = numCellData <= removeNbFormat(
|
2015-06-05 15:10:25 +02:00
|
|
|
sA.replace(re_le, ''), nbFormat);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//greater equal
|
|
|
|
else if(hasGE){
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = numCellData >= removeNbFormat(
|
2015-06-05 15:10:25 +02:00
|
|
|
sA.replace(re_ge, ''), nbFormat);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//lower
|
|
|
|
else if(hasLO){
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = numCellData < removeNbFormat(
|
2015-06-05 15:10:25 +02:00
|
|
|
sA.replace(re_l, ''), nbFormat);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//greater
|
|
|
|
else if(hasGR){
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = numCellData > removeNbFormat(
|
2015-06-05 15:10:25 +02:00
|
|
|
sA.replace(re_g, ''), nbFormat);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//different
|
|
|
|
else if(hasDF){
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = Str.contains(sA.replace(re_d, ''), cellData,
|
|
|
|
false, this.caseSensitive) ? false : true;
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//like
|
|
|
|
else if(hasLK){
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = Str.contains(sA.replace(re_lk, ''), cellData,
|
|
|
|
false, this.caseSensitive);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//equal
|
|
|
|
else if(hasEQ){
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = Str.contains(sA.replace(re_eq, ''), cellData,
|
|
|
|
true, this.caseSensitive);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//starts with
|
|
|
|
else if(hasST){
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = cellData.indexOf(sA.replace(re_st, '')) === 0 ?
|
2015-02-22 12:46:05 +01:00
|
|
|
true : false;
|
|
|
|
}
|
|
|
|
//ends with
|
|
|
|
else if(hasEN){
|
2015-06-05 15:10:25 +02:00
|
|
|
let searchArg = sA.replace(re_en, '');
|
2015-02-22 12:46:05 +01:00
|
|
|
occurence =
|
2015-12-05 14:37:59 +01:00
|
|
|
cellData.lastIndexOf(searchArg, cellData.length-1) ===
|
|
|
|
(cellData.length-1)-(searchArg.length-1) &&
|
|
|
|
cellData.lastIndexOf(
|
|
|
|
searchArg, cellData.length-1) > -1 ? true : false;
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//empty
|
|
|
|
else if(hasEM){
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = Str.isEmpty(cellData);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//non-empty
|
|
|
|
else if(hasNM){
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = !Str.isEmpty(cellData);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//regexp
|
|
|
|
else if(hasRE){
|
|
|
|
//in case regexp fires an exception
|
|
|
|
try{
|
|
|
|
//operator is removed
|
2015-05-30 14:23:33 +02:00
|
|
|
let srchArg = sA.replace(re_re,'');
|
|
|
|
let rgx = new RegExp(srchArg);
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = rgx.test(cellData);
|
2015-02-22 12:46:05 +01:00
|
|
|
} catch(e) { occurence = false; }
|
2015-10-13 15:15:18 +02:00
|
|
|
} else {
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence = Str.contains(sA, cellData, this.isExactMatch(j),
|
|
|
|
this.caseSensitive);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}//else
|
|
|
|
return occurence;
|
|
|
|
}//fn
|
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let k=this.refRow; k<this.nbRows; k++){
|
2015-02-22 12:46:05 +01:00
|
|
|
/*** if table already filtered some rows are not visible ***/
|
2016-01-02 04:43:00 +01:00
|
|
|
if(this.getRowDisplay(row[k]) === 'none'){
|
2015-02-22 12:46:05 +01:00
|
|
|
row[k].style.display = '';
|
|
|
|
}
|
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
let cell = row[k].cells,
|
2015-02-22 12:46:05 +01:00
|
|
|
nchilds = cell.length;
|
|
|
|
|
|
|
|
// checks if row has exact cell #
|
|
|
|
if(nchilds !== this.nbCells){
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
let occurence = [],
|
2015-06-11 09:27:02 +02:00
|
|
|
isRowValid = true,
|
2015-02-22 12:46:05 +01:00
|
|
|
//only for single filter search
|
|
|
|
singleFltRowValid = false;
|
|
|
|
|
|
|
|
// this loop retrieves cell data
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let j=0; j<nchilds; j++){
|
2015-02-22 12:46:05 +01:00
|
|
|
//searched keyword
|
2015-05-30 14:23:33 +02:00
|
|
|
let sA = this.searchArgs[this.singleSearchFlt ? 0 : j];
|
|
|
|
var dtType = this.hasColDateType ?
|
2015-02-22 12:46:05 +01:00
|
|
|
this.colDateType[j] : this.defaultDateType;
|
2015-06-07 12:30:32 +02:00
|
|
|
if(sA === ''){
|
2015-02-22 12:46:05 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-12-05 14:37:59 +01:00
|
|
|
let cellData = Str.matchCase(this.getCellData(cell[j]),
|
2015-11-07 07:00:29 +01:00
|
|
|
this.caseSensitive);
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
//multiple search parameter operator ||
|
2015-05-30 14:23:33 +02:00
|
|
|
let sAOrSplit = sA.split(this.orOperator),
|
2015-02-22 12:46:05 +01:00
|
|
|
//multiple search || parameter boolean
|
|
|
|
hasMultiOrSA = (sAOrSplit.length>1) ? true : false,
|
|
|
|
//multiple search parameter operator &&
|
|
|
|
sAAndSplit = sA.split(this.anOperator),
|
|
|
|
//multiple search && parameter boolean
|
|
|
|
hasMultiAndSA = sAAndSplit.length>1 ? true : false;
|
|
|
|
|
|
|
|
//multiple sarch parameters
|
|
|
|
if(hasMultiOrSA || hasMultiAndSA){
|
2015-05-30 14:23:33 +02:00
|
|
|
let cS,
|
2015-02-22 12:46:05 +01:00
|
|
|
occur = false,
|
|
|
|
s = hasMultiOrSA ? sAOrSplit : sAAndSplit;
|
2015-06-05 09:46:48 +02:00
|
|
|
for(let w=0, len=s.length; w<len; w++){
|
2015-05-30 14:23:33 +02:00
|
|
|
cS = Str.trim(s[w]);
|
2015-12-05 14:37:59 +01:00
|
|
|
occur = hasArg.call(this, cS, cellData, j);
|
2015-05-23 10:55:51 +02:00
|
|
|
highlight.call(this, cS, occur, cell[j]);
|
2015-02-22 12:46:05 +01:00
|
|
|
if(hasMultiOrSA && occur){
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(hasMultiAndSA && !occur){
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
occurence[j] = occur;
|
|
|
|
}
|
|
|
|
//single search parameter
|
|
|
|
else {
|
2015-12-05 14:37:59 +01:00
|
|
|
occurence[j] = hasArg.call(this, Str.trim(sA), cellData, j);
|
2015-05-23 10:55:51 +02:00
|
|
|
highlight.call(this, sA, occurence[j], cell[j]);
|
2015-02-22 12:46:05 +01:00
|
|
|
}//else single param
|
|
|
|
|
|
|
|
if(!occurence[j]){
|
2015-06-11 09:27:02 +02:00
|
|
|
isRowValid = false;
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
if(this.singleSearchFlt && occurence[j]){
|
|
|
|
singleFltRowValid = true;
|
|
|
|
}
|
2016-01-02 04:43:00 +01:00
|
|
|
|
|
|
|
this.emitter.emit('cell-processed', this, j, cell[j]);
|
2015-02-22 12:46:05 +01:00
|
|
|
}//for j
|
|
|
|
|
|
|
|
if(this.singleSearchFlt && singleFltRowValid){
|
|
|
|
isRowValid = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!isRowValid){
|
2015-05-24 08:50:39 +02:00
|
|
|
this.validateRow(k, false);
|
2015-12-31 02:56:50 +01:00
|
|
|
hiddenrows++;
|
2015-02-22 12:46:05 +01:00
|
|
|
} else {
|
2015-05-24 08:50:39 +02:00
|
|
|
this.validateRow(k, true);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2016-01-02 04:43:00 +01:00
|
|
|
|
|
|
|
this.emitter.emit('row-processed', this, k,
|
|
|
|
this.validRowsIndex.length, isRowValid);
|
2015-02-22 12:46:05 +01:00
|
|
|
}// for k
|
|
|
|
|
|
|
|
this.nbVisibleRows = this.validRowsIndex.length;
|
|
|
|
this.nbHiddenRows = hiddenrows;
|
|
|
|
|
2015-12-27 12:08:14 +01:00
|
|
|
//invokes onafterfilter callback
|
2015-02-22 12:46:05 +01:00
|
|
|
if(this.onAfterFilter){
|
2015-12-27 12:08:14 +01:00
|
|
|
this.onAfterFilter.call(null, this);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-12-08 12:53:12 +01:00
|
|
|
|
2015-12-28 07:53:03 +01:00
|
|
|
this.emitter.emit('after-filtering', this);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-23 10:55:51 +02:00
|
|
|
/**
|
2015-06-11 16:23:35 +02:00
|
|
|
* Return the data of a specified colum
|
2015-11-07 08:17:59 +01:00
|
|
|
* @param {Number} colIndex Column index
|
|
|
|
* @param {Boolean} includeHeaders Optional: include headers row
|
|
|
|
* @param {Boolean} num Optional: return unformatted number
|
|
|
|
* @param {Array} exclude Optional: list of row indexes to be excluded
|
2015-05-23 10:55:51 +02:00
|
|
|
* @return {Array} Flat list of data for a column
|
|
|
|
*/
|
2015-11-07 08:17:59 +01:00
|
|
|
getColValues(colIndex, includeHeaders=false, num=false, exclude=[]){
|
2015-02-22 12:46:05 +01:00
|
|
|
if(!this.fltGrid){
|
|
|
|
return;
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
let row = this.tbl.rows,
|
2015-02-22 12:46:05 +01:00
|
|
|
colValues = [];
|
|
|
|
|
2015-11-07 08:17:59 +01:00
|
|
|
if(includeHeaders){
|
|
|
|
colValues.push(this.getHeadersText()[colIndex]);
|
|
|
|
}
|
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let i=this.refRow; i<this.nbRows; i++){
|
|
|
|
let isExludedRow = false;
|
2015-02-22 12:46:05 +01:00
|
|
|
// checks if current row index appears in exclude array
|
2015-11-07 08:17:59 +01:00
|
|
|
if(exclude.length > 0){
|
2015-10-19 14:41:09 +02:00
|
|
|
isExludedRow = exclude.indexOf(i) != -1;
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
let cell = row[i].cells,
|
2015-02-22 12:46:05 +01:00
|
|
|
nchilds = cell.length;
|
|
|
|
|
|
|
|
// checks if row has exact cell # and is not excluded
|
2015-05-23 10:55:51 +02:00
|
|
|
if(nchilds === this.nbCells && !isExludedRow){
|
2015-02-22 12:46:05 +01:00
|
|
|
// this loop retrieves cell data
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let j=0; j<nchilds; j++){
|
2015-11-07 08:17:59 +01:00
|
|
|
if(j != colIndex || row[i].style.display !== ''){
|
2015-06-02 09:45:24 +02:00
|
|
|
continue;
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-12-05 14:37:59 +01:00
|
|
|
let cellData = this.getCellData(cell[j]),
|
2015-06-02 09:45:24 +02:00
|
|
|
nbFormat = this.colNbFormat ?
|
2015-11-07 08:17:59 +01:00
|
|
|
this.colNbFormat[colIndex] : null,
|
2015-06-02 09:45:24 +02:00
|
|
|
data = num ?
|
2015-12-05 14:37:59 +01:00
|
|
|
Helpers.removeNbFormat(cellData, nbFormat) :
|
|
|
|
cellData;
|
2015-06-02 09:45:24 +02:00
|
|
|
colValues.push(data);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
return colValues;
|
|
|
|
}
|
|
|
|
|
2015-05-23 10:55:51 +02:00
|
|
|
/**
|
2015-05-24 08:50:39 +02:00
|
|
|
* Return the filter's value of a specified column
|
2015-05-23 10:55:51 +02:00
|
|
|
* @param {Number} index Column index
|
|
|
|
* @return {String} Filter value
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
getFilterValue(index){
|
|
|
|
if(!this.fltGrid){
|
|
|
|
return;
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
let fltValue,
|
2015-02-22 12:46:05 +01:00
|
|
|
flt = this.getFilterElement(index);
|
|
|
|
if(!flt){
|
|
|
|
return '';
|
|
|
|
}
|
2015-07-12 11:50:55 +02:00
|
|
|
|
2015-06-05 15:10:25 +02:00
|
|
|
let fltColType = this.getFilterType(index);
|
2015-02-22 12:46:05 +01:00
|
|
|
if(fltColType !== this.fltTypeMulti &&
|
|
|
|
fltColType !== this.fltTypeCheckList){
|
|
|
|
fltValue = flt.value;
|
|
|
|
}
|
|
|
|
//mutiple select
|
|
|
|
else if(fltColType === this.fltTypeMulti){
|
|
|
|
fltValue = '';
|
2015-06-05 09:46:48 +02:00
|
|
|
for(let j=0, len=flt.options.length; j<len; j++){
|
2015-02-22 12:46:05 +01:00
|
|
|
if(flt.options[j].selected){
|
|
|
|
fltValue = fltValue.concat(
|
|
|
|
flt.options[j].value+' ' +
|
|
|
|
this.orOperator + ' '
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//removes last operator ||
|
2015-05-23 10:55:51 +02:00
|
|
|
fltValue = fltValue.substr(0, fltValue.length-4);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
//checklist
|
|
|
|
else if(fltColType === this.fltTypeCheckList){
|
|
|
|
if(flt.getAttribute('value') !== null){
|
|
|
|
fltValue = flt.getAttribute('value');
|
|
|
|
//removes last operator ||
|
2015-06-02 09:45:24 +02:00
|
|
|
fltValue = fltValue.substr(0, fltValue.length-3);
|
2015-02-22 12:46:05 +01:00
|
|
|
} else{
|
|
|
|
fltValue = '';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return fltValue;
|
|
|
|
}
|
|
|
|
|
2015-05-24 08:50:39 +02:00
|
|
|
/**
|
|
|
|
* Return the filters' values
|
|
|
|
* @return {Array} List of filters' values
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
getFiltersValue(){
|
|
|
|
if(!this.fltGrid){
|
|
|
|
return;
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
let searchArgs = [];
|
2015-06-05 09:46:48 +02:00
|
|
|
for(let i=0, len=this.fltIds.length; i<len; i++){
|
2015-02-22 12:46:05 +01:00
|
|
|
searchArgs.push(
|
2015-05-30 14:23:33 +02:00
|
|
|
Str.trim(
|
|
|
|
Str.matchCase(this.getFilterValue(i), this.caseSensitive))
|
2015-02-22 12:46:05 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return searchArgs;
|
|
|
|
}
|
|
|
|
|
2015-05-24 08:50:39 +02:00
|
|
|
/**
|
|
|
|
* Return the ID of the filter of a specified column
|
|
|
|
* @param {Number} index Column's index
|
|
|
|
* @return {String} ID of the filter element
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
getFilterId(index){
|
|
|
|
if(!this.fltGrid){
|
|
|
|
return;
|
|
|
|
}
|
2015-05-15 12:37:27 +02:00
|
|
|
return this.fltIds[index];
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-24 08:50:39 +02:00
|
|
|
/**
|
|
|
|
* Return the list of ids of filters matching a specified type.
|
|
|
|
* Note: hidden filters are also returned
|
|
|
|
*
|
|
|
|
* @param {String} type Filter type string ('input', 'select', 'multiple',
|
|
|
|
* 'checklist')
|
|
|
|
* @param {Boolean} bool If true returns columns indexes instead of IDs
|
|
|
|
* @return {[type]} List of element IDs or column indexes
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
getFiltersByType(type, bool){
|
|
|
|
if(!this.fltGrid){
|
|
|
|
return;
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
let arr = [];
|
2015-06-05 09:46:48 +02:00
|
|
|
for(let i=0, len=this.fltIds.length; i<len; i++){
|
2015-06-05 15:10:25 +02:00
|
|
|
let fltType = this.getFilterType(i);
|
2015-05-30 14:23:33 +02:00
|
|
|
if(fltType === Str.lower(type)){
|
2015-05-31 13:48:29 +02:00
|
|
|
let a = bool ? i : this.fltIds[i];
|
2015-02-22 12:46:05 +01:00
|
|
|
arr.push(a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return arr;
|
|
|
|
}
|
|
|
|
|
2015-05-24 08:50:39 +02:00
|
|
|
/**
|
|
|
|
* Return the filter's DOM element for a given column
|
|
|
|
* @param {Number} index Column's index
|
|
|
|
* @return {DOMElement}
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
getFilterElement(index){
|
2015-05-30 14:23:33 +02:00
|
|
|
let fltId = this.fltIds[index];
|
|
|
|
return Dom.id(fltId);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-24 08:50:39 +02:00
|
|
|
/**
|
|
|
|
* Return the number of cells for a given row index
|
|
|
|
* @param {Number} rowIndex Index of the row
|
|
|
|
* @return {Number} Number of cells
|
|
|
|
*/
|
2015-06-05 15:10:25 +02:00
|
|
|
getCellsNb(rowIndex=0){
|
|
|
|
let tr = this.tbl.rows[rowIndex];
|
2015-02-22 12:46:05 +01:00
|
|
|
return tr.cells.length;
|
|
|
|
}
|
|
|
|
|
2015-05-24 08:50:39 +02:00
|
|
|
/**
|
|
|
|
* Return the number of filterable rows starting from reference row if
|
|
|
|
* defined
|
|
|
|
* @param {Boolean} includeHeaders Include the headers row
|
|
|
|
* @return {Number} Number of filterable rows
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
getRowsNb(includeHeaders){
|
2015-06-05 15:10:25 +02:00
|
|
|
let s = Types.isUndef(this.refRow) ? 0 : this.refRow,
|
2015-02-22 12:46:05 +01:00
|
|
|
ntrs = this.tbl.rows.length;
|
|
|
|
if(includeHeaders){ s = 0; }
|
|
|
|
return parseInt(ntrs-s, 10);
|
|
|
|
}
|
|
|
|
|
2015-05-24 08:50:39 +02:00
|
|
|
/**
|
|
|
|
* Return the data of a given cell
|
2015-11-07 07:00:29 +01:00
|
|
|
* @param {DOMElement} cell Cell's DOM object
|
2015-05-24 08:50:39 +02:00
|
|
|
* @return {String}
|
|
|
|
*/
|
2015-11-07 07:00:29 +01:00
|
|
|
getCellData(cell){
|
2015-12-30 06:56:44 +01:00
|
|
|
let idx = cell.cellIndex;
|
2015-11-07 07:00:29 +01:00
|
|
|
//Check for customCellData callback
|
|
|
|
if(this.customCellData && this.customCellDataCols.indexOf(idx) != -1){
|
|
|
|
return this.customCellData.call(null, this, cell, idx);
|
2015-02-22 12:46:05 +01:00
|
|
|
} else {
|
2015-05-30 14:23:33 +02:00
|
|
|
return Dom.getText(cell);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-24 08:50:39 +02:00
|
|
|
/**
|
|
|
|
* Return the table data with following format:
|
|
|
|
* [
|
|
|
|
* [rowIndex, [value0, value1...]],
|
|
|
|
* [rowIndex, [value0, value1...]]
|
|
|
|
* ]
|
2015-11-07 08:17:59 +01:00
|
|
|
* @param {Boolean} includeHeaders Optional: include headers row
|
2015-05-24 08:50:39 +02:00
|
|
|
* @return {Array}
|
2015-05-25 09:55:56 +02:00
|
|
|
*
|
|
|
|
* TODO: provide an API returning data in JSON format
|
2015-05-24 08:50:39 +02:00
|
|
|
*/
|
2015-10-28 08:09:37 +01:00
|
|
|
getTableData(includeHeaders=false){
|
|
|
|
let rows = this.tbl.rows;
|
|
|
|
let tblData = [];
|
|
|
|
if(includeHeaders){
|
2015-11-07 08:17:59 +01:00
|
|
|
tblData.push([this.getHeadersRowIndex(), this.getHeadersText()]);
|
2015-10-28 08:09:37 +01:00
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let k=this.refRow; k<this.nbRows; k++){
|
2015-11-07 08:17:59 +01:00
|
|
|
let rowData = [k, []];
|
2015-10-28 08:09:37 +01:00
|
|
|
let cells = rows[k].cells;
|
2015-06-05 09:46:48 +02:00
|
|
|
for(let j=0, len=cells.length; j<len; j++){
|
2015-11-07 07:00:29 +01:00
|
|
|
let cellData = this.getCellData(cells[j]);
|
2015-10-28 08:09:37 +01:00
|
|
|
rowData[1].push(cellData);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-10-28 08:09:37 +01:00
|
|
|
tblData.push(rowData);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-10-28 08:09:37 +01:00
|
|
|
return tblData;
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-24 08:50:39 +02:00
|
|
|
/**
|
|
|
|
* Return the filtered data with following format:
|
|
|
|
* [
|
|
|
|
* [rowIndex, [value0, value1...]],
|
|
|
|
* [rowIndex, [value0, value1...]]
|
|
|
|
* ]
|
2015-11-07 08:17:59 +01:00
|
|
|
* @param {Boolean} includeHeaders Optional: include headers row
|
2015-05-24 08:50:39 +02:00
|
|
|
* @return {Array}
|
2015-05-25 09:55:56 +02:00
|
|
|
*
|
|
|
|
* TODO: provide an API returning data in JSON format
|
2015-05-24 08:50:39 +02:00
|
|
|
*/
|
2015-10-28 08:09:37 +01:00
|
|
|
getFilteredData(includeHeaders=false){
|
2015-02-22 12:46:05 +01:00
|
|
|
if(!this.validRowsIndex){
|
|
|
|
return [];
|
|
|
|
}
|
2015-10-28 08:09:37 +01:00
|
|
|
let rows = this.tbl.rows,
|
2015-02-22 12:46:05 +01:00
|
|
|
filteredData = [];
|
|
|
|
if(includeHeaders){
|
2015-11-07 08:17:59 +01:00
|
|
|
filteredData.push([this.getHeadersRowIndex(),
|
|
|
|
this.getHeadersText()]);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
let validRows = this.getValidRows(true);
|
|
|
|
for(let i=0; i<validRows.length; i++){
|
2015-11-07 08:17:59 +01:00
|
|
|
let rData = [this.validRowsIndex[i], []],
|
2015-10-28 08:09:37 +01:00
|
|
|
cells = rows[this.validRowsIndex[i]].cells;
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let k=0; k<cells.length; k++){
|
2015-11-07 07:00:29 +01:00
|
|
|
let cellData = this.getCellData(cells[k]);
|
2015-10-28 08:09:37 +01:00
|
|
|
rData[1].push(cellData);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
filteredData.push(rData);
|
|
|
|
}
|
|
|
|
return filteredData;
|
|
|
|
}
|
|
|
|
|
2015-05-24 08:50:39 +02:00
|
|
|
/**
|
|
|
|
* Return the filtered data for a given column index
|
|
|
|
* @param {Number} colIndex Colmun's index
|
2015-11-07 08:17:59 +01:00
|
|
|
* @param {Boolean} includeHeaders Optional: include headers row
|
2015-05-24 08:50:39 +02:00
|
|
|
* @return {Array} Flat list of values ['val0','val1','val2'...]
|
2015-05-25 09:55:56 +02:00
|
|
|
*
|
|
|
|
* TODO: provide an API returning data in JSON format
|
2015-05-24 08:50:39 +02:00
|
|
|
*/
|
2015-11-07 08:17:59 +01:00
|
|
|
getFilteredDataCol(colIndex, includeHeaders=false){
|
|
|
|
if(Types.isUndef(colIndex)){
|
2015-02-22 12:46:05 +01:00
|
|
|
return [];
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
let data = this.getFilteredData(),
|
2015-02-22 12:46:05 +01:00
|
|
|
colData = [];
|
2015-11-07 08:17:59 +01:00
|
|
|
if(includeHeaders){
|
|
|
|
colData.push(this.getHeadersText()[colIndex]);
|
|
|
|
}
|
2015-06-05 09:46:48 +02:00
|
|
|
for(let i=0, len=data.length; i<len; i++){
|
2015-05-30 14:23:33 +02:00
|
|
|
let r = data[i],
|
2015-02-22 12:46:05 +01:00
|
|
|
//cols values of current row
|
|
|
|
d = r[1],
|
|
|
|
//data of searched column
|
|
|
|
c = d[colIndex];
|
|
|
|
colData.push(c);
|
|
|
|
}
|
|
|
|
return colData;
|
|
|
|
}
|
|
|
|
|
2015-05-24 08:50:39 +02:00
|
|
|
/**
|
|
|
|
* Get the display value of a row
|
|
|
|
* @param {RowElement} DOM element of the row
|
|
|
|
* @return {String} Usually 'none' or ''
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
getRowDisplay(row){
|
2015-11-07 08:17:59 +01:00
|
|
|
if(!Types.isObj(row)){
|
|
|
|
return null;
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
return row.style.display;
|
|
|
|
}
|
|
|
|
|
2015-05-24 08:50:39 +02:00
|
|
|
/**
|
|
|
|
* Validate/invalidate row by setting the 'validRow' attribute on the row
|
|
|
|
* @param {Number} rowIndex Index of the row
|
|
|
|
* @param {Boolean} isValid
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
validateRow(rowIndex, isValid){
|
2015-05-30 14:23:33 +02:00
|
|
|
let row = this.tbl.rows[rowIndex];
|
2015-06-27 12:52:40 +02:00
|
|
|
if(!row || typeof isValid !== 'boolean'){
|
2015-02-22 12:46:05 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// always visible rows are valid
|
2015-08-01 09:45:29 +02:00
|
|
|
if(this.hasVisibleRows && this.visibleRows.indexOf(rowIndex) !== -1){
|
2015-02-22 12:46:05 +01:00
|
|
|
isValid = true;
|
|
|
|
}
|
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
let displayFlag = isValid ? '' : 'none',
|
2015-02-22 12:46:05 +01:00
|
|
|
validFlag = isValid ? 'true' : 'false';
|
|
|
|
row.style.display = displayFlag;
|
|
|
|
|
|
|
|
if(this.paging){
|
2015-05-24 08:50:39 +02:00
|
|
|
row.setAttribute('validRow', validFlag);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-12-31 02:56:50 +01:00
|
|
|
|
|
|
|
if(isValid){
|
|
|
|
if(this.validRowsIndex.indexOf(rowIndex) === -1){
|
|
|
|
this.validRowsIndex.push(rowIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(this.onRowValidated){
|
|
|
|
this.onRowValidated.call(null, this, rowIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.emitter.emit('row-validated', this, rowIndex);
|
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-25 09:55:56 +02:00
|
|
|
/**
|
|
|
|
* Validate all filterable rows
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
validateAllRows(){
|
|
|
|
if(!this._hasGrid){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.validRowsIndex = [];
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let k=this.refRow; k<this.nbFilterableRows; k++){
|
2015-02-22 12:46:05 +01:00
|
|
|
this.validateRow(k, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-25 09:55:56 +02:00
|
|
|
/**
|
|
|
|
* Set search value to a given filter
|
|
|
|
* @param {Number} index Column's index
|
|
|
|
* @param {String} searcharg Search term
|
|
|
|
*/
|
2015-06-13 16:46:42 +02:00
|
|
|
setFilterValue(index, searcharg=''){
|
2015-02-22 12:46:05 +01:00
|
|
|
if((!this.fltGrid && !this.isFirstLoad) ||
|
|
|
|
!this.getFilterElement(index)){
|
|
|
|
return;
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
let slc = this.getFilterElement(index),
|
2015-06-05 09:46:48 +02:00
|
|
|
fltColType = this.getFilterType(index);
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
if(fltColType !== this.fltTypeMulti &&
|
|
|
|
fltColType != this.fltTypeCheckList){
|
|
|
|
slc.value = searcharg;
|
|
|
|
}
|
|
|
|
//multiple selects
|
|
|
|
else if(fltColType === this.fltTypeMulti){
|
2015-05-30 14:23:33 +02:00
|
|
|
let s = searcharg.split(' '+this.orOperator+' ');
|
|
|
|
// let ct = 0; //keywords counter
|
2015-06-05 09:46:48 +02:00
|
|
|
for(let j=0, len=slc.options.length; j<len; j++){
|
2015-06-05 15:10:25 +02:00
|
|
|
let option = slc.options[j];
|
2015-02-22 12:46:05 +01:00
|
|
|
if(s==='' || s[0]===''){
|
2015-06-05 15:10:25 +02:00
|
|
|
option.selected = false;
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-06-05 15:10:25 +02:00
|
|
|
if(option.value===''){
|
|
|
|
option.selected = false;
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-06-05 15:10:25 +02:00
|
|
|
if(option.value!=='' &&
|
|
|
|
Arr.has(s, option.value, true)){
|
|
|
|
option.selected = true;
|
2015-02-22 12:46:05 +01:00
|
|
|
}//if
|
|
|
|
}//for j
|
|
|
|
}
|
|
|
|
//checklist
|
|
|
|
else if(fltColType === this.fltTypeCheckList){
|
2015-05-30 14:23:33 +02:00
|
|
|
searcharg = Str.matchCase(searcharg, this.caseSensitive);
|
|
|
|
let sarg = searcharg.split(' '+this.orOperator+' ');
|
|
|
|
let lisNb = Dom.tag(slc,'li').length;
|
2015-05-15 12:37:27 +02:00
|
|
|
|
2015-06-06 12:06:15 +02:00
|
|
|
slc.setAttribute('value', '');
|
|
|
|
slc.setAttribute('indexes', '');
|
2015-05-15 12:37:27 +02:00
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let k=0; k<lisNb; k++){
|
|
|
|
let li = Dom.tag(slc,'li')[k],
|
|
|
|
lbl = Dom.tag(li,'label')[0],
|
|
|
|
chk = Dom.tag(li,'input')[0],
|
|
|
|
lblTxt = Str.matchCase(
|
|
|
|
Dom.getText(lbl), this.caseSensitive);
|
|
|
|
if(lblTxt !== '' && Arr.has(sarg, lblTxt, true)){
|
2015-02-22 12:46:05 +01:00
|
|
|
chk.checked = true;
|
2015-06-07 17:31:15 +02:00
|
|
|
this.Mod.checkList.setCheckListValues(chk);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
else{
|
|
|
|
chk.checked = false;
|
2015-06-07 17:31:15 +02:00
|
|
|
this.Mod.checkList.setCheckListValues(chk);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-25 09:55:56 +02:00
|
|
|
/**
|
|
|
|
* Set them columns' widths as per configuration
|
|
|
|
* @param {Number} rowIndex Optional row index to apply the widths to
|
2015-06-06 12:06:15 +02:00
|
|
|
* @param {Element} tbl DOM element
|
2015-05-25 09:55:56 +02:00
|
|
|
*/
|
2015-06-06 12:06:15 +02:00
|
|
|
setColWidths(rowIndex, tbl){
|
2015-05-28 15:44:23 +02:00
|
|
|
if(!this.fltGrid || !this.hasColWidths){
|
2015-02-22 12:46:05 +01:00
|
|
|
return;
|
|
|
|
}
|
2015-06-06 12:06:15 +02:00
|
|
|
tbl = tbl || this.tbl;
|
2015-05-30 14:23:33 +02:00
|
|
|
let rIndex;
|
2015-02-22 12:46:05 +01:00
|
|
|
if(rowIndex===undefined){
|
2015-06-06 12:06:15 +02:00
|
|
|
rIndex = tbl.rows[0].style.display!='none' ? 0 : 1;
|
2015-02-22 12:46:05 +01:00
|
|
|
} else{
|
|
|
|
rIndex = rowIndex;
|
|
|
|
}
|
2015-06-06 12:06:15 +02:00
|
|
|
|
2015-08-11 13:28:26 +02:00
|
|
|
setWidths.call(this);
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-08-11 13:28:26 +02:00
|
|
|
function setWidths(){
|
2015-05-25 09:55:56 +02:00
|
|
|
/*jshint validthis:true */
|
2015-05-30 14:23:33 +02:00
|
|
|
let nbCols = this.nbCells;
|
|
|
|
let colWidths = this.colWidths;
|
2015-06-06 12:06:15 +02:00
|
|
|
let colTags = Dom.tag(tbl, 'col');
|
|
|
|
let tblHasColTag = colTags.length > 0;
|
|
|
|
let frag = !tblHasColTag ? doc.createDocumentFragment() : null;
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let k=0; k<nbCols; k++){
|
2015-06-06 12:06:15 +02:00
|
|
|
let col;
|
|
|
|
if(tblHasColTag){
|
|
|
|
col = colTags[k];
|
|
|
|
} else {
|
|
|
|
col = Dom.create('col', ['id', this.id+'_col_'+k]);
|
|
|
|
frag.appendChild(col);
|
|
|
|
}
|
|
|
|
col.style.width = colWidths[k];
|
|
|
|
}
|
|
|
|
if(!tblHasColTag){
|
|
|
|
tbl.insertBefore(frag, tbl.firstChild);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-25 09:55:56 +02:00
|
|
|
/**
|
|
|
|
* Makes defined rows always visible
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
enforceVisibility(){
|
2015-08-01 09:45:29 +02:00
|
|
|
if(!this.hasVisibleRows){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for(let i=0, len=this.visibleRows.length; i<len; i++){
|
|
|
|
let row = this.visibleRows[i];
|
|
|
|
//row index cannot be > nrows
|
|
|
|
if(row <= this.nbRows){
|
|
|
|
this.validateRow(row, true);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
clearFilters(){
|
|
|
|
this.EvtManager(this.Evt.name.clear);
|
|
|
|
}
|
2015-05-26 09:29:30 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Clear all the filters' values
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
_clearFilters(){
|
|
|
|
if(!this.fltGrid){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(this.onBeforeReset){
|
|
|
|
this.onBeforeReset.call(null, this, this.getFiltersValue());
|
|
|
|
}
|
2015-06-05 09:46:48 +02:00
|
|
|
for(let i=0, len=this.fltIds.length; i<len; i++){
|
2015-02-22 12:46:05 +01:00
|
|
|
this.setFilterValue(i, '');
|
|
|
|
}
|
2015-12-28 07:53:03 +01:00
|
|
|
// if(this.linkedFilters){
|
|
|
|
// this.linkFilters();
|
|
|
|
// }
|
2015-05-30 14:23:33 +02:00
|
|
|
if(this.rememberPageLen){ Cookie.remove(this.pgLenCookie); }
|
|
|
|
if(this.rememberPageNb){ Cookie.remove(this.pgNbCookie); }
|
2015-02-22 12:46:05 +01:00
|
|
|
if(this.onAfterReset){ this.onAfterReset.call(null, this); }
|
2015-12-28 07:53:03 +01:00
|
|
|
|
|
|
|
this.emitter.emit('cleared-filters', this);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-26 09:29:30 +02:00
|
|
|
/**
|
|
|
|
* Clears filtered columns visual indicator (background color)
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
clearActiveColumns(){
|
2015-08-11 13:28:26 +02:00
|
|
|
for(let i=0, len=this.getCellsNb(this.headersRow); i<len; i++){
|
2015-05-30 14:23:33 +02:00
|
|
|
Dom.removeClass(
|
2015-02-22 12:46:05 +01:00
|
|
|
this.getHeaderElement(i), this.activeColumnsCssClass);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-02 04:43:00 +01:00
|
|
|
/**
|
|
|
|
* Mark currently filtered column
|
|
|
|
* @param {Number} colIndex Column index
|
|
|
|
*/
|
|
|
|
markActiveColumn(colIndex){
|
|
|
|
let header = this.getHeaderElement(colIndex);
|
|
|
|
if(Dom.hasClass(header, this.activeColumnsCssClass)){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(this.onBeforeActiveColumn){
|
|
|
|
this.onBeforeActiveColumn.call(null, this, colIndex);
|
|
|
|
}
|
|
|
|
Dom.addClass(header, this.activeColumnsCssClass);
|
|
|
|
if(this.onAfterActiveColumn){
|
|
|
|
this.onAfterActiveColumn.call(null, this, colIndex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-26 09:29:30 +02:00
|
|
|
/**
|
|
|
|
* Refresh the filters subject to linking ('select', 'multiple',
|
|
|
|
* 'checklist' type)
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
linkFilters(){
|
2015-12-28 07:53:03 +01:00
|
|
|
if(!this.linkedFilters || !this.activeFilterId){
|
2015-06-13 13:23:33 +02:00
|
|
|
return;
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
let slcA1 = this.getFiltersByType(this.fltTypeSlc, true),
|
2015-02-22 12:46:05 +01:00
|
|
|
slcA2 = this.getFiltersByType(this.fltTypeMulti, true),
|
|
|
|
slcA3 = this.getFiltersByType(this.fltTypeCheckList, true),
|
|
|
|
slcIndex = slcA1.concat(slcA2);
|
|
|
|
slcIndex = slcIndex.concat(slcA3);
|
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
let activeFlt = this.activeFilterId.split('_')[0];
|
2015-05-26 09:29:30 +02:00
|
|
|
activeFlt = activeFlt.split(this.prfxFlt)[1];
|
2015-05-30 14:23:33 +02:00
|
|
|
let slcSelectedValue;
|
2015-06-05 09:46:48 +02:00
|
|
|
for(let i=0, len=slcIndex.length; i<len; i++){
|
2015-05-30 14:23:33 +02:00
|
|
|
let curSlc = Dom.id(this.fltIds[slcIndex[i]]);
|
2015-05-26 09:29:30 +02:00
|
|
|
slcSelectedValue = this.getFilterValue(slcIndex[i]);
|
2015-06-07 12:30:32 +02:00
|
|
|
|
|
|
|
// Welcome to cyclomatic complexity hell :)
|
|
|
|
// TODO: simplify/refactor if statement
|
2015-05-26 09:29:30 +02:00
|
|
|
if(activeFlt!==slcIndex[i] ||
|
2015-10-19 14:41:09 +02:00
|
|
|
(this.paging && slcA1.indexOf(slcIndex[i]) != -1 &&
|
2015-05-26 09:29:30 +02:00
|
|
|
activeFlt === slcIndex[i] ) ||
|
2015-10-19 14:41:09 +02:00
|
|
|
(!this.paging && (slcA3.indexOf(slcIndex[i]) != -1 ||
|
|
|
|
slcA2.indexOf(slcIndex[i]) != -1)) ||
|
2015-05-26 09:29:30 +02:00
|
|
|
slcSelectedValue === this.displayAllText ){
|
|
|
|
|
2015-10-19 14:41:09 +02:00
|
|
|
if(slcA3.indexOf(slcIndex[i]) != -1){
|
2015-06-07 17:31:15 +02:00
|
|
|
this.Mod.checkList.checkListDiv[slcIndex[i]].innerHTML = '';
|
2015-05-26 09:29:30 +02:00
|
|
|
} else {
|
|
|
|
curSlc.innerHTML = '';
|
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-05-26 09:29:30 +02:00
|
|
|
//1st option needs to be inserted
|
2015-09-20 10:42:00 +02:00
|
|
|
if(this.loadFltOnDemand) {
|
2015-05-30 14:23:33 +02:00
|
|
|
let opt0 = Dom.createOpt(this.displayAllText, '');
|
2015-05-26 09:29:30 +02:00
|
|
|
if(curSlc){
|
|
|
|
curSlc.appendChild(opt0);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-05-26 09:29:30 +02:00
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-10-19 14:41:09 +02:00
|
|
|
if(slcA3.indexOf(slcIndex[i]) != -1){
|
2015-06-07 17:31:15 +02:00
|
|
|
this.Mod.checkList._build(slcIndex[i]);
|
2015-05-26 09:29:30 +02:00
|
|
|
} else {
|
2015-06-07 17:31:15 +02:00
|
|
|
this.Mod.dropdown._build(slcIndex[i], true);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
2015-05-26 09:29:30 +02:00
|
|
|
|
2015-06-10 12:53:20 +02:00
|
|
|
this.setFilterValue(slcIndex[i], slcSelectedValue);
|
2015-05-26 09:29:30 +02:00
|
|
|
}
|
|
|
|
}// for i
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-27 09:58:02 +02:00
|
|
|
/**
|
|
|
|
* Re-generate the filters grid bar when previously removed
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
_resetGrid(){
|
|
|
|
if(this.isFirstLoad){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-06-07 17:31:15 +02:00
|
|
|
let Mod = this.Mod;
|
2015-05-30 14:23:33 +02:00
|
|
|
let tbl = this.tbl;
|
|
|
|
let rows = tbl.rows;
|
|
|
|
let filtersRowIndex = this.filtersRowIndex;
|
|
|
|
let filtersRow = rows[filtersRowIndex];
|
2015-05-28 12:09:34 +02:00
|
|
|
|
2015-02-22 12:46:05 +01:00
|
|
|
// grid was removed, grid row element is stored in fltGridEl property
|
|
|
|
if(!this.gridLayout){
|
2015-06-08 12:21:50 +02:00
|
|
|
// If table has a thead ensure the filters row is appended in the
|
|
|
|
// thead element
|
|
|
|
if(tbl.tHead){
|
|
|
|
var tempRow = tbl.tHead.insertRow(this.filtersRowIndex);
|
|
|
|
tbl.tHead.replaceChild(this.fltGridEl, tempRow);
|
|
|
|
} else {
|
|
|
|
filtersRow.parentNode.insertBefore(this.fltGridEl, filtersRow);
|
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// filters are appended in external placeholders elements
|
|
|
|
if(this.isExternalFlt){
|
2015-05-30 14:23:33 +02:00
|
|
|
let externalFltTgtIds = this.externalFltTgtIds;
|
|
|
|
for(let ct=0, len=externalFltTgtIds.length; ct<len; ct++){
|
|
|
|
let extFlt = Dom.id(externalFltTgtIds[ct]);
|
2015-05-28 12:09:34 +02:00
|
|
|
|
|
|
|
if(!extFlt){ continue; }
|
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
let externalFltEl = this.externalFltEls[ct];
|
2015-05-28 12:09:34 +02:00
|
|
|
extFlt.appendChild(externalFltEl);
|
2015-06-05 15:10:25 +02:00
|
|
|
let colFltType = this.getFilterType(ct);
|
2015-05-28 12:09:34 +02:00
|
|
|
//IE special treatment for gridLayout, appended filters are
|
|
|
|
//empty
|
|
|
|
if(this.gridLayout &&
|
|
|
|
externalFltEl.innerHTML === '' &&
|
|
|
|
colFltType !== this.fltTypeInp){
|
|
|
|
if(colFltType === this.fltTypeSlc ||
|
|
|
|
colFltType === this.fltTypeMulti){
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.dropdown.build(ct);
|
2015-05-28 12:09:34 +02:00
|
|
|
}
|
|
|
|
if(colFltType === this.fltTypeCheckList){
|
2015-06-07 17:31:15 +02:00
|
|
|
Mod.checkList.build(ct);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.nbFilterableRows = this.getRowsNb();
|
|
|
|
this.nbVisibleRows = this.nbFilterableRows;
|
2015-05-28 12:09:34 +02:00
|
|
|
this.nbRows = rows.length;
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-11-21 04:41:40 +01:00
|
|
|
if(this.popupFilters){
|
2015-06-07 12:30:32 +02:00
|
|
|
this.headersRow++;
|
2015-11-21 04:41:40 +01:00
|
|
|
Mod.popupFilter.reset();
|
2015-06-07 12:30:32 +02:00
|
|
|
}
|
2015-02-22 12:46:05 +01:00
|
|
|
|
|
|
|
if(!this.gridLayout){
|
2015-05-30 14:23:33 +02:00
|
|
|
Dom.addClass(this.tbl, this.prfxTf);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
this._hasGrid = true;
|
|
|
|
}
|
|
|
|
|
2015-10-13 15:15:18 +02:00
|
|
|
/**
|
|
|
|
* Determines if passed filter column implements exact query match
|
|
|
|
* @param {Number} colIndex [description]
|
|
|
|
* @return {Boolean} [description]
|
|
|
|
*/
|
|
|
|
isExactMatch(colIndex){
|
|
|
|
let fltType = this.getFilterType(colIndex);
|
|
|
|
return this.exactMatchByCol[colIndex] || this.exactMatch ||
|
2015-12-05 14:37:59 +01:00
|
|
|
(fltType !== this.fltTypeInp);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-27 09:58:02 +02:00
|
|
|
/**
|
|
|
|
* Check if passed script or stylesheet is already imported
|
|
|
|
* @param {String} filePath Ressource path
|
|
|
|
* @param {String} type Possible values: 'script' or 'link'
|
|
|
|
* @return {Boolean}
|
|
|
|
*/
|
2015-02-28 10:27:28 +01:00
|
|
|
isImported(filePath, type){
|
2015-05-30 14:23:33 +02:00
|
|
|
let imported = false,
|
2015-02-28 10:27:28 +01:00
|
|
|
importType = !type ? 'script' : type,
|
|
|
|
attr = importType == 'script' ? 'src' : 'href',
|
2015-05-30 14:23:33 +02:00
|
|
|
files = Dom.tag(doc, importType);
|
2015-06-05 09:46:48 +02:00
|
|
|
for (let i=0, len=files.length; i<len; i++){
|
2015-02-28 10:27:28 +01:00
|
|
|
if(files[i][attr] === undefined){
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(files[i][attr].match(filePath)){
|
|
|
|
imported = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return imported;
|
|
|
|
}
|
|
|
|
|
2015-05-27 09:58:02 +02:00
|
|
|
/**
|
|
|
|
* Import script or stylesheet
|
|
|
|
* @param {String} fileId Ressource ID
|
|
|
|
* @param {String} filePath Ressource path
|
|
|
|
* @param {Function} callback Callback
|
|
|
|
* @param {String} type Possible values: 'script' or 'link'
|
|
|
|
*/
|
2015-05-15 16:26:21 +02:00
|
|
|
import(fileId, filePath, callback, type){
|
2015-05-30 14:23:33 +02:00
|
|
|
let ftype = !type ? 'script' : type,
|
2015-02-22 12:46:05 +01:00
|
|
|
imported = this.isImported(filePath, ftype);
|
|
|
|
if(imported){
|
|
|
|
return;
|
|
|
|
}
|
2015-05-30 14:23:33 +02:00
|
|
|
let o = this,
|
2015-02-22 12:46:05 +01:00
|
|
|
isLoaded = false,
|
|
|
|
file,
|
2015-05-30 14:23:33 +02:00
|
|
|
head = Dom.tag(doc, 'head')[0];
|
2015-02-22 12:46:05 +01:00
|
|
|
|
2015-05-30 14:23:33 +02:00
|
|
|
if(Str.lower(ftype) === 'link'){
|
|
|
|
file = Dom.create(
|
2015-02-22 12:46:05 +01:00
|
|
|
'link',
|
|
|
|
['id', fileId], ['type', 'text/css'],
|
|
|
|
['rel', 'stylesheet'], ['href', filePath]
|
|
|
|
);
|
|
|
|
} else {
|
2015-05-30 14:23:33 +02:00
|
|
|
file = Dom.create(
|
2015-02-22 12:46:05 +01:00
|
|
|
'script', ['id', fileId],
|
|
|
|
['type', 'text/javascript'], ['src', filePath]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Browser <> IE onload event works only for scripts, not for stylesheets
|
|
|
|
file.onload = file.onreadystatechange = function(){
|
|
|
|
if(!isLoaded &&
|
|
|
|
(!this.readyState || this.readyState === 'loaded' ||
|
|
|
|
this.readyState === 'complete')){
|
|
|
|
isLoaded = true;
|
|
|
|
if(typeof callback === 'function'){
|
|
|
|
callback.call(null, o);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
file.onerror = function(){
|
2015-04-24 12:38:20 +02:00
|
|
|
throw new Error('TF script could not load: ' + filePath);
|
2015-02-22 12:46:05 +01:00
|
|
|
};
|
|
|
|
head.appendChild(file);
|
|
|
|
}
|
|
|
|
|
2015-05-27 09:58:02 +02:00
|
|
|
/**
|
|
|
|
* Check if table has filters grid
|
|
|
|
* @return {Boolean}
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
hasGrid(){
|
|
|
|
return this._hasGrid;
|
|
|
|
}
|
|
|
|
|
2015-05-27 09:58:02 +02:00
|
|
|
/**
|
|
|
|
* Get list of filter IDs
|
|
|
|
* @return {[type]} [description]
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
getFiltersId(){
|
2015-05-27 09:58:02 +02:00
|
|
|
return this.fltIds || [];
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-27 09:58:02 +02:00
|
|
|
/**
|
|
|
|
* Get filtered (valid) rows indexes
|
|
|
|
* @param {Boolean} reCalc Force calculation of filtered rows list
|
|
|
|
* @return {Array} List of row indexes
|
|
|
|
*/
|
2015-05-24 11:16:09 +02:00
|
|
|
getValidRows(reCalc){
|
2015-02-22 12:46:05 +01:00
|
|
|
if(!reCalc){
|
|
|
|
return this.validRowsIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.validRowsIndex = [];
|
2015-05-30 14:23:33 +02:00
|
|
|
for(let k=this.refRow; k<this.getRowsNb(true); k++){
|
|
|
|
let r = this.tbl.rows[k];
|
2015-02-22 12:46:05 +01:00
|
|
|
if(!this.paging){
|
|
|
|
if(this.getRowDisplay(r) !== 'none'){
|
|
|
|
this.validRowsIndex.push(r.rowIndex);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if(r.getAttribute('validRow') === 'true' ||
|
|
|
|
r.getAttribute('validRow') === null){
|
|
|
|
this.validRowsIndex.push(r.rowIndex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this.validRowsIndex;
|
|
|
|
}
|
|
|
|
|
2015-05-27 09:58:02 +02:00
|
|
|
/**
|
|
|
|
* Get the index of the row containing the filters
|
|
|
|
* @return {Number}
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
getFiltersRowIndex(){
|
|
|
|
return this.filtersRowIndex;
|
|
|
|
}
|
|
|
|
|
2015-05-27 09:58:02 +02:00
|
|
|
/**
|
|
|
|
* Get the index of the headers row
|
|
|
|
* @return {Number}
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
getHeadersRowIndex(){
|
|
|
|
return this.headersRow;
|
|
|
|
}
|
|
|
|
|
2015-05-27 09:58:02 +02:00
|
|
|
/**
|
|
|
|
* Get the row index from where the filtering process start (1st filterable
|
|
|
|
* row)
|
|
|
|
* @return {Number}
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
getStartRowIndex(){
|
|
|
|
return this.refRow;
|
|
|
|
}
|
|
|
|
|
2015-05-27 09:58:02 +02:00
|
|
|
/**
|
|
|
|
* Get the index of the last row
|
|
|
|
* @return {Number}
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
getLastRowIndex(){
|
|
|
|
if(!this._hasGrid){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
return (this.nbRows-1);
|
|
|
|
}
|
|
|
|
|
2015-05-27 09:58:02 +02:00
|
|
|
/**
|
|
|
|
* Get the header DOM element for a given column index
|
|
|
|
* @param {Number} colIndex Column index
|
|
|
|
* @return {Object}
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
getHeaderElement(colIndex){
|
2015-06-07 17:31:15 +02:00
|
|
|
let table = this.gridLayout ? this.Mod.gridLayout.headTbl : this.tbl;
|
2015-05-30 14:23:33 +02:00
|
|
|
let tHead = Dom.tag(table, 'thead');
|
|
|
|
let headersRow = this.headersRow;
|
|
|
|
let header;
|
|
|
|
for(let i=0; i<this.nbCells; i++){
|
2015-02-22 12:46:05 +01:00
|
|
|
if(i !== colIndex){
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(tHead.length === 0){
|
2015-04-04 10:10:09 +02:00
|
|
|
header = table.rows[headersRow].cells[i];
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
if(tHead.length === 1){
|
2015-04-04 10:10:09 +02:00
|
|
|
header = tHead[0].rows[headersRow].cells[i];
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return header;
|
|
|
|
}
|
|
|
|
|
2015-11-07 08:17:59 +01:00
|
|
|
/**
|
|
|
|
* Return the list of headers' text
|
|
|
|
* @return {Array} list of headers' text
|
|
|
|
*/
|
|
|
|
getHeadersText(){
|
|
|
|
let headers = [];
|
|
|
|
for(let j=0; j<this.nbCells; j++){
|
|
|
|
let header = this.getHeaderElement(j);
|
|
|
|
let headerText = Dom.getText(header);
|
|
|
|
headers.push(headerText);
|
|
|
|
}
|
|
|
|
return headers;
|
|
|
|
}
|
|
|
|
|
2015-05-27 09:58:02 +02:00
|
|
|
/**
|
2015-06-05 09:46:48 +02:00
|
|
|
* Return the filter type for a specified column
|
|
|
|
* @param {Number} colIndex Column's index
|
|
|
|
* @return {String}
|
2015-05-27 09:58:02 +02:00
|
|
|
*/
|
2015-06-05 09:46:48 +02:00
|
|
|
getFilterType(colIndex){
|
|
|
|
let colType = this.cfg['col_'+colIndex];
|
|
|
|
return !colType ? this.fltTypeInp : Str.lower(colType);
|
2015-02-22 12:46:05 +01:00
|
|
|
}
|
|
|
|
|
2015-05-27 09:58:02 +02:00
|
|
|
/**
|
|
|
|
* Get the total number of filterable rows
|
|
|
|
* @return {Number}
|
|
|
|
*/
|
2015-02-22 12:46:05 +01:00
|
|
|
getFilterableRowsNb(){
|
|
|
|
return this.getRowsNb(false);
|
|
|
|
}
|
2015-06-05 09:46:48 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the configuration object (literal object)
|
|
|
|
* @return {Object}
|
|
|
|
*/
|
|
|
|
config(){
|
|
|
|
return this.cfg;
|
|
|
|
}
|
2015-02-28 10:27:28 +01:00
|
|
|
}
|