devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
1,344 lines (1,247 loc) • 73.9 kB
JavaScript
"use strict";
var $ = require("../../core/renderer"),
windowUtils = require("../../core/utils/window"),
window = windowUtils.getWindow(),
eventsEngine = require("../../events/core/events_engine"),
registerComponent = require("../../core/component_registrator"),
getPublicElement = require("../../core/utils/dom").getPublicElement,
stringUtils = require("../../core/utils/string"),
commonUtils = require("../../core/utils/common"),
each = require("../../core/utils/iterator").each,
isDefined = require("../../core/utils/type").isDefined,
extend = require("../../core/utils/extend").extend,
clickEvent = require("../../events/click"),
messageLocalization = require("../../localization/message"),
Widget = require("../widget/ui.widget"),
eventUtils = require("../../events/utils"),
gridCoreUtils = require("../grid_core/ui.grid_core.utils"),
pivotGridUtils = require("./ui.pivot_grid.utils"),
pivotGridDataController = require("./ui.pivot_grid.data_controller"),
PivotGridDataSource = require("./data_source"),
dataAreaNamespace = require("./ui.pivot_grid.data_area"),
headersArea = require("./ui.pivot_grid.headers_area"),
fieldsArea = require("./ui.pivot_grid.fields_area"),
PivotGridFieldChooser = require("./ui.pivot_grid.field_chooser"),
PivotGridFieldChooserBase = require("./ui.pivot_grid.field_chooser_base"),
ExportMixin = require("./ui.pivot_grid.export").ExportMixin,
chartIntegrationMixin = require("./ui.pivot_grid.chart_integration"),
Popup = require("../popup"),
ContextMenu = require("../context_menu"),
deferredUtils = require("../../core/utils/deferred"),
when = deferredUtils.when,
Deferred = deferredUtils.Deferred,
DATA_AREA_CELL_CLASS = "dx-area-data-cell",
ROW_AREA_CELL_CLASS = "dx-area-row-cell",
COLUMN_AREA_CELL_CLASS = "dx-area-column-cell",
DESCRIPTION_AREA_CELL_CLASS = "dx-area-description-cell",
BORDERS_CLASS = "dx-pivotgrid-border",
PIVOTGRID_CLASS = "dx-pivotgrid",
ROW_LINES_CLASS = "dx-row-lines",
BOTTOM_ROW_CLASS = "dx-bottom-row",
BOTTOM_BORDER_CLASS = "dx-bottom-border",
FIELDS_CONTAINER_CLASS = "dx-pivotgrid-fields-container",
FIELDS_CLASS = "dx-area-fields",
FIELD_CHOOSER_POPUP_CLASS = "dx-fieldchooser-popup",
INCOMPRESSIBLE_FIELDS_CLASS = "dx-incompressible-fields",
OVERFLOW_HIDDEN_CLASS = "dx-overflow-hidden",
TR = "<tr>",
TD = "<td>",
DIV = "<div>",
TEST_HEIGHT = 66666;
function getArraySum(array) {
var sum = 0;
each(array, function (_, value) {
sum += value || 0;
});
return sum;
}
function adjustSizeArray(sizeArray, space) {
var delta = space / sizeArray.length;
for (var i = 0; i < sizeArray.length; i++) {
sizeArray[i] -= delta;
}
}
function unsubscribeScrollEvents(area) {
area.off("scroll").off("stop");
}
function subscribeToScrollEvent(area, handler) {
unsubscribeScrollEvents(area);
area.on('scroll', handler).on("stop", handler);
}
var scrollBarInfoCache = {};
function getScrollBarInfo(useNativeScrolling) {
if (scrollBarInfoCache[useNativeScrolling]) {
return scrollBarInfoCache[useNativeScrolling];
}
var scrollBarWidth = 0,
scrollBarUseNative,
options = {};
var container = $(DIV).css({
position: 'absolute',
visibility: 'hidden',
top: -1000,
left: -1000,
width: 100,
height: 100
}).appendTo("body");
var content = $('<p>').css({
width: '100%',
height: 200
}).appendTo(container);
if (useNativeScrolling !== 'auto') {
options.useNative = !!useNativeScrolling;
options.useSimulatedScrollbar = !useNativeScrolling;
}
container.dxScrollable(options);
scrollBarUseNative = container.dxScrollable('instance').option('useNative');
scrollBarWidth = scrollBarUseNative ? container.width() - content.width() : 0;
container.remove();
scrollBarInfoCache[useNativeScrolling] = {
scrollBarWidth: scrollBarWidth,
scrollBarUseNative: scrollBarUseNative
};
return scrollBarInfoCache[useNativeScrolling];
}
function getCommonBorderWidth(elements, direction) {
var borderStyleNames = direction === "width" ? ["borderLeftWidth", "borderRightWidth"] : ["borderTopWidth", "borderBottomWidth"],
width = 0;
each(elements, function (_, elem) {
var computedStyle = window.getComputedStyle(elem.get(0));
borderStyleNames.forEach(function (borderStyleName) {
width += parseFloat(computedStyle[borderStyleName]) || 0;
});
});
return width;
}
function clickedOnFieldsArea($targetElement) {
return $targetElement.closest("." + FIELDS_CLASS).length || $targetElement.find("." + FIELDS_CLASS).length;
}
/**
* @name dxPivotGridOptions.activeStateEnabled
* @publicName activeStateEnabled
* @hidden
* @inheritdoc
*/
/**
* @name dxPivotGridOptions.hoverStateEnabled
* @publicName hoverStateEnabled
* @hidden
* @inheritdoc
*/
/**
* @name dxPivotGridOptions.focusStateEnabled
* @publicName focusStateEnabled
* @hidden
* @inheritdoc
*/
/**
* @name dxPivotGridOptions.accessKey
* @publicName accessKey
* @hidden
* @inheritdoc
*/
/**
* @name dxPivotGridMethods.registerKeyHandler
* @publicName registerKeyHandler(key, handler)
* @hidden
* @inheritdoc
*/
var PivotGrid = Widget.inherit({
_getDefaultOptions: function _getDefaultOptions() {
return extend(this.callBase(), {
/**
* @name dxPivotGridOptions.scrolling
* @publicName scrolling
* @type object
*/
scrolling: {
timeout: 300,
renderingThreshold: 150,
minTimeout: 10,
/**
* @name dxPivotGridOptions.scrolling.mode
* @publicName mode
* @type Enums.PivotGridScrollingMode
* @default "standard"
*/
mode: "standard",
/**
* @name dxPivotGridOptions.scrolling.useNative
* @publicName useNative
* @type boolean
*/
useNative: "auto",
removeInvisiblePages: true
},
encodeHtml: true,
/**
* @name dxPivotGridOptions.dataSource
* @publicName dataSource
* @type Array<Object>|PivotGridDataSource|PivotGridDataSourceOptions
* @default null
*/
dataSource: null,
activeStateEnabled: false,
/**
* @name dxPivotGridOptions.fieldChooser
* @publicName fieldChooser
* @type object
*/
fieldChooser: {
minWidth: 250,
minHeight: 250,
/**
* @name dxPivotGridOptions.fieldChooser.enabled
* @publicName enabled
* @type boolean
* @default true
*/
enabled: true,
/**
* @name dxPivotGridOptions.fieldChooser.allowSearch
* @publicName allowSearch
* @type boolean
* @default false
*/
allowSearch: false,
/**
* @name dxPivotGridOptions.fieldChooser.layout
* @publicName layout
* @type Enums.PivotGridFieldChooserLayout
* @default 0
*/
layout: 0,
/**
* @name dxPivotGridOptions.fieldChooser.title
* @publicName title
* @type string
* @default "Field Chooser"
*/
title: messageLocalization.format("dxPivotGrid-fieldChooserTitle"),
/**
* @name dxPivotGridOptions.fieldChooser.width
* @publicName width
* @type number
* @default 600
*/
width: 600,
/**
* @name dxPivotGridOptions.fieldChooser.height
* @publicName height
* @type number
* @default 600
*/
height: 600,
/**
* @name dxPivotGridOptions.fieldChooser.applyChangesMode
* @publicName applyChangesMode
* @type Enums.ApplyChangesMode
* @default "instantly"
*/
applyChangesMode: "instantly"
/**
* @name dxPivotGridOptions.fieldChooser.texts
* @publicName texts
* @type object
*/
/**
* @name dxPivotGridOptions.fieldChooser.texts.columnFields
* @publicName columnFields
* @type string
* @default 'Column Fields'
*/
/**
* @name dxPivotGridOptions.fieldChooser.texts.rowFields
* @publicName rowFields
* @type string
* @default 'Row Fields'
*/
/**
* @name dxPivotGridOptions.fieldChooser.texts.dataFields
* @publicName dataFields
* @type string
* @default 'Data Fields'
*/
/**
* @name dxPivotGridOptions.fieldChooser.texts.filterFields
* @publicName filterFields
* @type string
* @default 'Filter Fields'
*/
/**
* @name dxPivotGridOptions.fieldChooser.texts.allFields
* @publicName allFields
* @type string
* @default 'All Fields'
*/
},
/**
* @name dxPivotGridOptions.onContextMenuPreparing
* @publicName onContextMenuPreparing
* @type function(e)
* @type_function_param1 e:Object
* @type_function_param1_field4 items:Array<Object>
* @type_function_param1_field5 area:string
* @type_function_param1_field6 cell:dxPivotGridPivotGridCell
* @type_function_param1_field7 cellElement:dxElement
* @type_function_param1_field8 columnIndex:number
* @type_function_param1_field9 rowIndex:number
* @type_function_param1_field10 dataFields:Array<PivotGridDataSourceOptions.fields>
* @type_function_param1_field11 rowFields:Array<PivotGridDataSourceOptions.fields>
* @type_function_param1_field12 columnFields:Array<PivotGridDataSourceOptions.fields>
* @type_function_param1_field13 field:PivotGridDataSourceOptions.fields
* @extends Action
* @action
*/
onContextMenuPreparing: null,
/**
* @name dxPivotGridOptions.allowSorting
* @publicName allowSorting
* @type boolean
* @default false
*/
allowSorting: false,
/**
* @name dxPivotGridOptions.allowSortingBySummary
* @publicName allowSortingBySummary
* @type boolean
* @default false
*/
allowSortingBySummary: false,
/**
* @name dxPivotGridOptions.allowFiltering
* @publicName allowFiltering
* @type boolean
* @default false
*/
allowFiltering: false,
/**
* @name dxPivotGridOptions.allowExpandAll
* @publicName allowExpandAll
* @type boolean
* @default false
*/
allowExpandAll: false,
/**
* @name dxPivotGridOptions.wordWrapEnabled
* @publicName wordWrapEnabled
* @type boolean
* @default true
*/
wordWrapEnabled: true,
/**
* @name dxPivotGridOptions.fieldPanel
* @publicName fieldPanel
* @type object
*/
fieldPanel: {
/**
* @name dxPivotGridOptions.fieldPanel.showColumnFields
* @publicName showColumnFields
* @type boolean
* @default true
*/
showColumnFields: true,
/**
* @name dxPivotGridOptions.fieldPanel.showFilterFields
* @publicName showFilterFields
* @type boolean
* @default true
*/
showFilterFields: true,
/**
* @name dxPivotGridOptions.fieldPanel.showDataFields
* @publicName showDataFields
* @type boolean
* @default true
*/
showDataFields: true,
/**
* @name dxPivotGridOptions.fieldPanel.showRowFields
* @publicName showRowFields
* @type boolean
* @default true
*/
showRowFields: true,
/**
* @name dxPivotGridOptions.fieldPanel.allowFieldDragging
* @publicName allowFieldDragging
* @type boolean
* @default true
*/
allowFieldDragging: true,
/**
* @name dxPivotGridOptions.fieldPanel.visible
* @publicName visible
* @type boolean
* @default false
*/
visible: false,
/**
* @name dxPivotGridOptions.fieldPanel.texts
* @publicName texts
* @type object
*/
texts: {
/**
* @name dxPivotGridOptions.fieldPanel.texts.columnFieldArea
* @publicName columnFieldArea
* @type string
* @default "Drop Column Fields Here"
*/
columnFieldArea: messageLocalization.format("dxPivotGrid-columnFieldArea"),
/**
* @name dxPivotGridOptions.fieldPanel.texts.rowFieldArea
* @publicName rowFieldArea
* @type string
* @default "Drop Row Fields Here"
*/
rowFieldArea: messageLocalization.format("dxPivotGrid-rowFieldArea"),
/**
* @name dxPivotGridOptions.fieldPanel.texts.filterFieldArea
* @publicName filterFieldArea
* @type string
* @default "Drop Filter Fields Here"
*/
filterFieldArea: messageLocalization.format("dxPivotGrid-filterFieldArea"),
/**
* @name dxPivotGridOptions.fieldPanel.texts.dataFieldArea
* @publicName dataFieldArea
* @type string
* @default "Drop Data Fields Here"
*/
dataFieldArea: messageLocalization.format("dxPivotGrid-dataFieldArea")
}
},
/**
* @name dxPivotGridOptions.dataFieldArea
* @publicName dataFieldArea
* @type Enums.PivotGridDataFieldArea
* @default "column"
*/
dataFieldArea: "column",
/**
* @name dxPivotGridOptions.export
* @publicName export
* @type object
*/
"export": {
/**
* @name dxPivotGridOptions.export.enabled
* @publicName enabled
* @type boolean
* @default false
*/
enabled: false,
/**
* @name dxPivotGridOptions.export.fileName
* @publicName fileName
* @type string
* @default "PivotGrid"
*/
fileName: "PivotGrid",
/**
* @name dxPivotGridOptions.export.proxyUrl
* @publicName proxyUrl
* @type string
* @default undefined
*/
proxyUrl: undefined,
/**
* @name dxPivotGridOptions.export.ignoreExcelErrors
* @publicName ignoreExcelErrors
* @type boolean
* @default true
*/
ignoreExcelErrors: true
},
/**
* @name dxPivotGridOptions.showRowTotals
* @publicName showRowTotals
* @type boolean
* @default true
*/
showRowTotals: true,
/**
* @name dxPivotGridOptions.showRowGrandTotals
* @publicName showRowGrandTotals
* @type boolean
* @default true
*/
showRowGrandTotals: true,
/**
* @name dxPivotGridOptions.showColumnTotals
* @publicName showColumnTotals
* @type boolean
* @default true
*/
showColumnTotals: true,
/**
* @name dxPivotGridOptions.showColumnGrandTotals
* @publicName showColumnGrandTotals
* @type boolean
* @default true
*/
showColumnGrandTotals: true,
/**
* @name dxPivotGridOptions.hideEmptySummaryCells
* @publicName hideEmptySummaryCells
* @type boolean
* @default true
*/
hideEmptySummaryCells: true,
/**
* @name dxPivotGridOptions.showTotalsPrior
* @publicName showTotalsPrior
* @type Enums.PivotGridTotalsDisplayMode
* @default "none"
*/
showTotalsPrior: "none",
/**
* @name dxPivotGridOptions.rowHeaderLayout
* @publicName rowHeaderLayout
* @type Enums.PivotGridRowHeadersLayout
* @default "standard"
*/
rowHeaderLayout: "standard",
/**
* @name dxPivotGridOptions.loadPanel
* @publicName loadPanel
* @type object
*/
loadPanel: {
/**
* @name dxPivotGridOptions.loadPanel.enabled
* @publicName enabled
* @type boolean
* @default true
*/
enabled: true,
/**
* @name dxPivotGridOptions.loadPanel.text
* @publicName text
* @type string
* @default 'Loading...'
*/
text: messageLocalization.format("Loading"),
/**
* @name dxPivotGridOptions.loadPanel.width
* @publicName width
* @type number
* @default 200
*/
width: 200,
/**
* @name dxPivotGridOptions.loadPanel.height
* @publicName height
* @type number
* @default 70
*/
height: 70,
/**
* @name dxPivotGridOptions.loadPanel.showIndicator
* @publicName showIndicator
* @type boolean
* @default true
*/
showIndicator: true,
/**
* @name dxPivotGridOptions.loadPanel.indicatorSrc
* @publicName indicatorSrc
* @type string
* @default ""
*/
indicatorSrc: "",
/**
* @name dxPivotGridOptions.loadPanel.showPane
* @publicName showPane
* @type boolean
* @default true
*/
showPane: true
},
/**
* @name dxPivotGridOptions.texts
* @publicName texts
* @type object
*/
texts: {
/**
* @name dxPivotGridOptions.texts.grandTotal
* @publicName grandTotal
* @type string
* @default 'Grand Total'
*/
grandTotal: messageLocalization.format("dxPivotGrid-grandTotal"),
/**
* @name dxPivotGridOptions.texts.total
* @publicName total
* @type string
* @default '{0} Total'
*/
total: messageLocalization.getFormatter("dxPivotGrid-total"),
/**
* @name dxPivotGridOptions.texts.noData
* @publicName noData
* @type string
* @default 'No data'
*/
noData: messageLocalization.format("dxDataGrid-noDataText"),
/**
* @name dxPivotGridOptions.texts.showFieldChooser
* @publicName showFieldChooser
* @type string
* @default 'Show Field Chooser'
*/
showFieldChooser: messageLocalization.format("dxPivotGrid-showFieldChooser"),
/**
* @name dxPivotGridOptions.texts.expandAll
* @publicName expandAll
* @type string
* @default 'Expand All'
*/
expandAll: messageLocalization.format("dxPivotGrid-expandAll"),
/**
* @name dxPivotGridOptions.texts.collapseAll
* @publicName collapseAll
* @type string
* @default 'Collapse All'
*/
collapseAll: messageLocalization.format("dxPivotGrid-collapseAll"),
/**
* @name dxPivotGridOptions.texts.sortColumnBySummary
* @publicName sortColumnBySummary
* @type string
* @default 'Sort {0} by This Column'
*/
sortColumnBySummary: messageLocalization.getFormatter("dxPivotGrid-sortColumnBySummary"),
/**
* @name dxPivotGridOptions.texts.sortRowBySummary
* @publicName sortRowBySummary
* @type string
* @default 'Sort {0} by This Row'
*/
sortRowBySummary: messageLocalization.getFormatter("dxPivotGrid-sortRowBySummary"),
/**
* @name dxPivotGridOptions.texts.removeAllSorting
* @publicName removeAllSorting
* @type string
* @default 'Remove All Sorting'
*/
removeAllSorting: messageLocalization.format("dxPivotGrid-removeAllSorting"),
/**
* @name dxPivotGridOptions.texts.exportToExcel
* @publicName exportToExcel
* @type string
* @default "Export to Excel file"
*/
exportToExcel: messageLocalization.format("dxDataGrid-exportToExcel"),
/**
* @name dxPivotGridOptions.texts.dataNotAvailable
* @publicName dataNotAvailable
* @type string
* @default "N/A"
*/
dataNotAvailable: messageLocalization.format("dxPivotGrid-dataNotAvailable")
},
/**
* @name dxPivotGridOptions.onCellClick
* @publicName onCellClick
* @type function(e)
* @type_function_param1 e:Object
* @type_function_param1_field4 area:string
* @type_function_param1_field5 cellElement:dxElement
* @type_function_param1_field6 cell:dxPivotGridPivotGridCell
* @type_function_param1_field7 rowIndex:number
* @type_function_param1_field8 columnIndex:number
* @type_function_param1_field9 columnFields:Array<PivotGridDataSourceOptions.fields>
* @type_function_param1_field10 rowFields:Array<PivotGridDataSourceOptions.fields>
* @type_function_param1_field11 dataFields:Array<PivotGridDataSourceOptions.fields>
* @type_function_param1_field12 jQueryEvent:jQuery.Event:deprecated(event)
* @type_function_param1_field13 event:event
* @type_function_param1_field14 cancel:boolean
* @extends Action
* @action
*/
onCellClick: null,
/**
* @name dxPivotGridOptions.onCellPrepared
* @publicName onCellPrepared
* @type function(e)
* @type_function_param1 e:object
* @type_function_param1_field4 area:string
* @type_function_param1_field5 cellElement:dxElement
* @type_function_param1_field6 cell:dxPivotGridPivotGridCell
* @type_function_param1_field7 rowIndex:number
* @type_function_param1_field8 columnIndex:number
* @extends Action
* @action
*/
onCellPrepared: null,
/**
* @name dxPivotGridOptions.showBorders
* @publicName showBorders
* @type boolean
* @default false
*/
showBorders: false,
/**
* @name dxPivotGridOptions.stateStoring
* @publicName stateStoring
* @type object
*/
stateStoring: {
/**
* @name dxPivotGridOptions.stateStoring.enabled
* @publicName enabled
* @type boolean
* @default false
*/
enabled: false,
/**
* @name dxPivotGridOptions.stateStoring.storageKey
* @publicName storageKey
* @type string
* @default null
*/
storageKey: null,
/**
* @name dxPivotGridOptions.stateStoring.type
* @publicName type
* @type Enums.StateStoringType
* @default "localStorage"
*/
type: "localStorage",
/**
* @name dxPivotGridOptions.stateStoring.customLoad
* @publicName customLoad
* @type function()
* @type_function_return Promise<Object>
*/
customLoad: null,
/**
* @name dxPivotGridOptions.stateStoring.customSave
* @publicName customSave
* @type function(state)
* @type_function_param1 state:object
*/
customSave: null,
/**
* @name dxPivotGridOptions.stateStoring.savingTimeout
* @publicName savingTimeout
* @type number
* @default 2000
*/
savingTimeout: 2000
},
onExpandValueChanging: null,
renderCellCountLimit: 20000,
/**
* @name dxPivotGridOptions.onExporting
* @publicName onExporting
* @type function(e)
* @type_function_param1 e:object
* @type_function_param1_field4 fileName:string
* @type_function_param1_field5 cancel:boolean
* @extends Action
* @action
*/
onExporting: null,
/**
* @name dxPivotGridOptions.onExported
* @publicName onExported
* @extends Action
* @action
*/
onExported: null,
/**
* @name dxPivotGridOptions.onFileSaving
* @publicName onFileSaving
* @type function(e)
* @type_function_param1 e:object
* @type_function_param1_field3 fileName:string
* @type_function_param1_field4 format:string
* @type_function_param1_field5 data:BLOB
* @type_function_param1_field6 cancel:boolean
* @extends Action
* @action
*/
onFileSaving: null,
/**
* @name dxPivotGridOptions.headerFilter
* @publicName headerFilter
* @type object
*/
headerFilter: {
/**
* @name dxPivotGridOptions.headerFilter.width
* @publicName width
* @type number
* @default 252
*/
width: 252,
/**
* @name dxPivotGridOptions.headerFilter.height
* @publicName height
* @type number
* @default 325
*/
height: 325,
/**
* @name dxPivotGridOptions.headerFilter.allowSearch
* @publicName allowSearch
* @type boolean
* @default false
*/
allowSearch: false,
/**
* @name dxPivotGridOptions.headerFilter.texts
* @publicName texts
* @type object
*/
texts: {
/**
* @name dxPivotGridOptions.headerFilter.texts.emptyValue
* @publicName emptyValue
* @type string
* @default "(Blanks)"
*/
emptyValue: messageLocalization.format("dxDataGrid-headerFilterEmptyValue"),
/**
* @name dxPivotGridOptions.headerFilter.texts.ok
* @publicName ok
* @type string
* @default "Ok"
*/
ok: messageLocalization.format("dxDataGrid-headerFilterOK"),
/**
* @name dxPivotGridOptions.headerFilter.texts.cancel
* @publicName cancel
* @type string
* @default "Cancel"
*/
cancel: messageLocalization.format("dxDataGrid-headerFilterCancel")
}
}
});
},
_getDataControllerOptions: function _getDataControllerOptions() {
var that = this;
return {
component: that,
dataSource: that.option('dataSource'),
texts: that.option('texts'),
showRowTotals: that.option('showRowTotals'),
showRowGrandTotals: that.option('showRowGrandTotals'),
showColumnTotals: that.option('showColumnTotals'),
showTotalsPrior: that.option('showTotalsPrior'),
showColumnGrandTotals: that.option('showColumnGrandTotals'),
dataFieldArea: that.option('dataFieldArea'),
rowHeaderLayout: that.option('rowHeaderLayout'),
hideEmptySummaryCells: that.option("hideEmptySummaryCells"),
onFieldsPrepared: function onFieldsPrepared(fields) {
each(fields, function (index, field) {
each(["allowSorting", "allowSortingBySummary", "allowFiltering", "allowExpandAll"], function (_, optionName) {
if (field[optionName] === undefined) {
pivotGridUtils.setFieldProperty(field, optionName, that.option(optionName));
}
});
});
}
};
},
_initDataController: function _initDataController() {
var that = this;
that._dataController && that._dataController.dispose();
that._dataController = new pivotGridDataController.DataController(that._getDataControllerOptions());
if (windowUtils.hasWindow()) {
that._dataController.changed.add(function () {
that._render();
});
}
that._dataController.scrollChanged.add(function (options) {
that._scrollLeft = options.left;
that._scrollTop = options.top;
});
that._dataController.loadingChanged.add(function (isLoading) {
that._updateLoading();
});
that._dataController.progressChanged.add(that._updateLoading.bind(that));
that._dataController.dataSourceChanged.add(function () {
that._trigger("onChanged");
});
var expandValueChanging = that.option('onExpandValueChanging');
if (expandValueChanging) {
that._dataController.expandValueChanging.add(function (e) {
expandValueChanging(e);
});
}
},
_init: function _init() {
var that = this;
that.callBase();
that._initDataController();
that._scrollLeft = that._scrollTop = null;
that._initActions();
},
_initActions: function _initActions() {
var that = this;
that._actions = {
onChanged: that._createActionByOption("onChanged"),
onContextMenuPreparing: that._createActionByOption("onContextMenuPreparing"),
onCellClick: that._createActionByOption("onCellClick"),
onExporting: that._createActionByOption("onExporting"),
onExported: that._createActionByOption("onExported"),
onFileSaving: that._createActionByOption("onFileSaving"),
onCellPrepared: that._createActionByOption("onCellPrepared")
};
},
_trigger: function _trigger(eventName, eventArg) {
this._actions[eventName](eventArg);
},
_optionValuesEqual: function _optionValuesEqual(name, oldValue, newValue) {
// T266402
if (name === "dataSource" && newValue instanceof PivotGridDataSource && oldValue instanceof PivotGridDataSource) {
return newValue === oldValue;
}
return this.callBase.apply(this, arguments);
},
_optionChanged: function _optionChanged(args) {
var that = this;
switch (args.name) {
case "dataSource":
case "allowSorting":
case "allowFiltering":
case "allowExpandAll":
case "allowSortingBySummary":
case "scrolling":
case "stateStoring":
that._initDataController();
that._fieldChooserPopup.hide();
that._renderFieldChooser();
that._invalidate();
break;
case "texts":
case "showTotalsPrior":
case "showRowTotals":
case "showRowGrandTotals":
case "showColumnTotals":
case "showColumnGrandTotals":
case "hideEmptySummaryCells":
case "dataFieldArea":
that._dataController.updateViewOptions(that._getDataControllerOptions());
break;
case "useNativeScrolling":
case "encodeHtml":
case "renderCellCountLimit":
break;
case "rtlEnabled":
that.callBase(args);
that._renderFieldChooser();
that._renderContextMenu();
windowUtils.hasWindow() && that._renderLoadPanel(that._dataArea.groupElement(), that.$element());
that._invalidate();
break;
case "export":
that._renderDescriptionArea();
break;
case "onExpandValueChanging":
break;
case "onCellClick":
case "onContextMenuPreparing":
case "onExporting":
case "onExported":
case "onFileSaving":
case "onCellPrepared":
that._actions[args.name] = that._createActionByOption(args.name);
break;
case "fieldChooser":
that._renderFieldChooser();
that._renderDescriptionArea();
break;
case "loadPanel":
if (windowUtils.hasWindow()) {
that._renderLoadPanel(that._dataArea.groupElement(), that.$element());
that._invalidate();
}
break;
case "fieldPanel":
that._renderDescriptionArea();
that._invalidate();
break;
case "headerFilter":
that._renderFieldChooser();
that._invalidate();
break;
case "showBorders":
that._tableElement().toggleClass(BORDERS_CLASS, !!args.value);
that.updateDimensions();
break;
case "wordWrapEnabled":
that._tableElement().toggleClass("dx-word-wrap", !!args.value);
that.updateDimensions();
break;
case "rowHeaderLayout":
that._tableElement().find("." + ROW_AREA_CELL_CLASS).toggleClass("dx-area-tree-view", args.value === "tree");
that._dataController.updateViewOptions(that._getDataControllerOptions());
break;
case "height":
case "width":
that._hasHeight = null;
that.callBase(args);
that.resize();
break;
default:
that.callBase(args);
}
},
_updateScrollPosition: function _updateScrollPosition(columnsArea, rowsArea, dataArea) {
var that = this,
scrollTop,
scrollLeft,
scrolled = that._scrollTop || that._scrollLeft;
if (rowsArea && !rowsArea.hasScroll() && that._hasHeight) {
that._scrollTop = null;
}
if (columnsArea && !columnsArea.hasScroll()) {
that._scrollLeft = null;
}
if (that._scrollTop !== null || that._scrollLeft !== null || scrolled || that.option("rtlEnabled")) {
scrollTop = that._scrollTop || 0;
scrollLeft = that._scrollLeft || 0;
dataArea.scrollTo({ x: scrollLeft, y: scrollTop });
columnsArea.scrollTo(scrollLeft);
rowsArea.scrollTo(scrollTop);
that._dataController.updateWindowScrollPosition(that._scrollTop);
}
},
_subscribeToEvents: function _subscribeToEvents(columnsArea, rowsArea, dataArea) {
var that = this,
scrollHandler = function scrollHandler(e) {
var scrollOffset = e.scrollOffset,
leftOffset = isDefined(scrollOffset.left) ? scrollOffset.left : that._scrollLeft,
topOffset = isDefined(scrollOffset.top) && that._hasHeight ? scrollOffset.top : that._scrollTop;
if ((that._scrollLeft || 0) !== (leftOffset || 0) || (that._scrollTop || 0) !== (topOffset || 0)) {
that._scrollLeft = leftOffset;
that._scrollTop = topOffset;
that._updateScrollPosition(columnsArea, rowsArea, dataArea);
if (that.option("scrolling.mode") === "virtual") {
that._dataController.setViewportPosition(that._scrollLeft, that._scrollTop);
}
}
};
each([columnsArea, rowsArea, dataArea], function (_, area) {
subscribeToScrollEvent(area, scrollHandler);
});
!that._hasHeight && that._dataController.subscribeToWindowScrollEvents(dataArea.groupElement());
},
_clean: commonUtils.noop,
_needDelayResizing: function _needDelayResizing(cellsInfo) {
var cellsCount = cellsInfo.length * (cellsInfo.length ? cellsInfo[0].length : 0);
return cellsCount > this.option("renderCellCountLimit");
},
_renderFieldChooser: function _renderFieldChooser() {
var that = this,
container = that._pivotGridContainer,
fieldChooserOptions = that.option("fieldChooser") || {},
toolbarItems = fieldChooserOptions.applyChangesMode === "onDemand" ? [{
toolbar: "bottom",
location: "after",
widget: "dxButton",
options: {
text: messageLocalization.format("OK"),
onClick: function onClick(e) {
that._fieldChooserPopup.$content().dxPivotGridFieldChooser("applyChanges");
that._fieldChooserPopup.hide();
}
}
}, {
toolbar: "bottom",
location: "after",
widget: "dxButton",
options: {
text: messageLocalization.format("Cancel"),
onClick: function onClick(e) {
that._fieldChooserPopup.hide();
}
}
}] : [],
fieldChooserComponentOptions = {
layout: fieldChooserOptions.layout,
texts: fieldChooserOptions.texts || {},
dataSource: that.getDataSource(),
allowSearch: fieldChooserOptions.allowSearch,
width: undefined,
height: undefined,
headerFilter: that.option("headerFilter"),
encodeHtml: that.option("encodeHtml"),
applyChangesMode: fieldChooserOptions.applyChangesMode
},
popupOptions = {
shading: false,
title: fieldChooserOptions.title,
width: fieldChooserOptions.width,
height: fieldChooserOptions.height,
showCloseButton: true,
resizeEnabled: true,
minWidth: fieldChooserOptions.minWidth,
minHeight: fieldChooserOptions.minHeight,
toolbarItems: toolbarItems,
onResize: function onResize(e) {
e.component.$content().dxPivotGridFieldChooser("updateDimensions");
},
onShown: function onShown(e) {
that._createComponent(e.component.content(), PivotGridFieldChooser, fieldChooserComponentOptions);
},
onHidden: function onHidden(e) {
var fieldChooser = e.component.$content().dxPivotGridFieldChooser("instance");
fieldChooser.resetTreeView();
fieldChooser.cancelChanges();
}
};
if (that._fieldChooserPopup) {
that._fieldChooserPopup.option(popupOptions);
that._fieldChooserPopup.$content().dxPivotGridFieldChooser(fieldChooserComponentOptions);
} else {
that._fieldChooserPopup = that._createComponent($(DIV).addClass(FIELD_CHOOSER_POPUP_CLASS).appendTo(container), Popup, popupOptions);
}
},
_renderContextMenu: function _renderContextMenu() {
var that = this,
$container = that._pivotGridContainer;
if (that._contextMenu) {
that._contextMenu.$element().remove();
}
that._contextMenu = that._createComponent($(DIV).appendTo($container), ContextMenu, {
onPositioning: function onPositioning(actionArgs) {
var event = actionArgs.event,
targetElement,
args,
items;
actionArgs.cancel = true;
if (!event) {
return;
}
targetElement = event.target.cellIndex >= 0 ? event.target : $(event.target).closest('td').get(0);
if (!targetElement) {
return;
}
args = that._createEventArgs(targetElement, event);
items = that._getContextMenuItems(args);
if (items) {
actionArgs.component.option('items', items);
actionArgs.cancel = false;
return;
}
},
onItemClick: function onItemClick(params) {
params.itemData.onItemClick && params.itemData.onItemClick(params);
},
cssClass: PIVOTGRID_CLASS,
target: that.$element()
});
},
_getContextMenuItems: function _getContextMenuItems(e) {
var that = this,
items = [],
texts = that.option("texts");
if (e.area === "row" || e.area === "column") {
var areaFields = e[e.area + "Fields"],
oppositeAreaFields = e[e.area === "column" ? "rowFields" : "columnFields"],
field = e.cell.path && areaFields[e.cell.path.length - 1],
dataSource = that.getDataSource();
if (field && field.allowExpandAll && e.cell.path.length < e[e.area + "Fields"].length) {
items.push({
beginGroup: true,
icon: "none",
text: texts.expandAll,
onItemClick: function onItemClick() {
dataSource.expandAll(field.index);
}
});
items.push({
text: texts.collapseAll,
icon: "none",
onItemClick: function onItemClick() {
dataSource.collapseAll(field.index);
}
});
}
if (e.cell.isLast) {
var sortingBySummaryItemCount = 0;
each(oppositeAreaFields, function (index, field) {
if (!field.allowSortingBySummary) {
return;
}
each(e.dataFields, function (dataIndex, dataField) {
if (isDefined(e.cell.dataIndex) && e.cell.dataIndex !== dataIndex) {
return;
}
var showDataFieldCaption = !isDefined(e.cell.dataIndex) && e.dataFields.length > 1,
textFormat = e.area === "column" ? texts.sortColumnBySummary : texts.sortRowBySummary,
checked = pivotGridUtils.findField(e.dataFields, field.sortBySummaryField) === dataIndex && (e.cell.path || []).join("/") === (field.sortBySummaryPath || []).join("/"),
text = stringUtils.format(textFormat, showDataFieldCaption ? field.caption + " - " + dataField.caption : field.caption);
items.push({
beginGroup: sortingBySummaryItemCount === 0,
icon: checked ? field.sortOrder === "desc" ? "sortdowntext" : "sortuptext" : "none",
text: text,
onItemClick: function onItemClick() {
dataSource.field(field.index, {
sortBySummaryField: dataField.caption || dataField.dataField,
sortBySummaryPath: e.cell.path,
sortOrder: field.sortOrder === "desc" ? "asc" : "desc"
});
dataSource.load();
}
});
sortingBySummaryItemCount++;
});
});
each(oppositeAreaFields, function (index, field) {
if (!field.allowSortingBySummary || !isDefined(field.sortBySummaryField)) {
return;
}
items.push({
beginGroup: sortingBySummaryItemCount === 0,
icon: "none",
text: texts.removeAllSorting,
onItemClick: function onItemClick() {
each(oppositeAreaFields, function (index, field) {
dataSource.field(field.index, {
sortBySummaryField: undefined,
sortBySummaryPath: undefined,
sortOrder: undefined
});
});
dataSource.load();
}
});
return false;
});
}
}
if (that.option("fieldChooser.enabled")) {
items.push({
beginGroup: true,
icon: "columnchooser",
text: texts.showFieldChooser,
onItemClick: function onItemClick() {
that._fieldChooserPopup.show();
}
});
}
if (that.option("export.enabled")) {
items.push({
beginGroup: true,
icon: "exportxlsx",
text: texts.exportToExcel,
onItemClick: function onItemClick() {
that.exportToExcel();
}
});
}
e.items = items;
that._trigger("onContextMenuPreparing", e);
items = e.items;
if (items && items.length) {
return items;