/*------------------------------------------------------------------------ - HTML Table Filter Generator v2.5 - By Max Guglielmi (tablefilter.free.fr) - Licensed under the MIT License -------------------------------------------------------------------------- Copyright (c) 2009-2012 Max Guglielmi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- - Special credit to: Cedric Wartel, cnx.claude@free.fr, Florent Hirchy, Váry Péter, Anthony Maes, Nuovella Williams, Fuggerbit, Venkata Seshagiri Rao Raya, Piepiax, Manuel Kern, Baladhandayutham for active contribution and/or inspiration ------------------------------------------------------------------------*/ var TF = (function() { /** * TF object constructor * @param {String} id Table id * @param {Number} row index indicating the 1st row * @param {Object} configuration object */ function TF(id) { if(arguments.length === 0){ return; } this.id = id; this.version = '2.5'; this.year = (new Date()).getFullYear(); this.tbl = tf_Id(id); this.startRow = undefined; this.refRow = null; this.headersRow = null; this.fObj = null; this.nbFilterableRows = null; this.nbRows = null; this.nbCells = null; this.hasGrid = false; this.enableModules = false; if(this.tbl !== null && this.tbl.nodeName.tf_LCase() === 'table' && this.GetRowsNb() > 0){ if(arguments.length>1) { for(var i=0; i1) this.filtersRowIndex = this.headersRow+1; else{ this.filtersRowIndex = 1; this.headersRow = 0; } } this.fltCellTag = f.filters_cell_tag!=undefined //defines tag of the cells containing filters (td/th) ? (f.filters_cell_tag!='th' ? 'td' : 'th') : 'td'; this.fltIds = []; //stores filters ids this.fltElms = []; //stores filters DOM elements this.searchArgs = null; //stores filters values this.tblData = []; //stores table data this.validRowsIndex = null; //stores valid rows indexes (rows visible upon filtering) this.fltGridEl = null; //stores filters row element this.isFirstLoad = true; //is first load boolean this.infDiv = null; //container div for paging elements, reset btn etc. this.lDiv = null; //div for rows counter this.rDiv = null; //div for reset button and results per page select this.mDiv = null; //div for paging elements this.contDiv = null; //table container div for fixed headers (IE only) this.infDivCssClass = f.inf_div_css_class!=undefined //defines css class for div containing ? f.inf_div_css_class : 'inf'; //paging elements, rows counter etc. this.lDivCssClass = f.left_div_css_class!=undefined //defines css class for left div ? f.left_div_css_class : 'ldiv'; this.rDivCssClass = f.right_div_css_class!=undefined //defines css class for right div ? f.right_div_css_class : 'rdiv'; this.mDivCssClass = f.middle_div_css_class!=undefined //defines css class for mid div ? f.middle_div_css_class : 'mdiv'; this.contDivCssClass = f.content_div_css_class!=undefined ? f.content_div_css_class : 'cont'; //table container div css class /*** filters' grid appearance ***/ this.stylesheet = f.stylesheet!=undefined ? f.stylesheet : this.basePath+'filtergrid.css'; //stylesheet file this.stylesheetId = this.id + '_style'; this.fltsRowCssClass = f.flts_row_css_class!=undefined //defines css class for filters row ? f.flts_row_css_class : 'fltrow'; this.enableIcons = f.enable_icons!=undefined ? f.enable_icons : true; //enables/disables icons (paging, reset button) this.alternateBgs = f.alternate_rows ? true : false; //enables/disbles rows alternating bg colors this.hasColWidth = f.col_width ? true : false; //defines widths of columns this.colWidth = this.hasColWidth ? f.col_width : null; this.fixedHeaders = f.fixed_headers ? true : false; //enables/disables fixed headers this.tBodyH = f.tbody_height ? f.tbody_height : 200; //tbody height if fixed headers enabled this.fltCssClass = f.flt_css_class!=undefined //defines css class for filters ? f.flt_css_class : 'flt'; this.fltMultiCssClass = f.flt_multi_css_class!=undefined //defines css class for multiple selects filters ? f.flt_multi_css_class : 'flt_multi'; this.fltSmallCssClass = f.flt_small_css_class!=undefined //defines css class for filters ? f.flt_small_css_class : 'flt_s'; this.singleFltCssClass = f.single_flt_css_class!=undefined //defines css class for single-filter ? f.single_flt_css_class : 'single_flt'; this.isStartBgAlternate = true; this.rowBgEvenCssClass = f.even_row_css_class!=undefined //defines css class for even rows ? f.even_row_css_class :'even'; this.rowBgOddCssClass = f.odd_row_css_class!=undefined //defines css class for odd rows ? f.odd_row_css_class :'odd'; /*** filters' grid behaviours ***/ this.enterKey = f.enter_key==false ? false : true; //enables/disables enter key this.isModFilterFn = f.mod_filter_fn ? true : false; //enables/disables alternative fn call this.modFilterFn = this.isModFilterFn ? f.mod_filter_fn : null;// used by tf_DetectKey fn this.onBeforeFilter = tf_IsFn(f.on_before_filter) //calls function before filtering starts ? f.on_before_filter : null; this.onAfterFilter = tf_IsFn(f.on_after_filter) //calls function after filtering ? f.on_after_filter : null; this.matchCase = f.match_case ? true : false; //enables/disables case sensitivity this.exactMatch = f.exact_match ? true : false; //enables/disbles exact match for search this.refreshFilters = f.refresh_filters ? true : false; //refreshes drop-down lists upon validation this.disableExcludedOptions = f.disable_excluded_options!=undefined ? f.disable_excluded_options : false; //wheter excluded options are disabled this.activeFlt = null; //stores active filter element this.activeFilterId = null; //id of active filter this.hasColOperation = f.col_operation ? true : false; //enables/disbles column operation(sum,mean) this.colOperation = null; this.hasVisibleRows = f.rows_always_visible ? true : false; //enables always visible rows this.visibleRows = this.hasVisibleRows ? f.rows_always_visible : [];//array containing always visible rows this.searchType = f.search_type!=undefined //defines search type: include or exclude ? f.search_type : 'include'; this.isExternalFlt = f.external_flt_grid ? true : false; //enables/disables external filters generation this.externalFltTgtIds = f.external_flt_grid_ids!=undefined //array containing ids of external elements containing filters ? f.external_flt_grid_ids : null; this.externalFltEls = []; //stores filters elements if isExternalFlt is true this.execDelay = f.exec_delay ? parseInt(f.exec_delay) : 100; //delays filtering process if loader true this.status = f.status ? true : false; //enables/disables status messages this.onFiltersLoaded = tf_IsFn(f.on_filters_loaded) //calls function when filters grid loaded ? f.on_filters_loaded : null; this.singleSearchFlt = f.single_search_filter ? true : false; //enables/disables single filter search this.onRowValidated = tf_IsFn(f.on_row_validated) //calls function after row is validated ? f.on_row_validated : null; this.customCellDataCols = f.custom_cell_data_cols ? f.custom_cell_data_cols : []; //array defining columns for customCellData event this.customCellData = tf_IsFn(f.custom_cell_data) //calls custom function for retrieving cell data ? f.custom_cell_data : null; this.inpWatermark = f.input_watermark!=undefined ? f.input_watermark : ''; //input watermark text array this.inpWatermarkCssClass = f.input_watermark_css_class!=undefined //defines css class for input watermark ? f.input_watermark_css_class : 'fltWatermark'; this.isInpWatermarkArray = f.input_watermark!=undefined ? (tf_IsArray(f.input_watermark) ? true : false) : false; this.toolBarTgtId = f.toolbar_target_id!=undefined //id of toolbar container element ? f.toolbar_target_id : null; this.helpInstructions = (f.help_instructions!=undefined) ? f.help_instructions : null; //enables/disables help div this.popUpFilters = f.popup_filters!=undefined ? f.popup_filters : false; //popup filters this.markActiveColumns = f.mark_active_columns!=undefined ? f.mark_active_columns : false; //active columns color this.activeColumnsCssClass = f.active_columns_css_class!=undefined //defines css class for active column header ? f.active_columns_css_class : 'activeHeader'; this.onBeforeActiveColumn = tf_IsFn(f.on_before_active_column) //calls function before active column header is marked ? f.on_before_active_column : null; this.onAfterActiveColumn = tf_IsFn(f.on_after_active_column) //calls function after active column header is marked ? f.on_after_active_column : null; /*** selects customisation and behaviours ***/ this.displayAllText = f.display_all_text!=undefined ? f.display_all_text : ''; //defines 1st option text this.enableSlcResetFilter = f.enable_slc_reset_filter!=undefined ? f.enable_slc_reset_filter : true; this.enableEmptyOption = f.enable_empty_option ? true : false; //enables/disables empty option in combo-box filters this.emptyText = f.empty_text!=undefined ? f.empty_text : '(Empty)'; //defines empty option text this.enableNonEmptyOption = f.enable_non_empty_option ? true : false; //enables/disables non empty option in combo-box filters this.nonEmptyText = f.non_empty_text!=undefined ? f.non_empty_text : '(Non empty)'; //defines empty option text this.onSlcChange = f.on_change==false ? false : true; //enables/disables onChange event on combo-box this.sortSlc = f.sort_select==false ? false : true; //enables/disables select options sorting this.isSortNumAsc = f.sort_num_asc ? true : false; //enables/disables ascending numeric options sorting this.sortNumAsc = this.isSortNumAsc ? f.sort_num_asc : null; this.isSortNumDesc = f.sort_num_desc ? true : false; //enables/disables descending numeric options sorting this.sortNumDesc = this.isSortNumDesc ? f.sort_num_desc : null; this.slcFillingMethod = f.slc_filling_method!=undefined //sets select filling method: 'innerHTML' or ? f.slc_filling_method : 'createElement'; //'createElement' this.fillSlcOnDemand = f.fill_slc_on_demand ? true : false; //enabled selects are populated on demand this.activateSlcTooltip = f.activate_slc_tooltip!=undefined //IE only, tooltip text appearing on select ? f.activate_slc_tooltip : 'Click to activate'; // before it is populated this.multipleSlcTooltip = f.multiple_slc_tooltip!=undefined //tooltip text appearing on multiple select ? f.multiple_slc_tooltip : 'Use Ctrl key for multiple selections'; this.hasCustomSlcOptions = f.custom_slc_options && tf_IsObj(f.custom_slc_options) ? true : false; this.customSlcOptions = f.custom_slc_options!=undefined ? f.custom_slc_options : null; this.onBeforeOperation = tf_IsFn(f.on_before_operation) //calls function before col operation ? f.on_before_operation : null; this.onAfterOperation = tf_IsFn(f.on_after_operation) //calls function after col operation ? f.on_after_operation : null; /*** checklist customisation and behaviours ***/ this.checkListDiv = []; //checklist container div this.checkListDivCssClass = f.div_checklist_css_class!=undefined ? f.div_checklist_css_class : 'div_checklist'; //defines css class for div containing checklist filter this.checkListCssClass = f.checklist_css_class!=undefined //defines css class for checklist filters ? f.checklist_css_class : 'flt_checklist'; this.checkListItemCssClass = f.checklist_item_css_class!=undefined //defines css class for checklist item (li) ? f.checklist_item_css_class : 'flt_checklist_item'; this.checkListSlcItemCssClass = f.checklist_selected_item_css_class!=undefined //defines css class for selected checklist item (li) ? f.checklist_selected_item_css_class : 'flt_checklist_slc_item'; this.activateCheckListTxt = f.activate_checklist_text!=undefined //Load on demand text ? f.activate_checklist_text : 'Click to load data'; this.checkListItemDisabledCssClass = f.checklist_item_disabled_css_class!=undefined //defines css class for checklist filters ? f.checklist_item_disabled_css_class : 'flt_checklist_item_disabled'; this.enableCheckListResetFilter = f.enable_checklist_reset_filter!=undefined ? f.enable_checklist_reset_filter : true; /*** Filter operators ***/ this.rgxOperator = f.regexp_operator!=undefined ? f.regexp_operator : 'rgx:'; this.emOperator = f.empty_operator!=undefined ? f.empty_operator : '[empty]'; this.nmOperator = f.nonempty_operator!=undefined ? f.nonempty_operator : '[nonempty]'; this.orOperator = f.or_operator!=undefined ? f.or_operator : '||'; this.anOperator = f.and_operator!=undefined ? f.and_operator : '&&'; this.grOperator = f.greater_operator!=undefined ? f.greater_operator : '>'; this.lwOperator = f.lower_operator!=undefined ? f.lower_operator : '<'; this.leOperator = f.lower_equal_operator!=undefined ? f.lower_equal_operator : '<='; this.geOperator = f.greater_equal_operator!=undefined ? f.greater_equal_operator : '>='; this.dfOperator = f.different_operator!=undefined ? f.different_operator : '!'; this.lkOperator = f.like_operator!=undefined ? f.like_operator : '*'; this.eqOperator = f.equal_operator!=undefined ? f.equal_operator : '='; this.stOperator = f.start_with_operator!=undefined ? f.start_with_operator : '{'; this.enOperator = f.end_with_operator!=undefined ? f.end_with_operator : '}'; this.curExp = f.cur_exp!=undefined ? f.cur_exp : '^[¥£€$]'; this.separator = f.separator!=undefined ? f.separator : ','; /*** rows counter ***/ this.rowsCounter = f.rows_counter ? true : false; //show/hides rows counter /*** status bar ***/ this.statusBar = f.status_bar ? f.status_bar : false; //show/hides status bar /*** loader ***/ this.loader = f.loader ? true : false; //enables/disables loader /*** validation - reset buttons/links ***/ this.displayBtn = f.btn ? true : false; //show/hides filter's validation button this.btnText = f.btn_text!=undefined ? f.btn_text : (!this.enableIcons ? 'Go' : ''); //defines validation button text this.btnCssClass = f.btn_css_class!=undefined ? f.btn_css_class : (!this.enableIcons ? 'btnflt' : 'btnflt_icon'); //defines css class for validation button this.btnReset = f.btn_reset ? true : false; //show/hides reset link this.btnResetCssClass = f.btn_reset_css_class!=undefined //defines css class for reset button ? f.btn_reset_css_class :'reset'; this.onBeforeReset = tf_IsFn(f.on_before_reset) ? f.on_before_reset : null; //callback function before filters are cleared this.onAfterReset = tf_IsFn(f.on_after_reset) ? f.on_after_reset : null; //callback function after filters are cleared /*** paging ***/ this.paging = f.paging ? true : false; //enables/disables table paging this.hasResultsPerPage = f.results_per_page ? true : false; //enables/disables results per page drop-down this.btnPageCssClass = f.paging_btn_css_class!=undefined ? f.paging_btn_css_class :'pgInp'; //css class for paging buttons (previous,next,etc.) this.pagingSlc = null; //stores paging select element this.resultsPerPage = null; //stores results per page text and values this.resultsPerPageSlc = null; //results per page select element this.isPagingRemoved = false; //indicates if paging elements were previously removed this.nbVisibleRows = 0; //nb visible rows this.nbHiddenRows = 0; //nb hidden rows this.startPagingRow = 0; //1st row index of current page this.nbPages = 0; //total nb of pages this.currentPageNb = 1; //current page nb /*** webfx sort adapter ***/ this.sort = f.sort ? true : false; //enables/disables default table sorting this.isSortEnabled = false; //indicates if sort is set (used in tfAdapter.sortabletable.js) this.sorted = false; //indicates if tables was sorted this.sortConfig = f.sort_config!=undefined ? f.sort_config : {}; this.sortConfig.name = this.sortConfig['name']!=undefined ? f.sort_config.name : 'sortabletable'; this.sortConfig.src = this.sortConfig['src']!=undefined ? f.sort_config.src : this.basePath+'sortabletable.js'; this.sortConfig.adapterSrc = this.sortConfig['adapter_src']!=undefined ? f.sort_config.adapter_src : this.basePath+'tfAdapter.sortabletable.js'; this.sortConfig.initialize =this.sortConfig['initialize']!=undefined ? f.sort_config.initialize : function(o){ if(o.SetSortTable) o.SetSortTable(); }; this.sortConfig.sortTypes = this.sortConfig['sort_types']!=undefined ? f.sort_config.sort_types : []; this.sortConfig.sortCol = this.sortConfig['sort_col']!=undefined ? f.sort_config.sort_col : null; this.sortConfig.asyncSort = this.sortConfig['async_sort']!=undefined ? true : false; this.sortConfig.triggerIds = this.sortConfig['sort_trigger_ids']!=undefined ? f.sort_config.sort_trigger_ids : []; /*** ezEditTable extension ***/ this.selectable = f.selectable!=undefined ? f.selectable : false; //enables/disables table selection feature this.editable = f.editable!=undefined ? f.editable : false; //enables/disables editable table feature this.ezEditTableConfig = f.ezEditTable_config!=undefined ? f.ezEditTable_config : {}; this.ezEditTableConfig.name = this.ezEditTableConfig['name']!=undefined ? f.ezEditTable_config.name : 'ezedittable'; this.ezEditTableConfig.src = this.ezEditTableConfig['src']!=undefined ? f.ezEditTable_config.src : this.basePath+'ezEditTable/ezEditTable.js'; //ezEditTable stylesheet not imported by default as filtergrid.css applies this.ezEditTableConfig.loadStylesheet = this.ezEditTableConfig['loadStylesheet']!=undefined ? f.ezEditTable_config.loadStylesheet : false; this.ezEditTableConfig.stylesheet = this.ezEditTableConfig['stylesheet']!=undefined ? f.ezEditTable_config.stylesheet : this.basePath+'ezEditTable/ezEditTable.css'; this.ezEditTableConfig.stylesheetName = this.ezEditTableConfig['stylesheetName']!=undefined ? f.ezEditTable_config.stylesheetName : 'ezEditTableCss'; this.ezEditTableConfig.err = 'Failed to instantiate EditTable object.\n"ezEditTable" module may not be available.'; /*** onkeyup event ***/ this.onKeyUp = f.on_keyup ? true : false; //enables/disables onkeyup event, table is filtered when user stops typing this.onKeyUpDelay = f.on_keyup_delay!=undefined ? f.on_keyup_delay : 900; //onkeyup delay timer (msecs) this.isUserTyping = null; //typing indicator this.onKeyUpTimer = undefined; /*** keyword highlighting ***/ this.highlightKeywords = f.highlight_keywords ? true : false; //enables/disables keyword highlighting this.highlightCssClass = f.highlight_css_class!=undefined ? f.highlight_css_class : 'keyword'; //defines css class for highlighting this.highlightedNodes = []; /*** data types ***/ this.defaultDateType = f.default_date_type!=undefined //defines default date type (european DMY) ? f.default_date_type : 'DMY'; this.thousandsSeparator = f.thousands_separator!=undefined //defines default thousands separator ? f.thousands_separator : ','; //US = ',' EU = '.' this.decimalSeparator = f.decimal_separator!=undefined //defines default decimal separator ? f.decimal_separator : '.'; //US & javascript = '.' EU = ',' this.hasColNbFormat = f.col_number_format ? true : false; //enables number format per column this.colNbFormat = this.hasColNbFormat ? f.col_number_format : null; //array containing columns nb formats this.hasColDateType = f.col_date_type ? true : false; //enables date type per column this.colDateType = this.hasColDateType ? f.col_date_type : null; //array containing columns date type /*** status messages ***/ this.msgFilter = f.msg_filter!=undefined ? f.msg_filter : 'Filtering data...'; //filtering this.msgPopulate = f.msg_populate!=undefined ? f.msg_populate : 'Populating filter...'; //populating drop-downs this.msgPopulateCheckList = f.msg_populate_checklist!=undefined ? f.msg_populate_checklist : 'Populating list...'; //populating drop-downs this.msgChangePage = f.msg_change_page!=undefined ? f.msg_change_page : 'Collecting paging data...'; //changing paging page this.msgClear = f.msg_clear!=undefined ? f.msg_clear : 'Clearing filters...'; //clearing filters this.msgChangeResults = f.msg_change_results!=undefined ? f.msg_change_results : 'Changing results per page...'; //changing nb results/page this.msgResetValues = f.msg_reset_grid_values!=undefined ? f.msg_reset_grid_values : 'Re-setting filters values...'; //re-setting grid values this.msgResetPage = f.msg_reset_page!=undefined ? f.msg_reset_page : 'Re-setting page...'; //re-setting page this.msgResetPageLength = f.msg_reset_page_length!=undefined ? f.msg_reset_page_length : 'Re-setting page length...'; //re-setting page length this.msgSort = f.msg_sort!=undefined ? f.msg_sort : 'Sorting data...'; //table sorting this.msgLoadExtensions = f.msg_load_extensions!=undefined ? f.msg_load_extensions : 'Loading extensions...'; //extensions loading this.msgLoadThemes = f.msg_load_themes!=undefined ? f.msg_load_themes : 'Loading theme(s)...'; //themes loading /*** ids prefixes ***/ this.prfxTf = 'TF'; //css class name added to table this.prfxFlt = 'flt'; //filters (inputs - selects) this.prfxValButton = 'btn'; //validation button this.prfxInfDiv = 'inf_'; //container div for paging elements, rows counter etc. this.prfxLDiv = 'ldiv_'; //left div this.prfxRDiv = 'rdiv_'; //right div this.prfxMDiv = 'mdiv_'; //middle div this.prfxContentDiv = 'cont_'; //table container if fixed headers enabled this.prfxCheckListDiv = 'chkdiv_'; //checklist filter container div this.prfxSlcPages = 'slcPages_'; //pages select this.prfxSlcResults = 'slcResults_'; //results per page select this.prfxSlcResultsTxt = 'slcResultsTxt_'; //label preciding results per page select this.prfxBtnNextSpan = 'btnNextSpan_'; //span containing next page button this.prfxBtnPrevSpan = 'btnPrevSpan_'; //span containing previous page button this.prfxBtnLastSpan = 'btnLastSpan_'; //span containing last page button this.prfxBtnFirstSpan = 'btnFirstSpan_'; //span containing first page button this.prfxBtnNext = 'btnNext_'; //next button this.prfxBtnPrev = 'btnPrev_'; //previous button this.prfxBtnLast = 'btnLast_'; //last button this.prfxBtnFirst = 'btnFirst_'; //first button this.prfxPgSpan = 'pgspan_'; //span for tot nb pages this.prfxPgBeforeSpan = 'pgbeforespan_'; //span preceding pages select (contains 'Page') this.prfxPgAfterSpan = 'pgafterspan_'; //span following pages select (contains ' of ') this.prfxCounter = 'counter_'; //rows counter div this.prfxTotRows = 'totrows_span_'; //nb displayed rows label this.prfxTotRowsTxt = 'totRowsTextSpan_'; //label preceding nb rows label this.prfxResetSpan = 'resetspan_'; //span containing reset button this.prfxLoader = 'load_'; //loader div this.prfxStatus = 'status_'; //status bar div this.prfxStatusSpan = 'statusSpan_'; //status bar label this.prfxStatusTxt = 'statusText_';//text preceding status bar label this.prfxCookieFltsValues = 'tf_flts_'; //filter values cookie this.prfxCookiePageNb = 'tf_pgnb_'; //page nb cookie this.prfxCookiePageLen = 'tf_pglen_'; //page length cookie this.prfxMainTblCont = 'gridCont_'; //div containing grid elements if grid_layout true this.prfxTblCont = 'tblCont_'; //div containing table if grid_layout true this.prfxHeadTblCont = 'tblHeadCont_'; //div containing headers table if grid_layout true this.prfxHeadTbl = 'tblHead_'; //headers' table if grid_layout true this.prfxGridFltTd = '_td_'; //id of td containing the filter if grid_layout true this.prfxGridTh = 'tblHeadTh_'; //id of th containing column header if grid_layout true this.prfxHelpSpan = 'helpSpan_'; //id prefix for help elements this.prfxHelpDiv = 'helpDiv_'; //id prefix for help elements this.prfxPopUpSpan = 'popUpSpan_'; //id prefix for pop-up filter span this.prfxPopUpDiv = 'popUpDiv_'; //id prefix for pop-up div containing filter /*** cookies ***/ this.hasStoredValues = false; this.rememberGridValues = f.remember_grid_values ? true : false; //remembers filters values on page load this.fltsValuesCookie = this.prfxCookieFltsValues + this.id; //cookie storing filter values this.rememberPageNb = this.paging && f.remember_page_number ? true : false; //remembers page nb on page load this.pgNbCookie = this.prfxCookiePageNb + this.id; //cookie storing page nb this.rememberPageLen = this.paging && f.remember_page_length ? true : false; //remembers page length on page load this.pgLenCookie = this.prfxCookiePageLen + this.id; //cookie storing page length this.cookieDuration = f.set_cookie_duration ? parseInt(f.set_cookie_duration) :100000; //cookie duration /*** extensions ***/ this.hasExtensions = f.extensions ? true : false; //imports external script this.extensions = (this.hasExtensions) ? f.extensions : null; /*** themes ***/ this.enableDefaultTheme = f.enable_default_theme ? true : false; this.hasThemes = (f.enable_default_theme || (f.themes && tf_IsObj(f.themes))) ? true : false; //imports themes this.themes = (this.hasThemes) ? f.themes : null; this.themesPath = f.themes_path!=undefined ? f.themes_path : this.basePath+'TF_Themes/'; //themes path /***(deprecated: backward compatibility) ***/ this.hasBindScript = f.bind_script ? true : false; //imports external script this.bindScript = (this.hasBindScript) ? f.bind_script : null; /*** TF events ***/ var o = this; this.Evt = { name: { filter: 'Filter', populateselect: 'Populate', populatechecklist: 'PopulateCheckList', changepage: 'ChangePage', clear: 'Clear', changeresultsperpage: 'ChangeResults', resetvalues: 'ResetValues', resetpage: 'ResetPage', resetpagelength: 'ResetPageLength', sort: 'Sort', loadextensions: 'LoadExtensions', loadthemes: 'LoadThemes' }, _DetectKey: function(e) /*==================================================== - common fn that detects return key for a given element (onkeypress for inputs) =====================================================*/ { if(!o.enterKey) return; var evt = e || window.event; if(evt) { var key=(evt.charCode)?evt.charCode: ((evt.keyCode)?evt.keyCode:((evt.which)?evt.which:0)); if(key=='13') { o._Filter(); tf_CancelEvent(evt); tf_StopEvent(evt); } else { o.isUserTyping = true; window.clearInterval(o.onKeyUpTimer); o.onKeyUpTimer = undefined; } }//if evt }, _OnKeyUp: function(e) /*==================================================== - onkeyup event for text filters (onKeyUp property) =====================================================*/ { if(!o.onKeyUp) return; var evt = e || window.event; var key=(evt.charCode)?evt.charCode: ((evt.keyCode)?evt.keyCode:((evt.which)?evt.which:0)); o.isUserTyping = false; if(key!=13 && key!=9 && key!=27 && key!=38 && key!=40) { function filter() { window.clearInterval(o.onKeyUpTimer); o.onKeyUpTimer = undefined; if(!o.isUserTyping) { o.Filter(); o.isUserTyping = null; } } if(o.onKeyUpTimer==undefined) o.onKeyUpTimer = window.setInterval(filter, o.onKeyUpDelay); } else { window.clearInterval(o.onKeyUpTimer); o.onKeyUpTimer = undefined; } }, _OnKeyDown: function(e) /*==================================================== - onkeydown event for input filters (onKeyUp property) =====================================================*/ { if(!o.onKeyUp) return; o.isUserTyping = true; }, _OnInpBlur: function(e) /*==================================================== - onblur event for input filters (onKeyUp property) =====================================================*/ { if(o.onKeyUp){ o.isUserTyping = false; window.clearInterval(o.onKeyUpTimer); } //Watermark if(this.value == '' && o.inpWatermark != ''){ this.value = (o.isInpWatermarkArray) ? o.inpWatermark[this.getAttribute('ct')] : o.inpWatermark; tf_AddClass(this, o.inpWatermarkCssClass); } if(o.ezEditTable){ if(o.editable) o.ezEditTable.Editable.Set(); if(o.selectable) o.ezEditTable.Selection.Set(); } }, _OnInpFocus: function(e) /*==================================================== - onfocus event for input filters =====================================================*/ { var evt = e || window.event; o.activeFilterId = this.getAttribute('id'); o.activeFlt = tf_Id(o.activeFilterId); //Watermark if(!o.isInpWatermarkArray){ if(this.value == o.inpWatermark && o.inpWatermark != ''){ this.value = ''; tf_RemoveClass(this, o.inpWatermarkCssClass); } } else { var inpWatermark = o.inpWatermark[this.getAttribute('ct')]; if(this.value == inpWatermark && inpWatermark != ''){ this.value = ''; tf_RemoveClass(this, o.inpWatermarkCssClass); } } if(o.popUpFilters){ tf_CancelEvent(evt); tf_StopEvent(evt); } if(o.ezEditTable){ if(o.editable) o.ezEditTable.Editable.Remove(); if(o.selectable) o.ezEditTable.Selection.Remove(); } }, _OnSlcFocus: function(e) /*==================================================== - onfocus event for select filters =====================================================*/ { var evt = e || window.event; o.activeFilterId = this.getAttribute('id'); o.activeFlt = tf_Id(o.activeFilterId); if(o.fillSlcOnDemand && this.getAttribute('filled') == '0') {// select is populated when element has focus var ct = this.getAttribute('ct'); o.PopulateSelect(ct); if(!tf_isIE) this.setAttribute('filled','1'); } if(o.popUpFilters){ tf_CancelEvent(evt); tf_StopEvent(evt); } }, _OnSlcChange: function(e) /*==================================================== - onchange event for select filters =====================================================*/ { //Checks filter is a checklist and caller is not null if(o.activeFlt && o.activeFlt.getAttribute('colIndex') && o['col'+o.activeFlt.getAttribute('colIndex')]==o.fltTypeCheckList && !o.Evt._OnSlcChange.caller) return; var evt = e || window.event; if(o.popUpFilters) tf_StopEvent(evt); if(o.onSlcChange) o.Filter(); }, _OnSlcBlur: function(e) /*==================================================== - onblur event for select filters =====================================================*/ {}, _OnCheckListChange: function(e) /*==================================================== - onchange event for checklist filters =====================================================*/ { //Checks caller is not null if(!o.Evt._OnCheckListChange.caller) return; o.Evt._OnSlcChange(e); }, _OnCheckListClick: function() /*==================================================== - onclick event for checklist filters =====================================================*/ { if(o.fillSlcOnDemand && this.getAttribute('filled') == '0') { var ct = this.getAttribute('ct'); o.PopulateCheckList(ct); o.checkListDiv[ct].onclick = null; o.checkListDiv[ct].title = ''; } }, _OnCheckListFocus: function(e) /*==================================================== - onclick event for checklist filter container =====================================================*/ { o.activeFilterId = this.firstChild.getAttribute('id'); o.activeFlt = tf_Id(o.activeFilterId); }, _OnCheckListBlur: function(e){}, _OnBtnClick: function() /*==================================================== - onclick event for validation button (btn property) =====================================================*/ { o.Filter(); }, _OnSlcPagesChangeEvt: null, //used by sort adapter _EnableSlc: function() /*==================================================== - onclick event slc parent node (enables filters) IE only =====================================================*/ { this.firstChild.disabled = false; this.firstChild.focus(); this.onclick = null; }, _Clear: function() /*==================================================== - clears filters =====================================================*/ { o.ClearFilters(); }, _OnHelpBtnClick: function() /*==================================================== - Help button onclick event =====================================================*/ { o._ToggleHelp(); }, _Paging: { //used by sort adapter nextEvt: null, prevEvt: null, lastEvt: null, firstEvt: null } }; }//if tbl!=null }; TF.prototype = { AddGrid: function() { this._AddGrid(); }, Init : function(){ this.AddGrid(); }, Initialize : function(){ this.AddGrid(); }, init : function(){ this.AddGrid(); }, initialize : function(){ this.AddGrid(); }, _AddGrid: function() /*==================================================== - adds row with filtering grid bar and sets grid behaviours and layout =====================================================*/ { if(this.hasGrid) return; if(this.gridLayout) this.refRow = this.startRow==undefined ? 0 : this.startRow; if(this.popUpFilters && ((this.filtersRowIndex==0 && this.headersRow == 1) || this.gridLayout)) this.headersRow = 0; var f = !this.fObj ? {} : this.fObj; var n = (this.singleSearchFlt) ? 1 : this.nbCells, inpclass; if(window['tf_'+this.id] == undefined) window['tf_'+this.id] = this; //loads stylesheet if not imported //Issues with browsers != IE, IE rules in this case this.IncludeFile(this.stylesheetId, this.stylesheet, null, 'link'); //loads theme if(this.hasThemes) this._LoadThemes(); if(this.gridLayout) { this.isExternalFlt = true; this.SetGridLayout(); //Once grid generated 1st filterable row is 0 again this.refRow = (tf_isIE || tf_isIE7) ? (this.refRow+1) : 0; } if(this.loader) this.SetLoader(); if(this.popUpFilters){ if(!this.isFirstLoad && !this.gridLayout){ this.headersRow--; } this.SetPopupFilterIcons(); } if(this.hasResultsPerPage) { this.resultsPerPage = f['results_per_page']!=undefined ? f['results_per_page'] : this.resultsPerPage; if(this.resultsPerPage.length<2) this.hasResultsPerPage = false; else this.pagingLength = this.resultsPerPage[1][0]; } if(!this.fltGrid) {//filters grid is not genetared 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) { if(!this.gridLayout){ var fltrow; var thead = tf_Tag(this.tbl,'thead'); 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 && !this.popUpFilters) this.headersRow++; if(this.popUpFilters) this.headersRow++; if(this.fixedHeaders) this.SetFixedHeaders(); fltrow.className = this.fltsRowCssClass; //Disable for grid_layout if(this.isExternalFlt && (!this.gridLayout || this.popUpFilters)) fltrow.style.display = 'none'; } this.nbFilterableRows = this.GetRowsNb(); this.nbVisibleRows = this.nbFilterableRows; this.nbRows = this.tbl.rows.length; for(var i=0; i'; //Paging buttons this.btnPrevPageHtml = ''; this.btnNextPageHtml = ''; this.btnFirstPageHtml = ''; this.btnLastPageHtml = ''; //Loader this.loader = true; this.loaderHtml = '
'; this.loaderText = null; }, RemoveGrid: function() /*==================================================== - removes a filter grid =====================================================*/ { if(this.fltGrid && this.hasGrid) { var rows = this.tbl.rows; if(this.paging) this.RemovePaging(); if(this.statusBar) this.RemoveStatusBar(); if(this.rowsCounter) this.RemoveRowsCounter(); if(this.btnReset) this.RemoveResetBtn(); if(this.helpInstructions || this.helpInstructions==null) this.RemoveHelpInstructions(); if(this.paging) this.RemoveResultsPerPage(); if(this.isExternalFlt && !this.popUpFilters) this.RemoveExternalFlts(); if(this.fixedHeaders) this.RemoveFixedHeaders(); if(this.infDiv) this.RemoveTopDiv(); if(this.highlightKeywords) this.UnhighlightAll(); if(this.sort) this.RemoveSort(); if(this.loader) this.RemoveLoader(); if(this.popUpFilters) this.RemovePopupFilters(); if(this.markActiveColumns) this.ClearActiveColumns(); if(this.editable || this.selectable) this.RemoveEditable(); for(var j=this.refRow; j 0 && !o.ezEditTableConfig.startRow) startRow = undefined; //otherwise startRow config property if any or TableFilter refRow else startRow = o.ezEditTableConfig.startRow || o.refRow; o.ezEditTableConfig.scroll_into_view = o.ezEditTableConfig.scroll_into_view!=undefined ? o.ezEditTableConfig.scroll_into_view : true; o.ezEditTableConfig.base_path = o.ezEditTableConfig.base_path!=undefined ? o.ezEditTableConfig.base_path : o.basePath + 'ezEditTable/'; o.ezEditTableConfig.editable = o.editable = o.fObj.editable; o.ezEditTableConfig.selection = o.selectable = o.fObj.selectable; if(o.selectable) o.ezEditTableConfig.default_selection = o.ezEditTableConfig.default_selection!=undefined ? o.ezEditTableConfig.default_selection : 'row'; //CSS Styles o.ezEditTableConfig.active_cell_css = o.ezEditTableConfig.active_cell_css!=undefined ? o.ezEditTableConfig.active_cell_css : 'ezETSelectedCell'; o._lastValidRowIndex = 0; o._lastRowIndex = 0; if(o.selectable){ //Row navigation needs to be calculated according to TableFilter's validRowsIndex array function onAfterSelection(et, selecteElm, e){ if(!o.validRowsIndex) return; //table is not filtered var row = et.defaultSelection != 'row' ? selecteElm.parentNode : selecteElm; var cell = selecteElm.nodeName=='TD' ? selecteElm : null; //cell for default_selection = 'both' or 'cell' var keyCode = e != undefined ? et.Event.GetKey(e) : 0; var isRowValid = o.validRowsIndex.tf_Has(row.rowIndex); var nextRowIndex; var d = (keyCode == 34 || keyCode == 33 ? (o.pagingLength || et.nbRowsPerPage) : 1); //pgup/pgdown keys //If next row is not valid, next valid filtered row needs to be calculated if(!isRowValid){ //Selection direction up/down if(row.rowIndex>o._lastRowIndex){ if(row.rowIndex >= o.validRowsIndex[o.validRowsIndex.length-1]) //last row nextRowIndex = o.validRowsIndex[o.validRowsIndex.length-1]; else{ var calcRowIndex = (o._lastValidRowIndex + d); if(calcRowIndex > (o.validRowsIndex.length-1)) nextRowIndex = o.validRowsIndex[o.validRowsIndex.length-1]; else nextRowIndex = o.validRowsIndex[calcRowIndex]; } } else{ if(row.rowIndex <= o.validRowsIndex[0]) nextRowIndex = o.validRowsIndex[0];//first row else{ var v = o.validRowsIndex[o._lastValidRowIndex - d]; nextRowIndex = v ? v : o.validRowsIndex[0]; } } o._lastRowIndex = row.rowIndex; DoSelection(nextRowIndex); } else{ //If filtered row is valid, special calculation for pgup/pgdown keys if(keyCode!=34 && keyCode!=33){ o._lastValidRowIndex = o.validRowsIndex.tf_IndexByValue(row.rowIndex); o._lastRowIndex = row.rowIndex; } else { if(keyCode == 34){ //pgdown if((o._lastValidRowIndex + d) <= (o.validRowsIndex.length-1)) //last row nextRowIndex = o.validRowsIndex[o._lastValidRowIndex + d]; else nextRowIndex = o.validRowsIndex[o.validRowsIndex.length-1]; } else { //pgup if((o._lastValidRowIndex - d) <= (o.validRowsIndex[0])) //first row nextRowIndex = o.validRowsIndex[0]; else nextRowIndex = o.validRowsIndex[o._lastValidRowIndex - d]; } o._lastRowIndex = nextRowIndex; o._lastValidRowIndex = o.validRowsIndex.tf_IndexByValue(nextRowIndex); DoSelection(nextRowIndex); } } //Next valid filtered row needs to be selected function DoSelection(nextRowIndex){ if(et.defaultSelection == 'row'){ et.Selection.SelectRowByIndex(nextRowIndex); } else { et.ClearSelections(); var cellIndex = selecteElm.cellIndex; var row = o.tbl.rows[nextRowIndex]; if(et.defaultSelection == 'both') et.Selection.SelectRowByIndex(nextRowIndex); if(row) et.Selection.SelectCell(row.cells[cellIndex]); } //Table is filtered if(o.validRowsIndex.length != o.GetRowsNb()){ var row = o.tbl.rows[nextRowIndex]; if(row) row.scrollIntoView(false); if(cell){ if(cell.cellIndex==(o.GetCellsNb()-1) && o.gridLayout) o.tblCont.scrollLeft = 100000000; else if(cell.cellIndex==0 && o.gridLayout) o.tblCont.scrollLeft = 0; else cell.scrollIntoView(false); } } } } //Page navigation has to be enforced whenever selected row is out of the current page range function onBeforeSelection(et, selecteElm, e){ var row = et.defaultSelection != 'row' ? selecteElm.parentNode : selecteElm; if(o.paging){ if(o.nbPages>1){ et.nbRowsPerPage = o.pagingLength; //page length is re-assigned in case it has changed var pagingEndRow = parseInt(o.startPagingRow) + parseInt(o.pagingLength); var rowIndex = row.rowIndex; if((rowIndex == o.validRowsIndex[o.validRowsIndex.length-1]) && o.currentPageNb!=o.nbPages) o.SetPage('last'); else if((rowIndex == o.validRowsIndex[0]) && o.currentPageNb!=1) o.SetPage('first'); else if(rowIndex > o.validRowsIndex[pagingEndRow-1] && rowIndex < o.validRowsIndex[o.validRowsIndex.length-1]) o.SetPage('next'); else if(rowIndex < o.validRowsIndex[o.startPagingRow] && rowIndex > o.validRowsIndex[0]) o.SetPage('previous'); } } } //Selected row needs to be visible when paging is activated if(o.paging){ o.onAfterChangePage = function(tf, i){ var row = tf.ezEditTable.Selection.GetActiveRow(); if(row) row.scrollIntoView(false); var cell = tf.ezEditTable.Selection.GetActiveCell(); if(cell) cell.scrollIntoView(false); } } //Rows navigation when rows are filtered is performed with the EditTable row selection callback events if(o.ezEditTableConfig.default_selection=='row'){ var fnB = o.ezEditTableConfig.on_before_selected_row; o.ezEditTableConfig.on_before_selected_row = function(){ onBeforeSelection(arguments[0], arguments[1], arguments[2]); if(fnB) fnB.call(null, arguments[0], arguments[1], arguments[2]); }; var fnA = o.ezEditTableConfig.on_after_selected_row; o.ezEditTableConfig.on_after_selected_row = function(){ onAfterSelection(arguments[0], arguments[1], arguments[2]); if(fnA) fnA.call(null, arguments[0], arguments[1], arguments[2]); }; } else { var fnB = o.ezEditTableConfig.on_before_selected_cell; o.ezEditTableConfig.on_before_selected_cell = function(){ onBeforeSelection(arguments[0], arguments[1], arguments[2]); if(fnB) fnB.call(null, arguments[0], arguments[1], arguments[2]); }; var fnA = o.ezEditTableConfig.on_after_selected_cell; o.ezEditTableConfig.on_after_selected_cell = function(){ onAfterSelection(arguments[0], arguments[1], arguments[2]); if(fnA) fnA.call(null, arguments[0], arguments[1], arguments[2]); }; } } if(o.editable){ //Added or removed rows, TF rows number needs to be re-calculated var fnC = o.ezEditTableConfig.on_added_dom_row; o.ezEditTableConfig.on_added_dom_row = function(){ o.nbFilterableRows++; if(!o.paging){ o.RefreshNbRows(); } else { o.nbRows++; o.nbVisibleRows++; o.nbFilterableRows++; o.paging=false; o.RemovePaging(); o.AddPaging(false); } if(o.alternateBgs) o.SetAlternateRows(); if(fnC) fnC.call(null, arguments[0], arguments[1], arguments[2]); }; if(o.ezEditTableConfig.actions && o.ezEditTableConfig.actions['delete']){ var fnD = o.ezEditTableConfig.actions['delete'].on_after_submit; o.ezEditTableConfig.actions['delete'].on_after_submit = function(){ o.nbFilterableRows--; if(!o.paging){ o.RefreshNbRows(); } else { o.nbRows--; o.nbVisibleRows--; o.nbFilterableRows--; o.paging=false; o.RemovePaging(); o.AddPaging(false); } if(o.alternateBgs) o.SetAlternateRows(); if(fnD) fnD.call(null, arguments[0], arguments[1]); } } } try{ o.ezEditTable = new EditTable(o.id, o.ezEditTableConfig, startRow); o.ezEditTable.Init(); } catch(e) { alert(o.ezEditTableConfig.err); } }, SetPaging: function() /*==================================================== - Generates paging elements: - pages drop-down list - previous, next, first, last buttons =====================================================*/ { if(!this.hasGrid && !this.isFirstLoad) return; if(!this.paging || (!this.isPagingRemoved && !this.isFirstLoad)) return; var f = this.fObj; this.pagingTgtId = f.paging_target_id!=undefined //id of container element ? f.paging_target_id : null; this.pagingLength = f.paging_length!=undefined ? f.paging_length : 10; //defines table paging length this.resultsPerPageTgtId = f.results_per_page_target_id!=undefined //id of container element ? f.results_per_page_target_id : null; this.pgSlcCssClass = f.paging_slc_css_class!=undefined ? f.paging_slc_css_class :'pgSlc'; //css class for paging select element this.pgInpCssClass = f.paging_inp_css_class!=undefined ? f.paging_inp_css_class :'pgNbInp'; //css class for paging input element this.resultsSlcCssClass = f.results_slc_css_class!=undefined ? f.results_slc_css_class :'rspg'; //defines css class for results per page select this.resultsSpanCssClass = f.results_span_css_class!=undefined ? f.results_span_css_class :'rspgSpan'; //css class for label preceding results per page select this.nbVisibleRows = 0; //nb visible rows this.nbHiddenRows = 0; //nb hidden rows this.startPagingRow = 0; //1st row index of current page this.nbPages = 0; //total nb of pages this.btnNextPageText = f.btn_next_page_text!=undefined ? f.btn_next_page_text : '>'; //defines next page button text this.btnPrevPageText = f.btn_prev_page_text!=undefined ? f.btn_prev_page_text : '<'; //defines previous page button text this.btnLastPageText = f.btn_last_page_text!=undefined ? f.btn_last_page_text : '>|'; //defines last page button text this.btnFirstPageText = f.btn_first_page_text!=undefined ? f.btn_first_page_text : '|<' ; //defines first page button text this.btnNextPageHtml = f.btn_next_page_html!=undefined //defines next page button html ? f.btn_next_page_html : (!this.enableIcons ? null : ''); this.btnPrevPageHtml = f.btn_prev_page_html!=undefined //defines previous page button html ? f.btn_prev_page_html : (!this.enableIcons ? null : ''); this.btnFirstPageHtml = f.btn_first_page_html!=undefined //defines last page button html ? f.btn_first_page_html : (!this.enableIcons ? null : ''); this.btnLastPageHtml = f.btn_last_page_html!=undefined //defines previous page button html ? f.btn_last_page_html : (!this.enableIcons ? null : ''); this.pageText = f.page_text!=undefined ? f.page_text : ' Page '; //defines text preceeding page selector drop-down this.ofText = f.of_text!=undefined ? f.of_text : ' of '; //defines text after page selector drop-down this.nbPgSpanCssClass = f.nb_pages_css_class!=undefined ? f.nb_pages_css_class :'nbpg'; //css class for span containing tot nb of pages this.hasPagingBtns = f.paging_btns==false ? false : true; //enables/disables paging buttons this.pagingBtnEvents = null; //stores paging buttons events this.pageSelectorType = f.page_selector_type!=undefined ? f.page_selector_type : this.fltTypeSlc; //defines previous page button html this.onBeforeChangePage = tf_IsFn(f.on_before_change_page) ? f.on_before_change_page : null; //calls function before page is changed this.onAfterChangePage = tf_IsFn(f.on_after_change_page) ? f.on_after_change_page : null; //calls function before page is changed var start_row = this.refRow; var nrows = this.nbRows; this.nbPages = Math.ceil( (nrows-start_row)/this.pagingLength );//calculates page nb //Paging elements events if(!this.Evt._Paging.next) { var o = this; this.Evt._Paging = {// paging buttons events slcIndex: function(){ return (o.pageSelectorType==o.fltTypeSlc) ? o.pagingSlc.options.selectedIndex : parseInt(o.pagingSlc.value)-1; }, nbOpts: function(){ return (o.pageSelectorType==o.fltTypeSlc) ? parseInt(o.pagingSlc.options.length)-1 : (o.nbPages-1); }, next: function(){ if(o.Evt._Paging.nextEvt) o.Evt._Paging.nextEvt(); var nextIndex = (o.Evt._Paging.slcIndex()0 ? o.Evt._Paging.slcIndex()-1 : o.Evt._Paging.nbOpts(); o.ChangePage(prevIndex); }, last: function(){ if(o.Evt._Paging.lastEvt) o.Evt._Paging.lastEvt(); o.ChangePage(o.Evt._Paging.nbOpts()); }, first: function(){ if(o.Evt._Paging.firstEvt) o.Evt._Paging.firstEvt(); o.ChangePage(0); }, _detectKey: function(e) { var evt=(e)?e:(window.event)?window.event:null; if(evt) { var key=(evt.charCode)?evt.charCode: ((evt.keyCode)?evt.keyCode:((evt.which)?evt.which:0)); if(key=='13'){ if(o.sorted){ o.Filter(); o.ChangePage(o.Evt._Paging.slcIndex()); } else o.ChangePage(); this.blur(); } }//if evt }, nextEvt: null, prevEvt: null, lastEvt: null, firstEvt: null } } if(!this.Evt._OnSlcPagesChange) { this.Evt._OnSlcPagesChange = function() /*==================================================== - onchange event for paging select =====================================================*/ { if(o.Evt._Paging._OnSlcPagesChangeEvt) o.Evt._Paging._OnSlcPagesChangeEvt(); o.ChangePage(); this.blur(); //ie only: blur is not enough... if(this.parentNode && tf_isIE) this.parentNode.focus(); } } // Paging drop-down list selector if(this.pageSelectorType == this.fltTypeSlc) { var slcPages = tf_CreateElm( this.fltTypeSlc, ['id',this.prfxSlcPages+this.id] ); slcPages.className = this.pgSlcCssClass; slcPages.onchange = this.Evt._OnSlcPagesChange; } // Paging input selector if(this.pageSelectorType == this.fltTypeInp) { var slcPages = tf_CreateElm( this.fltTypeInp, ['id',this.prfxSlcPages+this.id], ['value',this.currentPageNb] ); slcPages.className = this.pgInpCssClass; slcPages.onkeypress = this.Evt._Paging._detectKey; } var btnNextSpan, btnPrevSpan, btnLastSpan, btnFirstSpan;// btns containers btnNextSpan = tf_CreateElm('span',['id',this.prfxBtnNextSpan+this.id]); btnPrevSpan = tf_CreateElm('span',['id',this.prfxBtnPrevSpan+this.id]); btnLastSpan = tf_CreateElm('span',['id',this.prfxBtnLastSpan+this.id]); btnFirstSpan = tf_CreateElm('span',['id',this.prfxBtnFirstSpan+this.id]); if(this.hasPagingBtns) { if(this.btnNextPageHtml==null) {// Next button var btn_next = tf_CreateElm( this.fltTypeInp,['id',this.prfxBtnNext+this.id], ['type','button'],['value',this.btnNextPageText],['title','Next'] ); btn_next.className = this.btnPageCssClass; btn_next.onclick = this.Evt._Paging.next; btnNextSpan.appendChild(btn_next); } else { btnNextSpan.innerHTML = this.btnNextPageHtml; btnNextSpan.onclick = this.Evt._Paging.next; } if(this.btnPrevPageHtml==null) {// Previous button var btn_prev = tf_CreateElm( this.fltTypeInp,['id',this.prfxBtnPrev+this.id], ['type','button'],['value',this.btnPrevPageText],['title','Previous'] ); btn_prev.className = this.btnPageCssClass; btn_prev.onclick = this.Evt._Paging.prev; btnPrevSpan.appendChild(btn_prev); } else { btnPrevSpan.innerHTML = this.btnPrevPageHtml; btnPrevSpan.onclick = this.Evt._Paging.prev; } if(this.btnLastPageHtml==null) {// Last button var btn_last = tf_CreateElm( this.fltTypeInp,['id',this.prfxBtnLast+this.id], ['type','button'],['value',this.btnLastPageText],['title','Last'] ); btn_last.className = this.btnPageCssClass; btn_last.onclick = this.Evt._Paging.last; btnLastSpan.appendChild(btn_last); } else { btnLastSpan.innerHTML = this.btnLastPageHtml; btnLastSpan.onclick = this.Evt._Paging.last; } if(this.btnFirstPageHtml==null) {// First button var btn_first = tf_CreateElm( this.fltTypeInp,['id',this.prfxBtnFirst+this.id], ['type','button'],['value',this.btnFirstPageText],['title','First'] ); btn_first.className = this.btnPageCssClass; btn_first.onclick = this.Evt._Paging.first; btnFirstSpan.appendChild(btn_first); } else { btnFirstSpan.innerHTML = this.btnFirstPageHtml; btnFirstSpan.onclick = this.Evt._Paging.first; } }//if this.hasPagingBtns // paging elements (buttons+drop-down list) are added to defined element if(this.pagingTgtId==null) this.SetTopDiv(); var targetEl = ( this.pagingTgtId==null ) ? this.mDiv : tf_Id( this.pagingTgtId ); /*** if paging previously removed this prevents IE memory leak with removeChild used in RemovePaging method. For more info refer to http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2840253&SiteID=1 ***/ if ( targetEl.innerHTML!='' ) targetEl.innerHTML = ''; /*** ***/ targetEl.appendChild(btnFirstSpan); targetEl.appendChild(btnPrevSpan); var pgBeforeSpan = tf_CreateElm( 'span',['id',this.prfxPgBeforeSpan+this.id] ); pgBeforeSpan.appendChild( tf_CreateText(this.pageText) ); pgBeforeSpan.className = this.nbPgSpanCssClass; targetEl.appendChild(pgBeforeSpan); targetEl.appendChild(slcPages); var pgAfterSpan = tf_CreateElm( 'span',['id',this.prfxPgAfterSpan+this.id] ); pgAfterSpan.appendChild( tf_CreateText(this.ofText) ); pgAfterSpan.className = this.nbPgSpanCssClass; targetEl.appendChild(pgAfterSpan) var pgspan = tf_CreateElm( 'span',['id',this.prfxPgSpan+this.id] ); pgspan.className = this.nbPgSpanCssClass; pgspan.appendChild( tf_CreateText(' '+this.nbPages+' ') ); targetEl.appendChild(pgspan); targetEl.appendChild(btnNextSpan); targetEl.appendChild(btnLastSpan); this.pagingSlc = tf_Id(this.prfxSlcPages+this.id); //to be easily re-used // if this.rememberGridValues==true this.SetPagingInfo() is called // in ResetGridValues() method if( !this.rememberGridValues || this.isPagingRemoved ) this.SetPagingInfo(); if( !this.fltGrid ) { this.ValidateAllRows(); this.SetPagingInfo(this.validRowsIndex); } this.pagingBtnEvents = this.Evt._Paging; this.isPagingRemoved = false; }, RemovePaging: function() /*==================================================== - Removes paging elements =====================================================*/ { if(!this.hasGrid) return; if( this.pagingSlc==null ) return; var btnNextSpan, btnPrevSpan, btnLastSpan, btnFirstSpan;// btns containers var pgBeforeSpan, pgAfterSpan, pgspan; btnNextSpan = tf_Id(this.prfxBtnNextSpan+this.id); btnPrevSpan = tf_Id(this.prfxBtnPrevSpan+this.id); btnLastSpan = tf_Id(this.prfxBtnLastSpan+this.id); btnFirstSpan = tf_Id(this.prfxBtnFirstSpan+this.id); pgBeforeSpan = tf_Id(this.prfxPgBeforeSpan+this.id);//span containing 'Page' text pgAfterSpan = tf_Id(this.prfxPgAfterSpan+this.id);//span containing 'of' text pgspan = tf_Id(this.prfxPgSpan+this.id);//span containing nb of pages this.pagingSlc.parentNode.removeChild(this.pagingSlc); if( btnNextSpan!=null ) btnNextSpan.parentNode.removeChild( btnNextSpan ); if( btnPrevSpan!=null ) btnPrevSpan.parentNode.removeChild( btnPrevSpan ); if( btnLastSpan!=null ) btnLastSpan.parentNode.removeChild( btnLastSpan ); if( btnFirstSpan!=null ) btnFirstSpan.parentNode.removeChild( btnFirstSpan ); if( pgBeforeSpan!=null ) pgBeforeSpan.parentNode.removeChild( pgBeforeSpan ); if( pgAfterSpan!=null ) pgAfterSpan.parentNode.removeChild( pgAfterSpan ); if( pgspan!=null ) pgspan.parentNode.removeChild( pgspan ); this.pagingBtnEvents = null; this.pagingSlc = null; this.isPagingRemoved = true; }, SetPagingInfo: function( validRows ) /*==================================================== - calculates page # according to valid rows - refreshes paging select according to page # - Calls GroupByPage method =====================================================*/ { var row = this.tbl.rows; var mdiv = ( this.pagingTgtId==null ) ? this.mDiv : tf_Id( this.pagingTgtId ); var pgspan = tf_Id(this.prfxPgSpan+this.id); if( validRows!=undefined ) this.validRowsIndex = validRows;//stores valid rows index else { this.validRowsIndex = [];//re-sets valid rows index for(var j=this.refRow; j0 ) { mdiv.style.visibility = 'visible'; if(this.pageSelectorType==this.fltTypeSlc) for(var z=0; z