datatable.js
来自「一款可以和GOOGLE媲美的开源统计系统,运用AJAX.功能强大. 无色提示:」· JavaScript 代码 · 共 992 行 · 第 1/2 页
JS
992 行
//-----------------------------------------------------------------------------// Data Table//-----------------------------------------------------------------------------//A list of all our DataTables//Test if the object have already been initialized (multiple includes)if(typeof dataTables == "undefined") var dataTables = new Object;//DataTable constructorfunction dataTable(){ this.param = new Object;}//Prototype of the DataTable objectdataTable.prototype ={ //initialisation function init: function(workingDivId, domElem) { if(typeof domElem == "undefined") { domElem = $('#'+workingDivId); } this.workingDivId = workingDivId; this.loadedSubDataTable = new Object; this.bindEventsAndApplyStyle(domElem); this.initialized = true; }, //function triggered when user click on column sort onClickSort: function(domElem) { var self = this; var newColumnToSort = $(domElem).attr('id'); // we lookup if the column to sort was already this one, if it is the case then we switch from desc <-> asc if(self.param.filter_sort_column == newColumnToSort) { // toggle the sorted order if(this.param.filter_sort_order == 'asc') { self.param.filter_sort_order = 'desc'; } else { self.param.filter_sort_order = 'asc'; } } self.param.filter_offset = 0; self.param.filter_sort_column = newColumnToSort; self.reloadAjaxDataTable(); }, //Reset DataTable filters (used before a reload or view change) resetAllFilters: function() { var self = this; var FiltersToRestore = new Array(); filters = [ 'filter_column', 'filter_pattern', 'filter_column_recursive', 'filter_pattern_recursive', 'filter_excludelowpop', 'filter_excludelowpop_value', 'filter_offset', 'filter_limit', 'filter_sort_column', 'filter_sort_order', 'show_search' ]; for(var key in filters) { var value = filters[key]; FiltersToRestore[value] = self.param[value]; delete self.param[value]; } return FiltersToRestore; }, //Restores the filters to the values given in the array in parameters restoreAllFilters: function(FiltersToRestore) { var self = this; for(key in FiltersToRestore) { self.param[key] = FiltersToRestore[key]; } }, //Translate string parameters to javascript builtins //'true' -> true, 'false' -> false //it simplifies condition tests in the code cleanParams: function() { var self = this; for(var key in self.param) { if(self.param[key] == 'true') self.param[key]=true; if(self.param[key] == 'false') self.param[key]=false; } }, // Returns the standard Ajax request object used by the Jquery .ajax method buildAjaxRequest: function(callbackSuccess) { var self = this; //prepare the ajax request var ajaxRequest = { type: 'GET', url: self.param.pathToPiwik + 'index.php', dataType: 'html', async: true, error: ajaxHandleError, // Callback when the request fails success: callbackSuccess, // Callback when the request succeeds data: new Object }; //Extract the configuration from the datatable and pass it to the API for(var key in self.param) { if(typeof self.param[key] != "undefined") ajaxRequest.data[key] = self.param[key]; } return ajaxRequest; }, // Function called to trigger the AJAX request // The ajax request contains the function callback to trigger if the request is successful or failed // displayLoading = false When we don't want to display the Loading... DIV #loadingDataTable // for example when the script add a Loading... it self and doesn't want to display the generic Loading reloadAjaxDataTable: function(displayLoading, callbackSuccess) { var self = this; if (typeof displayLoading == "undefined") { displayLoading = true; } if (typeof callbackSuccess == "undefined") { callbackSuccess = self.dataTableLoaded; } if(displayLoading) { $('#'+self.workingDivId+' #loadingDataTable').css('display','block'); } $.ajax(self.buildAjaxRequest(callbackSuccess)); }, // Function called when the AJAX request is successful // it looks for the ID of the response and replace the very same ID // in the current page with the AJAX response dataTableLoaded: function(response) { var content = $(response); var idToReplace = $(content).attr('id'); var dataTableSel = $('#'+idToReplace); // if the current dataTable is situated inside another datatable table = $(content).parents('table.dataTable'); if(dataTableSel.parents('.dataTable').is('table')) { // we add class to the table so that we can give a different style to the subtable $(content).children('table.dataTable').addClass('subDataTable'); $(content).children('#dataTableFeatures').addClass('subDataTable'); //we force the initialisation of subdatatables dataTableSel.html( $(content).html() ); //dataTables[idToReplace].init( idToReplace, $('#'+idToReplace) ); } else { dataTableSel.html( $(content).html() ); lazyScrollTo(dataTableSel[0], 400); } }, /* This method is triggered when a new DIV is loaded, which happens - at the first loading of the page - after any AJAX loading of a DataTable This method basically add features to the DataTable, - such as column sorting, searching in the rows, displaying Next / Previous links, etc. - add styles to the cells and rows (odd / even styles) - modify some rows to add images if a span img is found, or add a link if a span urlLink is found or truncate the labels when they are too big - bind new events onclick / hover / etc. to trigger AJAX requests, nice hovertip boxes for truncated cells */ bindEventsAndApplyStyle: function(domElem) { var self = this; self.cleanParams(); self.handleSort(domElem); self.handleSearchBox(domElem); self.handleLowPopulationLink(domElem); self.handleOffsetInformation(domElem); self.handleExportBox(domElem); self.applyCosmetics(domElem); self.handleSubDataTable(domElem); }, // if sorting the columns is enabled, when clicking on a column, // - if this column was already the one used for sorting, we revert the order desc<->asc // - we send the ajax request with the new sorting information handleSort: function(domElem) { var self = this; if( self.param.enable_sort ) { $('.sortable', domElem).click( function() { $(this).unbind('click'); self.onClickSort(this); } ); // are we in a subdatatable? var currentIsSubDataTable = $(domElem).parent().hasClass('cellSubDataTable'); var prefixSortIcon = ''; if(currentIsSubDataTable) { prefixSortIcon = '_subtable_'; } var imageSortWidth = 16; var imageSortHeight = 16; // we change the style of the column currently used as sort column // adding an image and the class columnSorted to the TD $(".sortable#"+self.param.filter_sort_column+' #thDIV', domElem).parent() .addClass('columnSorted') .prepend('<div id="sortIconContainer"><img id="sortIcon" width="'+imageSortWidth+'" height="'+imageSortHeight+'" src="'+self.param.pathToPiwik+'themes/default/images/sort'+prefixSortIcon+ self.param.filter_sort_order+'.png" /></div>'); } }, // Add behaviour to the low population link handleLowPopulationLink: function(domElem, callbackSuccess) { var self = this; // Showing the link "Exclude low population" for this DIV if(self.param.show_exclude_low_population) { // Set the string for the DIV, either "Exclude low pop" or "Include all" $('#dataTableExcludeLowPopulation', domElem) .each( function() { if(Number(self.param.filter_excludelowpop) != 0) { string = _pk_translate('CoreHome_IncludeAllPopulation'); } else { string = _pk_translate('CoreHome_ExcludeLowPopulation'); } $(this).html(string); } ) // Bind a click event to the DIV that triggers the ajax request .click( function() { if(Number(self.param.filter_excludelowpop) != 0) { self.param.filter_excludelowpop = 0; self.param.filter_excludelowpop_value = 0; } else { self.param.filter_excludelowpop = self.param.filter_excludelowpop_default; self.param.filter_excludelowpop_value = self.param.filter_excludelowpop_value_default; } self.param.filter_offset = 0; self.reloadAjaxDataTable(true, callbackSuccess); } ); } }, //behaviour for the DataTable 'search box' handleSearchBox: function(domElem, callbackSuccess) { var self = this; // Showing the search box for dom element DIV and binding the event // - on the keyword DIV anywhere, if the ENTER key is pressed if(self.param.show_search) { var currentPattern = self.param.filter_pattern; if(typeof self.param.filter_pattern != "undefined" && self.param.filter_pattern.length > 0) { currentPattern = self.param.filter_pattern; } else if(typeof self.param.filter_pattern_recursive != "undefined" && self.param.filter_pattern_recursive.length > 0) { currentPattern = self.param.filter_pattern_recursive; } else { currentPattern = ''; } $('#dataTableSearchPattern', domElem) .show() .each(function(){ // when enter is pressed in the input field we submit the form $('#keyword', this) .keypress( function(e) { if(submitOnEnter(e)) { $(this).siblings(':submit').submit(); } } ) .val(currentPattern) ; $(':submit', this).submit( function() { var keyword = $(this).siblings('#keyword').val(); self.param.filter_offset = 0; if(self.param.search_recursive) { self.param.filter_column_recursive = 'label'; self.param.filter_pattern_recursive = keyword; } else { self.param.filter_column = 'label'; self.param.filter_pattern = keyword; } self.reloadAjaxDataTable(true, callbackSuccess); } ); $(':submit', this) .click( function(){ $(this).submit(); }) ; // in the case there is a searched keyword we display the RESET image if(currentPattern) { var target = this; var clearImg = $('<span style="position: relative;">\ <img src="'+self.param.pathToPiwik+'plugins/CoreHome/templates/images/reset_search.png" style="position: absolute; top: 4px; left: -15px; cursor: pointer; display: inline;" title="Clear"/>\ </span>') .click( function() { $('#keyword', target).val(''); $(':submit', target).submit(); }); $('#keyword',this).after(clearImg); } } ); } }, //behaviour for '< prev' 'next >' links and page count handleOffsetInformation: function(domElem) { var self = this; // Showing the offset information (1 - 10 of 42) for this DIV if( self.param.show_offset_information // fix konqueror that doesnt recognize the show_offset_information false for the tag cloud // and we really dont want to print Next/Previous for tag clouds && self.param.viewDataTable != 'cloud' ) { $('#dataTablePages', domElem).each( function(){ var offset = 1+Number(self.param.filter_offset); var offsetEnd = Number(self.param.filter_offset) + Number(self.param.filter_limit); var totalRows = Number(self.param.totalRows); offsetEndDisp = offsetEnd; if(offsetEnd > totalRows) offsetEndDisp = totalRows; // only show this string if there is some rows in the datatable if(totalRows != 0) { var str = sprintf(_pk_translate('CoreHome_PageOf'),offset + '-' + offsetEndDisp,totalRows); $(this).text(str); } } ); // Display the next link if the total Rows is greater than the current end row $('#dataTableNext', domElem) .each(function(){ var offsetEnd = Number(self.param.filter_offset) + Number(self.param.filter_limit); var totalRows = Number(self.param.totalRows); if(offsetEnd < totalRows) { $(this).css('display','inline'); } }) // bind the click event to trigger the ajax request with the new offset .click(function(){ $(this).unbind('click'); self.param.filter_offset = Number(self.param.filter_offset) + Number(self.param.filter_limit); self.reloadAjaxDataTable(); }) ; // Display the previous link if the current offset is not zero $('#dataTablePrevious', domElem) .each(function(){ var offset = 1+Number(self.param.filter_offset); if(offset != 1) { $(this).css('display','inline'); } } ) // bind the click event to trigger the ajax request with the new offset // take care of the negative offset, we setup 0 .click( function(){ $(this).unbind('click'); var offset = Number(self.param.filter_offset) - Number(self.param.filter_limit); if(offset < 0) { offset = 0; } self.param.filter_offset = offset; self.reloadAjaxDataTable(); } ) ; } }, //behaviour for DataTable view box (data, table, cloud, graph, ...) handleExportBox: function(domElem) { var self = this; if( !self.param.idSubtable ) { // When the (+) image is hovered, the export buttons are displayed $('#exportDataTableShow', domElem) .show() .hover( function() { $(this).fadeOut('slow'); $('#exportToFormat', $(this).parent()).show('slow'); }, function(){} ); //timeout object used to hide the datatable export buttons var timeout = null; $('#exportDataTable', domElem) .hover( function() { //display 'hand' cursor $(this).css({ cursor: "pointer"}); //cancel timeout if necessary if(timeout != null) { clearTimeout(timeout); timeout = null; } }, function() { //display standard cursor $(this).css({ cursor: "auto"}); //set a timeout that will hide export buttons after a few moments var dom = this; timeout = setTimeout(function(){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?