Hi I have worked out how to store a hierarchical grid expanded row and I do this when my datasource updates from firebase database. And I would like to once the grid has been updated with new data expand the stored row. Problem is that it seems that I am always too early, is there a way to detect that the datasource has been updated and I should trigger the expand stored row function
this.expandedIndexes();
.
export class MainComponent {
parentKey: any;
constructor(
public firebase: AngularFireDatabase,
private fns: AngularFireFunctions,
private firebasedb: FirebaseService,
private toast: HotToastService
) {
firebase
.list('/main')
.valueChanges()
.subscribe((users) => {
this.storeExpandedIndexes();
this.mainGrid.dataSource = users; //intial data binding to grid
this.expandedIndexes();
});
firebase
.list('/main')
.snapshotChanges()
.subscribe((users) => {
this.storeExpandedIndexes();
this.mainGrid.dataSource = users; // sync server data changes to grid
this.expandedIndexes();
});
}
@ViewChild('mainGrid')
public mainGrid: GridComponent;
public editSettings: EditSettingsModel;
public toolbar: ToolbarItems[];
public filterOption: FilterSettingsModel = { type: 'Excel' };
sortOptions: { columns: { field: string; direction: string }[] };
public commandsInvoice: CommandModel[];
public dropdownRates: object[] = [
{ value: '1', text: 'Hourly' },
{ value: '0', text: 'Flat' },
];
public dropdown2: object[] = [
{ uid: 'Waiting', countryId: '1' },
{ uid: 'In Progress', countryId: '2' },
{ uid: 'Finished', countryId: '3' },
];
public dropdownParams2 = {
params: {
allowFiltering: true,
dataSource: new DataManager(this.dropdown2),
fields: { text: 'uid', value: 'uid' },
query: new Query(),
actionComplete: () => false,
},
};
public userparams = {
params: {
allowFiltering: true,
fields: { text: 'email', value: 'email' },
query: new Query(),
actionComplete: () => false,
},
};
public childGrid: GridModel = {
toolbar: ['Add', 'Delete'],
queryString: 'key',
allowResizing: true,
editSettings: {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
mode: 'Dialog',
},
columns: [
{
field: 'jobTitle',
headerText: 'Job Title',
textAlign: 'Right',
allowEditing: true,
width: 120,
},
{
field: 'worker',
headerText: 'Worker Name',
width: 100,
editType: 'dropdownedit',
edit: this.userparams,
},
{
field: 'rateType',
headerText: 'Rate Type',
width: 50,
allowEditing: true,
foreignKeyValue: 'text',
foreignKeyField: 'value',
dataSource: this.dropdownRates,
},
{
field: 'rateQty',
headerText: 'Rate Qty',
width: 50,
allowEditing: true,
},
{ field: 'ebay', headerText: 'Ebay', width: 50, allowEditing: true },
{
field: 'euroCarParts',
headerText: 'EuroCarParts',
width: 50,
allowEditing: true,
},
{ field: 'sdl', headerText: 'SDL', width: 50, allowEditing: true },
{ field: 'imex', headerText: 'IMEX', width: 50, allowEditing: true },
{ field: 'dawmac', headerText: 'Dawmac', width: 50, allowEditing: true },
{
field: 'salvageYard',
headerText: 'SalvageYard',
width: 50,
allowEditing: true,
},
{ field: 'oil', headerText: 'Oil', width: 50 },
{
field: 'priceMulti',
headerText: 'Price Multi',
width: 50,
allowEditing: true,
},
{ field: 'time', headerText: 'Spent Time', width: 50 },
{
field: 'date',
headerText: 'Date',
width: 70,
type: 'date',
format: 'dd/MM/yyyy',
editType: 'datepickeredit',
},
{ field: 'cof', headerText: 'Cof', width: 50, allowEditing: true },
{
field: 'price',
headerText: 'Final Price',
width: 50,
allowEditing: false,
},
{
field: 'salary',
headerText: 'Worker Salary',
width: 50,
allowEditing: false,
},
{ field: 'profit', headerText: 'Profit', width: 50, allowEditing: false },
],
actionComplete: (args: any) => {
switch (args.requestType) {
case 'save':
this.firebasedb.updateJobs(JSON.parse(JSON.stringify(args.data)),this.parentKey);
break;
case 'delete':
args.data.forEach((row: any) => {
this.firebasedb.removeJob(row.key, this.parentKey);
});
break;
}
},
};
public actionCompleteMain(args: any): void {
switch (args.requestType) {
case 'save':
this.firebasedb.updateMain(JSON.parse(JSON.stringify(args.data)));
break;
case 'delete':
args.data.forEach((row: any) => {
this.firebasedb.removeMain(row.key);
});
break;
}
}
public indexes;
public expandFlag = false;
// Function for storing expanded parent row indexes
storeExpandedIndexes() {
// Retrieves the expanded row elements
var expandedElements = this.mainGrid.element.querySelectorAll('.e-detailrowexpand');
this.indexes = [];
// // Parent row indexes of the expanded child Grid are pushed to global variable – “indexes”
expandedElements.forEach(ele => this.indexes.push(parseInt(ele.closest('.e-row').getAttribute("aria-rowindex"))))
}
expandedIndexes() {
this.mainGrid.detailRowModule.expand(this.indexes[0]-1)
}
detailDataBound(e: any) {
this.parentKey = e.data.key;
this.firebase
.list(`/main/${this.parentKey}/children`)
.snapshotChanges()
.subscribe((users) => {
e.childGrid.query = new Query();
e.childGrid.dataSource = users; // sync server data changes to grid
});
this.firebase
.list(`/main/${this.parentKey}/children`)
.valueChanges()
.subscribe((users) => {
e.childGrid.query = new Query();
e.childGrid.dataSource = users; //intial data binding to grid
});
}
onLoad(e): void {
// event capturing used
this.mainGrid.element.addEventListener(
'click',
this.collapseAll.bind(this),
true
);
}
collapseAll(args): void {
let tgt = args.target;
if (
tgt.closest('.e-grid').getAttribute('id') !==
this.mainGrid.element.getAttribute('id')
) {
// for child grid
if (
tgt.classList.contains('e-dtdiagonalright') ||
tgt.classList.contains('e-detailrowcollapse')
) {
tgt.closest('.e-grid').ej2_instances[0].detailRowModule.collapseAll();
}
} else if (
tgt.classList.contains('e-dtdiagonalright') ||
tgt.classList.contains('e-detailrowcollapse')
) {
// for Parent Grid Alone
this.mainGrid.detailRowModule.collapseAll();
}
}
All the datasourcechange / changed and dataStatechange events seem to trigger too early as well.