I am using the Angular version of DevExtreme PivotGrid. Here is my Code
import { Component, OnInit, ViewChild, HostListener } from '@angular/core';
import { Service, Sale } from './pivotgrid.service';
import PivotGridDataSource from 'devextreme/ui/pivot_grid/data_source';
import { DxPivotGridComponent } from 'devextreme-angular';
@Component({
selector: 'app-pivotgridsample',
templateUrl: './pivotgridsample.component.html',
styleUrls: ['./pivotgridsample.component.scss'],
providers: [Service]
})
export class PivotgridsampleComponent implements OnInit {
pivotGridDataSource: any;
drillDownDataSource: any;
originalData: Sale[];
@ViewChild("sales", { static: true }) salesPivotGrid: DxPivotGridComponent;
constructor(private service: Service) {
this.originalData = this.service.getSales();
this.pivotGridDataSource = new PivotGridDataSource({
fields: [{
caption: "Region",
width: 120,
dataField: "region",
area: "row"
}, {
caption: "City",
dataField: "city",
width: 150,
area: "row"
}, {
dataField: "date",
dataType: "date",
area: "column"
}, {
groupName: "date",
groupInterval: "year",
expanded: true
}, {
groupName: "date",
groupInterval: "month",
visible: false
}, {
caption: "Total",
dataField: "amount",
dataType: "number",
summaryType: "sum",
format: "currency",
area: "data"
}, {
caption: "Running Total",
dataField: "amount",
dataType: "number",
summaryType: "sum",
format: "currency",
area: "data",
runningTotal: "row",
allowCrossGroupCalculation: true
}],
store: service.getSales()
});
}
onPivotCellClick(e) {
if (e.area == "data") {
let cellValue = e.cell.value == null ? "" : e.cell.value;
let cell = e.cellElement;
this.drillDownDataSource = this.pivotGridDataSource.createDrillDownDataSource(e.cell);
// Check if there is already input attched to cell
if (cell.childNodes.length > 0) {
// Clear Cell content
cell.innerHTML = '';
// Append Textbox
cell.innerHTML = '<input type="text" class="editable" value="' + cellValue + '" style="width:100%;">'
var textBox = cell.querySelector("input.editable");
textBox.focus();
this.drillDownDataSource.load();
let groupData = this.drillDownDataSource._items;
let oData = this.originalData;
let pivotTable = this.salesPivotGrid.instance;
textBox.onkeypress = function (event) {
var keycode = (event.keyCode ? event.keyCode : event.which);
if (keycode == '13') {
var newValue = textBox.value;
cell.innerHTML = "<span>" + parseInt(newValue) + "</span>";
textBox.remove();
console.log(oData);
for (var i = 0; i < oData.length; i++) {
for (var j = 0; j < groupData.length; j++) {
if (oData[i].id == groupData[j].id) {
oData[i].amount = newValue / groupData.length;
//console.log(drillDownDataSource._items[i].amount);
}
}
}
this.setDataSource(oData)
//pivotTable.option("store", oData);
//pivotTable.dataSource.store = oData;
}
return true;
}
}
}
}
setDataSource(data:any){
alert('can be called');
}
ngOnInit() {
}
}
Here, I'm using onPivotCellClick of PivotGrid to handle my custom requirements. Basically, I'm attaching an input to a grid cell for inline editing purpose and also I'm attaching a key-press event to it.
Since, It is in plain JavaScript I'm not able to call the Angular method (i.e. setDataSource) from my input keypress callback function written in JavaScript.
Is there any way I can do this?
This problem is not about plain JavaScript but scope of this
in JavaScript.
Declare a variable that references this
and use the variable when call methods of the component inside the callback function.
onPivotCellClick(e) {
const that = this;
...
textBox.onkeypress = function (event) {
...
that.setDataSource(oData);
...
Or you can use arrow function to use this
keyword as you intended.
onPivotCellClick(e) {
textBox.onkeypress = (event) => {
...
this.setDataSource(oData);
...