/*! * Piwik - Web Analytics * * @link http://piwik.org * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later */ //----------------------------------------------------------------------------- // DataTable //----------------------------------------------------------------------------- (function ($, require) { var exports = require('piwik/UI'), UIControl = exports.UIControl; /** * This class contains the client side logic for viewing and interacting with * Piwik datatables. * * The id attribute for DataTables is set dynamically by the initNewDataTables * method, and this class instance is stored using the jQuery $.data function * with the 'uiControlObject' key. * * To find a datatable element by report (ie, 'UserSettings.getBrowser'), * use piwik.DataTable.getDataTableByReport. * * To get the dataTable JS instance (an instance of this class) for a * datatable HTML element, use $(element).data('uiControlObject'). * * @constructor */ function DataTable(element) { UIControl.call(this, element); this.init(); } DataTable._footerIconHandlers = {}; DataTable.initNewDataTables = function () { $('div.dataTable').each(function () { if (!$(this).attr('id')) { var tableType = $(this).attr('data-table-type') || 'DataTable', klass = require('piwik/UI')[tableType] || require(tableType), table = new klass(this); } }); }; DataTable.registerFooterIconHandler = function (id, handler) { var handlers = DataTable._footerIconHandlers; if (handlers[id]) { setTimeout(function () { // fail gracefully throw new Exception("DataTable footer icon handler '" + id + "' is already being used.") }, 1); return; } handlers[id] = handler; }; /** * Returns the first datatable div displaying a specific report. * * @param {string} report The report, eg, UserSettings.getWideScreen * @return {Element} The datatable div displaying the report, or undefined if * it cannot be found. */ DataTable.getDataTableByReport = function (report) { var result = undefined; $('div.dataTable').each(function () { if ($(this).attr('data-report') == report) { result = this; return false; } }); return result; }; $.extend(DataTable.prototype, UIControl.prototype, { _init: function (domElem) { // initialize your dataTable in your plugin }, //initialisation function init: function () { var domElem = this.$element; this.workingDivId = this._createDivId(); domElem.attr('id', this.workingDivId); this.loadedSubDataTable = {}; this.isEmpty = $('.pk-emptyDataTable', domElem).length > 0; this.bindEventsAndApplyStyle(domElem); this._init(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(); }, setGraphedColumn: function (columnName) { this.param.columns = columnName; }, isWithinDialog: function (domElem) { return !!$(domElem).parents('.ui-dialog').length; }, isDashboard: function () { return !!$('#dashboardWidgetsArea').length; }, //Reset DataTable filters (used before a reload or view change) resetAllFilters: function () { var self = this; var FiltersToRestore = {}; var filters = [ 'filter_column', 'filter_pattern', 'filter_column_recursive', 'filter_pattern_recursive', 'enable_filter_excludelowpop', 'filter_offset', 'filter_limit', 'filter_sort_column', 'filter_sort_order', 'disable_generic_filters', 'columns', 'flat', 'include_aggregate_rows', 'totalRows' ]; for (var key = 0; key < filters.length; key++) { 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 (var 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; } }, // 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 .loadingPiwik // 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 = function (response) { self.dataTableLoaded(response, self.workingDivId); }; } if (displayLoading) { $('#' + self.workingDivId + ' .loadingPiwik').last().css('display', 'block'); } // when switching to display graphs, reset limit if (self.param.viewDataTable && self.param.viewDataTable.indexOf('graph') === 0) { delete self.param.filter_offset; delete self.param.filter_limit; } var container = $('#' + self.workingDivId + ' .piwik-graph'); var params = {}; for (var key in self.param) { if (typeof self.param[key] != "undefined" && self.param[key] != '') params[key] = self.param[key]; } var ajaxRequest = new ajaxHelper(); ajaxRequest.addParams(params, 'get'); ajaxRequest.setCallback( function (response) { container.trigger('piwikDestroyPlot'); container.off('piwikDestroyPlot'); callbackSuccess(response); } ); ajaxRequest.setFormat('html'); ajaxRequest.send(false); }, // 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, workingDivId) { var content = $(response); var idToReplace = workingDivId || $(content).attr('id'); var dataTableSel = $('#' + idToReplace); // if the current dataTable is located 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).find('table.dataTable').addClass('subDataTable'); $(content).find('.dataTableFeatures').addClass('subDataTable'); //we force the initialisation of subdatatables dataTableSel.replaceWith(content); } else { dataTableSel.find('object').remove(); dataTableSel.replaceWith(content); } content.trigger('piwik:dataTableLoaded'); piwikHelper.lazyScrollTo(content[0], 400); return content; }, /* 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 - 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.handleLimit(domElem); self.handleSearchBox(domElem); self.handleOffsetInformation(domElem); self.handleAnnotationsButton(domElem); self.handleEvolutionAnnotations(domElem); self.handleExportBox(domElem); self.applyCosmetics(domElem); self.handleSubDataTable(domElem); self.handleConfigurationBox(domElem); self.handleColumnDocumentation(domElem); self.handleRowActions(domElem); self.handleCellTooltips(domElem); self.handleRelatedReports(domElem); self.handleTriggeredEvents(domElem); self.handleColumnHighlighting(domElem); self.handleExpandFooter(domElem); self.setFixWidthToMakeEllipsisWork(domElem); }, setFixWidthToMakeEllipsisWork: function (domElem) { var self = this; function getTableWidth(domElem) { var totalWidth = $(domElem).width(); var totalWidthTable = $('table.dataTable', domElem).width(); // fixes tables in dbstats, referrers, ... if (totalWidthTable < totalWidth) { totalWidth = totalWidthTable; } if (!totalWidth) { totalWidth = 0; } return parseInt(totalWidth, 10); } function getLabelWidth(domElem, tableWidth, minLabelWidth, maxLabelWidth) { var labelWidth = minLabelWidth; var columnsInFirstRow = $('tr:nth-child(1) td:not(.label)', domElem); var widthOfAllColumns = 0; columnsInFirstRow.each(function (index, column) { widthOfAllColumns += $(column).outerWidth(); }); if (tableWidth - widthOfAllColumns >= minLabelWidth) { labelWidth = tableWidth - widthOfAllColumns; } else if (widthOfAllColumns >= tableWidth) { labelWidth = tableWidth * 0.5; } var isWidgetized = -1 !== location.search.indexOf('module=Widgetize'); if (labelWidth > maxLabelWidth && !isWidgetized && !self.isDashboard()) { labelWidth = maxLabelWidth; // prevent for instance table in Actions-Pages is not too wide } return parseInt(labelWidth, 10); } function getLabelColumnMinWidth(domElem) { var minWidth = 0; var minWidthHead = $('thead .first.label', domElem).css('minWidth'); if (minWidthHead) { minWidth = parseInt(minWidthHead, 10); } var minWidthBody = $('tbody tr:nth-child(1) td.label', domElem).css('minWidth'); if (minWidthBody) { minWidthBody = parseInt(minWidthBody, 10); if (minWidthBody && minWidthBody > minWidth) { minWidth = minWidthBody; } } return parseInt(minWidth, 10); } function removePaddingFromWidth(domElem, labelWidth) { var firstLabel = $('tbody tr:nth-child(1) td.label', domElem); var paddingLeft = firstLabel.css('paddingLeft'); paddingLeft = paddingLeft ? parseInt(paddingLeft, 10) : 0; var paddingRight = firstLabel.css('paddingRight'); paddingRight = paddingRight ? parseInt(paddingRight, 10) : 0; labelWidth = labelWidth - paddingLeft - paddingRight; return labelWidth; } var minLabelWidth = 125; var maxLabelWidth = 440; var tableWidth = getTableWidth(domElem); var labelColumnMinWidth = getLabelColumnMinWidth(domElem); var labelColumnWidth = getLabelWidth(domElem, tableWidth, 125, 440); if (labelColumnMinWidth > labelColumnWidth) { labelColumnWidth = labelColumnMinWidth; } labelColumnWidth = removePaddingFromWidth(domElem, labelColumnWidth); if (labelColumnWidth) { $('td.label', domElem).width(labelColumnWidth); } $('td span.label', domElem).each(function () { self.tooltip($(this)); }); }, handleLimit: function (domElem) { var tableRowLimits = [5, 10, 25, 50, 100, 250, 500], evolutionLimits = { day: [30, 60, 90, 180, 365, 500], week: [4, 12, 26, 52, 104, 500], month: [3, 6, 12, 24, 36, 120], year: [3, 5, 10] }; var self = this; if (typeof self.parentId != "undefined" && self.parentId != '') { // no limit selector for subtables $('.limitSelection', domElem).remove(); return; } // configure limit control var setLimitValue, numbers, limitParamName; if (self.param.viewDataTable == 'graphEvolution') { limitParamName = 'evolution_' + self.param.period + '_last_n'; numbers = evolutionLimits[self.param.period] || tableRowLimits; setLimitValue = function (params, limit) { params[limitParamName] = limit; }; } else { numbers = tableRowLimits; limitParamName = 'filter_limit'; setLimitValue = function (params, value) { params.filter_limit = value; params.filter_offset = 0; }; } // setup limit control $('.limitSelection', domElem).append('
\
')
.click(function () {
$('.searchInput', target).val('');
$(':submit', target).submit();
});
$('.searchInput', this).after(clearImg);
}
}
);
if (this.isEmpty && !currentPattern) {
$('.dataTableSearchPattern', domElem).hide();
}
},
//behaviour for '< prev' 'next >' links and page count
handleOffsetInformation: function (domElem) {
var self = this;
$('.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);
var offsetEndDisp = offsetEnd;
if (self.param.keep_summary_row == 1) --totalRows;
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);
} else {
$(this).hide();
}
}
);
// 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 (self.param.keep_summary_row == 1) --totalRows;
if (offsetEnd < totalRows) {
$(this).css('display', 'inline');
}
})
// bind the click event to trigger the ajax request with the new offset
.click(function () {
$(this).off('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).off('click');
var offset = Number(self.param.filter_offset) - Number(self.param.filter_limit);
if (offset < 0) { offset = 0; }
self.param.filter_offset = offset;
self.param.previous = 1;
self.reloadAjaxDataTable();
}
);
},
handleEvolutionAnnotations: function (domElem) {
var self = this;
if (self.param.viewDataTable == 'graphEvolution'
&& $('.annotationView', domElem).length > 0) {
// get dates w/ annotations across evolution period (have to do it through AJAX since we
// determine placement using the elements created by jqplot)
$('.dataTableFeatures', domElem).addClass('hasEvolution');
piwik.annotations.api.getEvolutionIcons(
self.param.idSite,
self.param.date,
self.param.period,
self.param['evolution_' + self.param.period + '_last_n'],
function (response) {
var annotations = $(response),
datatableFeatures = $('.dataTableFeatures', domElem),
noteSize = 16,
annotationAxisHeight = 30 // css height + padding + margin
;
var annotationsCss = {left: 6}; // padding-left of .jqplot-graph element (in _dataTableViz_jqplotGraph.tpl)
if (!self.isDashboard() && !self.isWithinDialog(domElem)) {
annotationsCss['top'] = -datatableFeatures.height() - annotationAxisHeight + noteSize / 2;
}
// set position of evolution annotation icons
annotations.css(annotationsCss);
piwik.annotations.placeEvolutionIcons(annotations, domElem);
// add new section under axis
if (self.isDashboard() || self.isWithinDialog(domElem)) {
annotations.insertAfter($('.datatableRelatedReports', domElem));
} else {
datatableFeatures.append(annotations);
}
// reposition annotation icons every time the graph is resized
$('.piwik-graph', domElem).on('resizeGraph', function () {
piwik.annotations.placeEvolutionIcons(annotations, domElem);
});
// on hover of x-axis, show note icon over correct part of x-axis
datatableFeatures.on('mouseenter', '.evolution-annotations>span', function () {
$(this).css('opacity', 1);
});
datatableFeatures.on('mouseleave', '.evolution-annotations>span', function () {
if ($(this).attr('data-count') == 0) // only hide if there are no annotations for this note
{
$(this).css('opacity', 0);
}
});
// when clicking an annotation, show the annotation viewer for that period
datatableFeatures.on('click', '.evolution-annotations>span', function () {
var spanSelf = $(this),
date = spanSelf.attr('data-date'),
oldDate = $('.annotation-manager', domElem).attr('data-date');
if (date) {
var period = self.param.period;
if (period == 'range') {
period = 'day';
}
piwik.annotations.showAnnotationViewer(
domElem,
self.param.idSite,
date,
period,
undefined, // lastN
function (manager) {
manager.attr('data-is-range', 0);
$('.annotationView img', domElem)
.attr('title', _pk_translate('Annotations_IconDesc'));
var viewAndAdd = _pk_translate('Annotations_ViewAndAddAnnotations'),
hideNotes = _pk_translate('Annotations_HideAnnotationsFor');
// change the tooltip of the previously clicked evolution icon (if any)
if (oldDate) {
$('span', annotations).each(function () {
if ($(this).attr('data-date') == oldDate) {
$(this).attr('title', viewAndAdd.replace("%s", oldDate));
return false;
}
});
}
// change the tooltip of the clicked evolution icon
if (manager.is(':hidden')) {
spanSelf.attr('title', viewAndAdd.replace("%s", date));
}
else {
spanSelf.attr('title', hideNotes.replace("%s", date));
}
}
);
}
});
// when hover over annotation in annotation manager, highlight the annotation
// icon
var runningAnimation = null;
domElem.on('mouseenter', '.annotation', function (e) {
var date = $(this).attr('data-date');
// find the icon for this annotation
var icon = $();
$('span', annotations).each(function () {
if ($(this).attr('data-date') == date) {
icon = $('img', this);
return false;
}
});
if (icon[0] == runningAnimation) // if the animation is already running, do nothing
{
return;
}
// stop ongoing animations
$('span', annotations).each(function () {
$('img', this).removeAttr('style');
});
// start a bounce animation
icon.effect("bounce", {times: 1, distance: 10}, 1000);
runningAnimation = icon[0];
});
// reset running animation item when leaving annotations list
domElem.on('mouseleave', '.annotations', function (e) {
runningAnimation = null;
});
self.$element.trigger('piwik:annotationsLoaded');
}
);
}
},
handleAnnotationsButton: function (domElem) {
var self = this;
if (self.param.idSubtable) // no annotations for subtables, just whole reports
{
return;
}
// show the annotations view on click
$('.annotationView', domElem).click(function () {
var annotationManager = $('.annotation-manager', domElem);
if (annotationManager.length > 0
&& annotationManager.attr('data-is-range') == 1) {
if (annotationManager.is(':hidden')) {
annotationManager.slideDown('slow'); // showing
$('img', this).attr('title', _pk_translate('Annotations_IconDescHideNotes'));
}
else {
annotationManager.slideUp('slow'); // hiding
$('img', this).attr('title', _pk_translate('Annotations_IconDesc'));
}
}
else {
// show the annotation viewer for the whole date range
var lastN = self.param['evolution_' + self.param.period + '_last_n'];
piwik.annotations.showAnnotationViewer(
domElem,
self.param.idSite,
self.param.date,
self.param.period,
lastN,
function (manager) {
manager.attr('data-is-range', 1);
}
);
// change the tooltip of the view annotation icon
$('img', this).attr('title', _pk_translate('Annotations_IconDescHideNotes'));
}
});
},
// DataTable view box (simple table, all columns table, Goals table, pie graph, tag cloud, graph, ...)
handleExportBox: function (domElem) {
var self = this;
if (self.param.idSubtable) {
// no view box for subtables
return;
}
// When the (+) image is hovered, the export buttons are displayed
$('.dataTableFooterIconsShow', domElem)
.show()
.hover(function () {
$(this).fadeOut('slow');
$('.exportToFormatIcons', $(this).parent()).show('slow');
}, function () {}
);
//footer arrow position element name
self.jsViewDataTable = self.param.viewDataTable;
$('.tableAllColumnsSwitch a', domElem).show();
$('.dataTableFooterIcons .tableIcon', domElem).click(function () {
var id = $(this).attr('data-footer-icon-id');
if (!id) {
return;
}
var handler = DataTable._footerIconHandlers[id];
if (!handler) {
handler = DataTable._footerIconHandlers['table'];
}
handler(self, id);
});
//Graph icon Collapsed functionality
self.currentGraphViewIcon = 0;
self.graphViewEnabled = 0;
self.graphViewStartingThreads = 0;
self.graphViewStartingKeep = false; //show keep flag
//define collapsed icons
$('.tableGraphCollapsed a', domElem)
.each(function (i) {
if (self.jsViewDataTable == $(this).attr('data-footer-icon-id')) {
self.currentGraphViewIcon = i;
self.graphViewEnabled = true;
}
})
.each(function (i) {
if (self.currentGraphViewIcon != i) $(this).hide();
});
$('.tableGraphCollapsed', domElem).hover(
function () {
//Graph icon onmouseover
if (self.graphViewStartingThreads > 0) return self.graphViewStartingKeep = true; //exit if animation is not finished
$(this).addClass('tableIconsGroupActive');
$('a', this).each(function (i) {
if (self.currentGraphViewIcon != i || self.graphViewEnabled) {
self.graphViewStartingThreads++;
}
if (self.currentGraphViewIcon != i) {
//show other icons
$(this).show('fast', function () {self.graphViewStartingThreads--});
}
else if (self.graphViewEnabled) {
self.graphViewStartingThreads--;
}
});
self.exportToFormatHide(domElem);
},
function() {
//Graph icon onmouseout
if (self.graphViewStartingKeep) return self.graphViewStartingKeep = false; //exit while icons animate
$('a', this).each(function (i) {
if (self.currentGraphViewIcon != i) {
//hide other icons
$(this).hide('fast');
}
});
$(this).removeClass('tableIconsGroupActive');
}
);
//handle exportToFormat icons
self.exportToFormat = null;
$('.exportToFormatIcons a', domElem).click(function () {
self.exportToFormat = {};
self.exportToFormat.lastActiveIcon = this;
self.exportToFormat.target = $(this).parent().siblings('.exportToFormatItems').show('fast');
self.exportToFormat.obj = $(this).hide();
});
//close exportToFormat onClickOutside
$('body').on('mouseup', function (e) {
if (self.exportToFormat) {
self.exportToFormatHide(domElem);
}
});
$('.exportToFormatItems a', domElem)
// prevent click jacking attacks by dynamically adding the token auth when the link is clicked
.click(function () {
$(this).attr('href', function () {
var url = $(this).attr('href') + '&token_auth=' + piwik.token_auth;
var limit = $('.limitSelection>div>span', domElem).text();
var defaultLimit = $(this).attr('filter_limit');
if (!limit || 'undefined' === limit || defaultLimit == -1) {
limit = defaultLimit;
}
url += '&filter_limit=' + limit;
return url;
})
})
.attr('href', function () {
var format = $(this).attr('format');
var method = $(this).attr('methodToCall');
var segment = self.param.segment;
var label = self.param.label;
var idGoal = self.param.idGoal;
var param_date = self.param.date;
var date = $(this).attr('date');
if (typeof date != 'undefined') {
param_date = date;
}
if (typeof self.param.dateUsedInGraph != 'undefined') {
param_date = self.param.dateUsedInGraph;
}
var period = self.param.period;
var formatsUseDayNotRange = piwik.config.datatable_export_range_as_day.toLowerCase();
if (formatsUseDayNotRange.indexOf(format.toLowerCase()) != -1
&& self.param.period == 'range') {
period = 'day';
}
// Below evolution graph, show daily exports
if(self.param.period == 'range'
&& self.param.viewDataTable == "graphEvolution") {
period = 'day';
}
var str = 'index.php?module=API'
+ '&method=' + method
+ '&format=' + format
+ '&idSite=' + self.param.idSite
+ '&period=' + period
+ '&date=' + param_date
+ ( typeof self.param.filter_pattern != "undefined" ? '&filter_pattern=' + self.param.filter_pattern : '')
+ ( typeof self.param.filter_pattern_recursive != "undefined" ? '&filter_pattern_recursive=' + self.param.filter_pattern_recursive : '');
if (typeof self.param.flat != "undefined") {
str += '&flat=' + (self.param.flat == 0 ? '0' : '1');
if (typeof self.param.include_aggregate_rows != "undefined" && self.param.include_aggregate_rows) {
str += '&include_aggregate_rows=1';
}
if (!self.param.flat
&& typeof self.param.filter_pattern_recursive != "undefined"
&& self.param.filter_pattern_recursive) {
str += '&expanded=1';
}
} else {
str += '&expanded=1';
}
if (format == 'CSV' || format == 'TSV' || format == 'RSS') {
str += '&translateColumnNames=1&language=' + piwik.language;
}
if (typeof segment != 'undefined') {
str += '&segment=' + segment;
}
// Export Goals specific reports
if (typeof idGoal != 'undefined'
&& idGoal != '-1') {
str += '&idGoal=' + idGoal;
}
if (label) {
label = label.split(',');
if (label.length > 1) {
for (var i = 0; i != label.length; ++i) {
str += '&label[]=' + encodeURIComponent(label[i]);
}
} else {
str += '&label=' + encodeURIComponent(label[0]);
}
}
return str;
}
);
},
exportToFormatHide: function (domElem, noAnimation) {
var self = this;
if (self.exportToFormat) {
var animationSpeed = noAnimation ? 0 : 'fast';
self.exportToFormat.target.hide(animationSpeed);
self.exportToFormat.obj.show(animationSpeed);
self.exportToFormat = null;
}
},
handleConfigurationBox: function (domElem, callbackSuccess) {
var self = this;
if (typeof self.parentId != "undefined" && self.parentId != '') {
// no manipulation when loading subtables
return;
}
if ((typeof self.numberOfSubtables == 'undefined' || self.numberOfSubtables == 0)
&& (typeof self.param.flat == 'undefined' || self.param.flat != 1)) {
// if there are no subtables, remove the flatten action
$('.dataTableFlatten', domElem).parent().remove();
}
var ul = $('div.tableConfiguration ul', domElem);
function hideConfigurationIcon() {
// hide the icon when there are no actions available or we're not in a table view
$('div.tableConfiguration', domElem).remove();
}
if (ul.find('li').size() == 0) {
hideConfigurationIcon();
return;
}
var icon = $('a.tableConfigurationIcon', domElem);
icon.click(function () { return false; });
var iconHighlighted = false;
ul.find('li:first').addClass('first');
ul.find('li:last').addClass('last');
ul.prepend('');
// open and close the box
var open = function () {
self.exportToFormatHide(domElem, true);
ul.addClass('open');
icon.css('opacity', 1);
};
var close = function () {
ul.removeClass('open');
icon.css('opacity', icon.hasClass('highlighted') ? .85 : .6);
};
$('div.tableConfiguration', domElem).hover(open, close);
var generateClickCallback = function (paramName, callbackAfterToggle) {
return function () {
close();
self.param[paramName] = 1 - self.param[paramName];
self.param.filter_offset = 0;
delete self.param.totalRows;
if (callbackAfterToggle) callbackAfterToggle();
self.reloadAjaxDataTable(true, callbackSuccess);
var data = {};
data[paramName] = self.param[paramName];
self.notifyWidgetParametersChange(domElem, data);
};
};
var getText = function (text, addDefault) {
text = _pk_translate(text);
if (text.indexOf('%s') > 0) {
text = text.replace('%s', '
' + _pk_translate('General_Loading') + '' +
'