We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Bind Master/detail grid to database

Hi,

I saw in your documentation master/detail grid that is bind to local data, but l want to accomplish it by binding to database. I tried the codes below but couldnt succeed. Kindly assist

@Component({
  selector: 'app-manage-leave',
  templateUrl: './manage-leave.component.html',
  styleUrls: ['./manage-leave.component.css'],
  providers: [SelectionService]
})
export class ManageLeaveComponent implements OnInit {
  public dataManager: DataManager = new DataManager({
    url: 'Employees/UrlDatasource',   
    adaptor: new UrlAdaptor()
  });

   public data: any;
    public key: string = null;
   
    @ViewChild('mastergrid', {static:false}) public mastergrid: GridComponent;
    @ViewChild('detailgrid', {static:false}) public detailgrid: GridComponent;

    constructor() {
       
    }

    public ngOnInit(): void {
      this.data = this.dataManager;
    }

    public onRowSelected(args: RowSelectEventArgs): void {
        const queryData: any =  args.data;
        this.key = queryData.EmployeeId;
        const dataSource: object[] = new DataManager( {url: 'api/nextofkin', adaptor: new WebApiAdaptor()})
        .executeLocal(new Query().where('FirstName', 'equal', queryData.EmployeeId));
        this.detailgrid.dataSource = dataSource.slice(0, 5);
    }
}


Regards

Charles


30 Replies 1 reply marked as answer

NS Nithya Sivaprakasam Syncfusion Team October 5, 2022 11:10 AM

Hi Charles,


Greeting from Syncfusion support.


Query:” Bind Master/detail grid to database”


Currently, we are validating your query ”How to bind master/detail grid to database”. We will update further details on or before 07/10/2022.


Until then, we appreciate your patience.


Regards,

Nithya Sivaprakasam.



CH Charles replied to Nithya Sivaprakasam October 10, 2022 07:12 AM

Hi, 

It been past 07/10/2022 and I'm yet to get feedback from you on the grid master/detail.


Regards

Charles



NS Nithya Sivaprakasam Syncfusion Team October 10, 2022 10:52 AM

Hi Charles,


Thanks for your patience.


Query:” Bind master/detail grid to the database”


By checking your code, we could see that you have used webAPIAdaptor with executeLocal. You have used excutelocal method it is filter the data based specific condition(generate query using where and it will fetch require data alone) from local JSON. It is cause of the problem.


When generate query for data iteration on remote databinding, the DataManager will convert the query object( Query) into a server request after calling executeQuery and waits for the server response(JSON format).


Since we suggest you to use the “executeQuery” instead of “executeLocal” it will overcome the reported problem.


To achieve your requirement, please use the following code in your code.


Code:


    public onRowSelected(args: RowSelectEventArgs): void {

 

        const queryData: any =  args.data;

        this.key = queryData.EmployeeName;

        const dataSource: object[] = new DataManager( {url: 'api/nextofkin', adaptor: new WebApiAdaptor()})

        .executeQuery(new Query().where('FirstName', 'equal', queryData.EmployeeName)); // Field = FirstName, operator =”equal” key = queryData.EmployeeName

        this.detailgrid.dataSource = dataSource.slice(0, 5);

 

   }


Kindly check the below documentation for reference.


Documentation: https://ej2.syncfusion.com/angular/documentation/data/adaptors/#web-api-adaptor


Please get back to us if you need further assistance on this.


Regards,

Nithya Sivaprakasam.



CH Charles October 11, 2022 10:10 AM

Hi  Nithya,

In my project mastergrid is 'list of employees', while detailgrid is 'list of employees's next-of-kin'. These grids are bind to two different tables in the database. So l want when l select a employee from the mastergrid, then detailgrid should display the record of next-of- kin of that employee. I tried the below codes and the mastergrid was loaded but detailgrid is empty. Kindly assist

<div class="control-section">
    <div class='e-mastertext'>Master Grid</div>

    <ejs-grid #mastergrid id="mastergrid" [dataSource]='data' [selectedRowIndex]="2" (rowSelected)="onRowSelected($event)">
        <e-columns>
            <e-column field="EmployeeId" headerText="ID" width="70" [isPrimaryKey]="true"> </e-column>
            <e-column field='FirstName' headerText='First Name' width='110'></e-column>
            <e-column field='LastName' headerText='Last Name' width='110'></e-column>
            <e-column field='Address' headerText='Address' width='150'></e-column>
            <e-column field='Email' headerText='Email' width='130'></e-column>
        </e-columns>
    </ejs-grid>

    <div class='e-statustext' *ngIf="key">Showing Employee next-of-kin: <b>{{key}}</b></div>
   
    <ejs-grid #detailgrid id="detailgrid" [dataSource]=' data' [allowSelection]='false'>
        <e-columns>
            <e-column field="EmployeeId" headerText="ID" width="70"  [isPrimaryKey]="true"> </e-column>          
            <e-column field='Name' headerText="Name" width='110'></e-column>
            <e-column field='Relationship' headerText="Relationship" width='120'></e-column>  
            <e-column field='Address' headerText="Address" width='150'></e-column>        
        </e-columns>
    </ejs-grid>
</div>


Component.ts

public dataManager: DataManager = new DataManager({
    url: 'Employees/UrlDatasource',  
    adaptor: new UrlAdaptor()
  });

   public data: any;
    public key: string = null;
    public names: string[] = ['AROUT', 'BERGS', 'BLONP', 'CHOPS', 'ERNSH'];
   
    @ViewChild('mastergrid', {static:false}) public mastergrid: GridComponent;
    @ViewChild('detailgrid', {static:false}) public detailgrid: GridComponent;

    constructor() {
      this.data = data.filter((e: carType) => this.names.indexOf(e.EmployeeId) !== -1);
    }

    public ngOnInit(): void {
      this.data = this.dataManager;
    }

    public onRowSelected(args: RowSelectEventArgs): void {
        const queryData: any =  args.data;
        this.key = queryData.EmployeeId;
        const dataSource: object[] = new DataManager( {url: 'api/nextofkin', adaptor: new WebApiAdaptor()})
        .executeQuery(new Query().where('EmployeeId', 'equal', queryData.EmployeeId));
        this.detailgrid.dataSource = dataSource.slice(0, 5);
    }



Regards

Charles






NS Nithya Sivaprakasam Syncfusion Team October 12, 2022 11:20 AM

Hi Charles,


Thanks for contacting Syncfusion support.


Query:” the mastergrid was loaded but detailgrid is empty. Kindly assist”


Currently, we are validating your query and will update further details on or before 14/10/2022. Until then we appreciate your patience.


Regards,

Nithya Sivaprakasam.



PS Pavithra Subramaniyam Syncfusion Team October 13, 2022 08:51 AM

Hi Charles,


Thanks for your patience.


Based on your shred code, we have prepared a simple sample in which selecting a row from the master Grid will populate the records in the detail Grid. Please refer to the below code example and the sample link for more information.


public onRowSelected(args: any): void {

    const queryData: any = args.data;

    this.key = queryData.EmployeeID;

    if (queryData.EmployeeID) {

      // change url and adaptor based on your server

      const dataSource: object[] = new DataManager({

        url: 'https://services.odata.org/V4/Northwind/Northwind.svc/Orders/',

        adaptor: new ODataV4Adaptor(),

      })

        .executeQuery(

          new Query().where('EmployeeID''equal', queryData.EmployeeID)

        )

        .then((e: any) => {

          this.detailgrid.dataSource = e.result;

        });

    }

  }

 


Sample: https://stackblitz.com/edit/angular-kfusl6-5hm7re?file=app.component.html,app.component.ts


So we suggest modifying the way of assigning the detail Grid dataSource as per the shared sample.


Regards,

Pavithra S



CH Charles October 13, 2022 12:45 PM

Hi Pavithra,

Thank you for the solution. The master and detail grid work fine as expected. So I want to perform editing in the detailgrid but it's not working. Kindly assist


Regards

Charles



VB Vinitha Balasubramanian Syncfusion Team October 14, 2022 10:24 AM

Hi Charles,


Thanks for your update.


Currently, we are validating your reported problem, we will update you the details on or before 18th Oct 2022. Until then we appreciate your patience.


Regards,

Vinitha Balasubramanian



CH Charles October 19, 2022 08:34 AM

Hi  Vinitha,


It's past 18th Oct 2022 and i'm still waiting for your feedback. 


Regards

Charles



VB Vinitha Balasubramanian Syncfusion Team October 20, 2022 09:11 AM

Hi Charles,


Sorry for the inconvenience caused.


Based on your update, we have prepared a sample to perform editing in the detailGrid. Kindly refer the sample for your reference.


Sample link : https://stackblitz.com/edit/angular-lgtohh-gpc9pf?file=app.component.html,app.component.ts


Please get back to us for further assistance.


Regards,

Vinitha Balasubramanian

If this post is helpful, please consider Accepting it as the solution so that other members can locate it more quickly.



CH Charles October 20, 2022 12:40 PM

Hi Vinitha,


In the sample you have provided the grids are bind locally, but l want to work with database. So, the link below is my working sample that populate the mastergrid and detailgrid from the database. lt filters the detailgrid as expected when a row is selected from the mastergrid, but when l try to edit any row in the detailgrid no success. Kindly assist.

https://stackblitz.com/edit/angular-lgtohh-rrshef?file=app.component.html,app.component.ts


Regards

Charles



RR Rajapandi Ravi Syncfusion Team October 21, 2022 06:10 AM

Hi Charles,


Thanks for your update


Based on your query we suspect that you want to use the remote data for Master/Detail Grid and like to edit the detail Grid and facing the problem. Based on your requirement we have prepared a sample and tried to reproduce the reported problem, but it was working fine at our end. Please refer the below code example and sample for more information.

fetchdata.component.html 

 

<div>

 

    <ejs-grid #grid [dataSource]='data' [selectedRowIndex]='selectedRowIndex' (rowSelected)='rowSelected($event)' allowFiltering="true" allowSorting="true">

        <e-columns>

            <e-column field='OrderID' headerText='Order ID' isPrimaryKey=true width='150'></e-column>

            <e-column field='CustomerID' headerText='Customer Name' width='150'></e-column>

            <e-column field='ShipCity' headerText='ShipCity' width='150' textAlign='Right'></e-column>

        </e-columns>

    </ejs-grid>

 

    <div class='e-statustext'>Showing orders of Customer: <b>{{key}}</b></div>

 

    <ejs-grid #detailgrid [dataSource]='detail' [allowSelection]='false'  [editSettings]='detaileditSettings' [allowFiltering]='true'>

        <e-columns>

            <e-column field='OrderID' headerText='Order ID' isPrimaryKey=true width='150'></e-column>

            <e-column field='Freight' headerText='Freight' format='C2' type='number' width='120'></e-column>

            <e-column field='ShipName' headerText="Ship Name" width='140'></e-column>

            <e-column field='ShipCountry' headerText="Ship Country" width='120'></e-column>

            <e-column field='ShipAddress' headerText="Ship Address" width='140'></e-column>

            <e-column field='ShipCity' headerText='ShipCity' width='150' textAlign='Right'></e-column>

        </e-columns>

    </ejs-grid>

</div>


fetchdata.component.ts

 

export class FetchDataComponent {

    public data: any;

    public editSettings: Object;

    public toolbar: string[];

    public filterSettings: Object;

    public options: PageSettingsModel;

    public infiniteOptions: InfiniteScrollSettingsModel;

    public selectedRowIndex:any;

    public key: any = null;

    public detail: Object = [];

  @ViewChild('grid')

    public grid: GridComponent;

    public detaileditSettings: Object;

  

    @ViewChild("detailgrid") detailGrid: GridComponent;

    public query: Query;

 

    ngOnInit(): void {

        this.options = { pageSize: 50 };

        this.infiniteOptions = { initialBlocks: 5 };

        this.selectedRowIndex = 2;

        this.detaileditSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Normal' };

    this.data = new DataManager({

        url: 'Home/UrlDatasource',

        adaptor: new UrlAdaptor

    });

        this.filterSettings = { type: "Menu" };

        this.query = new Query().addParams('ej2grid', 'true').addParams("CustomValue", '123').addParams('Value', 'Test');

    }

    rowSelected(args:any) {

      

        let selRecord = args.data;

      

        let selecteMessage: any = document.getElementsByClassName(

            "e-statustext"

        )[0];

        let message: HTMLElement = selecteMessage.querySelector("b");

        message.textContent = selRecord.ShipCity;

        let employee: any = (args.data as any).ShipCity;

      

        let detaildata: any = new DataManager({

            url: 'Home/UrlDatasource',

            adaptor: new UrlAdaptor })

                .executeQuery(new Query().where('ShipCity', 'equal', employee))

                .then((e: ReturnOption) => {

                   (this.detailGrid as any).dataSource = e.result;

                });

     

    }

 

}

 

 


Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/sample-2035862095.zip

Video demo: https://www.syncfusion.com/downloads/support/directtrac/general/ze/177978vd-747355495.zip

Regards,

Rajapandi R



CH Charles October 21, 2022 08:19 AM

Hi Rajapandi,


Thank you for your efforts. Editing a row work fine in my sample, but what l mean is that the changes made in the detailgrid is not saving into the database. It does not add or update changes made to the database. When l edit a row in the detailgrid it does not effect the change made after l refresh the grid.

ngOnInit(): void {
this.options = { pageSize: 50 };
this.infiniteOptions = { initialBlocks: 5 };
this.selectedRowIndex = 2;
this.detaileditSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Normal' };
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];

this.data = new DataManager({
url: 'Employee/UrlDatasource',
adaptor: new UrlAdaptor
});
this.filterSettings = { type: "Menu" };
this.query = new Query().addParams('ej2grid', 'true').addParams("CustomValue", '123').addParams('Value', 'Test');
}

rowSelected(args:any) {
let selRecord = args.data;
let selecteMessage: any = document.getElementsByClassName(
"e-statustext"
)[0];
let message: HTMLElement = selecteMessage.querySelector("b");
message.textContent = selRecord.ShipCity;
let employee: any = (args.data as any).EmployeeId;
let detaildata: any = new DataManager({
url: 'Nextofkin/UrlDatasource',
updateUrl: 'Nextofkin/Update',
insertUrl: 'Nextofkin/Insert',
removeUrl: 'Nextofkin/Delete',
adaptor: new UrlAdaptor() })
.executeQuery(new Query().where('EmployeeId', 'equal', employee))
.then((e: ReturnOption) => {
(this.detailGrid as any).dataSource = e.result;
});
}


Regards

Charles



RS Rajapandiyan Settu Syncfusion Team October 24, 2022 06:18 AM

Hi Charles,


Based on your requirement you want to update the edited value of Detail Grid in the server. We will prepare the sample for your requirement and update the further details on or before Oct 28th, 2022.


We appreciate your patience until then.


Regards,

Rajapandiyan S



RR Rajapandi Ravi Syncfusion Team October 28, 2022 09:02 AM

Hi Charles,


Thanks for your patience


Based on your requirement we have prepared a sample to update the edited value of Detail Grid in the server and we suggest you use the below way to achieve your requirement. Please refer the below sample and video demo for more information.


 

rowSelected(args:any) {

      

        let selRecord = args.data;

      

        let selecteMessage: any = document.getElementsByClassName(

            "e-statustext"

        )[0];

        let message: HTMLElement = selecteMessage.querySelector("b");

        message.textContent = selRecord.ShipCity;

        let id: any = (args.data as any).OrderID;

      

        let detaildata: any = new DataManager({

            url: 'Home/EmployeeDatasource',

            updateUrl: 'Home/EmpUpdate',

            insertUrl: 'Home/EmpInsert',

            removeUrl: 'Home/EmpDelete',

            adaptor: new UrlAdaptor

        })

 

        let query = new Query().where('OrderID', 'equal', id);

        (this.detailGrid as any).dataSource = [];

        (this.detailGrid as any).query = query;

        (this.detailGrid as any).dataSource = detaildata;

     

    }

 


Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/sampledetail-106145715.zip


Video demo: https://www.syncfusion.com/downloads/support/directtrac/general/ze/detailvd266791032.zip


Regards,

Rajapandi R



CH Charles November 3, 2022 02:50 PM

Hi Rajapandi,


Thank you for the solution you have provided.

I have EmployeeId as my unique ID in both of my Employee Table and Next-of-kin table. So I selected a row in the mastergrid and when l click 'Add' button on detailgrid toolbar l want it to pass the unique ID of an employeeId column from Mastergrid to the new row in detailgrid EmployeeId column. Can you show me how to do it?


Regards

Charles



RR Rajapandi Ravi Syncfusion Team November 7, 2022 08:57 AM

Hi Charles,


In our sample, we have OrderID field as unique in both Master and detail Grid. While selecting row in the Master Grid we have fetched the data based on the OrderID and display the result to the detail grid. From your query we could see that, while adding a record in the detail grid you like to pass the OrderID and save the new records under the unique ID.


Based on your query we have prepared a sample and to add a new record in detail grid, We have to set the OrderID field value which was same as Master Grid selected row in the actionBegin event of detail Grid. Please refer the below code example and sample for more information.


 

<ejs-grid #grid [dataSource]='data' [selectedRowIndex]='selectedRowIndex' (rowSelected)='rowSelected($event)' allowFiltering="true" allowSorting="true">

        <e-columns>

            <e-column field='OrderID' headerText='Order ID' isPrimaryKey=true width='150'></e-column>

           <e-column field='CustomerID' headerText='Customer Name' width='150'></e-column>

            <e-column field='ShipCity' headerText='ShipCity' width='150' textAlign='Right'></e-column>

        </e-columns>

    </ejs-grid>

 

    <div class='e-statustext'>Showing orders of Customer: <b>{{key}}</b></div>

 

    <ejs-grid #detailgrid [dataSource]='detail' [allowSelection]='false' [toolbar]='detailToolbar' (actionBegin)="actionBegin($event)"  [editSettings]='detaileditSettings' [allowFiltering]='true'>

        <e-columns>

            <e-column field='OrderID' headerText='Order ID' isPrimaryKey=true allowEditing="false" width='150'></e-column>

            <e-column field='FirstName' headerText="First Name" width='140'></e-column>

            <e-column field='LastName' headerText="Last Name" width='120'></e-column>

        </e-columns>

    </ejs-grid>

 

Fetchdata.component.ts

 

actionBegin(args: any) { //actionBegin event of detail Grid

        console.log(args);

        if (args.requestType === 'add') {

            args.data.OrderID = (this.grid.getSelectedRecords()[0] as any).OrderID; //based on master Grid row selection we can get the unique field and set the value to the detail Grid

        }

    }


Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/sample1219816737.zip


Screenshot:



Regards,

Rajapandi R



CH Charles November 12, 2022 01:18 PM

Hi Rajapandi,


  1. Deleting row in the master grid work fine, but when l check the database the detail grid rows that is bind to the master grid's row was not deleted. I want when l click on delete button from the master grid it should delete the row in both master & detail grid that is bind via the unique ID.
  2. In my detail grid l have 'Unit Price', 'Quantity', 'Amount Total '. Whenever l have enter a value in any of UnitPrice or Quantity it should calculate and display in the Amount Total,
  3. I have a 'Grand Total' column in master grid. So the 'Amount Total' values of the detail grid should sum and cumulatively display in the 'Grand Total' of the master grid after l click save. For instance in the detail grid, the sum of 'Amount Total' for 3 rows should be display in the master grid's Grand Total. Kindly assist


Rgards

Charles



RR Rajapandi Ravi Syncfusion Team November 14, 2022 08:48 AM

Hi Charles,


Thanks for your update


Before we start providing solution to your query, please share the below details that will be helpful for us to provide better solution.


1)             Share your exact requirement of each query with detailed description.


2)             Share your requirement in pictorial or video demonstration that will be helpful for us to provide solution on your exact requirement case.


3)             Please share any issue reproducible sample or try to reproduce the issue with our above attached sample.


Regards,

Rajapandi R



CH Charles November 14, 2022 02:22 PM

Hi Rajapandi,


  1. In my detail grid l have 'Unit Price', 'Quantity', 'Amount '. During editing whenever l enter a value in any of UnitPrice or Quantity it should multiply and display the result in the Amount column, i.e Quantity*UnitPrice = Amount
  2. When l delete a row let say InvoiceNo:1001 from the master grid, I want it to also delete InvoiceNo:1001 from the detail grid. When l check the database the selected master grid row have been deleted but the detail grid was not successful.
  3. In my master grid l have a column called 'GrandTotal'. So, I want the sumation of 'Amount' column from the detail grid to display in the GrandTotal Column of the master grid. i.e. see below table

Master grid

Invoice Number

Grand Total

1001

1700


Detail grid

Invoice Number

Product

Unit Price

Quantity

Amount

1001

Banana

200

2

400

1001

Apple

300

3

900

1001

Mango

100

4

400


component.ts

import { Component, ViewChild, OnInit } from '@angular/core';

import { Column, EditSettingsModel, ToolbarItems, IEditCell } from '@syncfusion/ej2-angular-grids';

import { DataManager, WebApiAdaptor, UrlAdaptor, Query, ODataV4Adaptor } from '@syncfusion/ej2-data';

import { CommandModel } from '@syncfusion/ej2-grids';

import { DropDownList } from '@syncfusion/ej2-dropdowns';

import { GridComponent } from '@syncfusion/ej2-angular-grids';

import { PageSettingsModel, InfiniteScrollSettingsModel } from '@syncfusion/ej2-angular-grids';

import {

ODataAdaptor,

Predicate,

ReturnOption

} from "@syncfusion/ej2-data";

@Component({

selector: 'app-manange-invoice',

templateUrl: './manange-invoice.component.html',

styleUrls: ['./manange-invoice.component.css']

})

export class ManangeInvoiceComponent implements OnInit {

public commands: CommandModel[];

public data: DataManager;

public editSettings: Object;

public pageSettings: Object;

public toolbar: ToolbarItems[] | object;

public filterSettings: Object;

public infiniteOptions: InfiniteScrollSettingsModel;

public selectedRowIndex:any;

public key: any = null;

public detail: any;

@ViewChild('grid', {static:false})

public grid: GridComponent;

public detaileditSettings: Object;

public detailedittoolbar: ToolbarItems[] | object;

@ViewChild("detailgrid", {static:false})

public detailGrid: GridComponent;

public query: Query;

public dataManager: DataManager = new DataManager({

url: 'Invoice1/UrlDatasource',

updateUrl: 'Invoice1/Update',

insertUrl: 'Invoice1/Insert',

removeUrl: 'Invoice1/Delete',

adaptor: new UrlAdaptor()

});

ngOnInit(): void {

this.data = this.dataManager;

this.commands = [{ type: 'Edit', buttonOption: { iconCss: ' e-icons e-edit', cssClass: 'e-flat' } },

{ type: 'Delete', buttonOption: { iconCss: 'e-icons e-delete', cssClass: 'e-flat' } },

{ type: 'Save', buttonOption: { iconCss: 'e-icons e-update', cssClass: 'e-flat' } },

{ type: 'Cancel', buttonOption: { iconCss: 'e-icons e-cancel-icon', cssClass: 'e-flat' } }];

this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, showDeleteConfirmDialog: true, mode: 'Dialog' };

this.toolbar = ['Add', 'Edit', 'Delete', 'Search',

{ text: 'Refresh grid', tooltipText: 'Refresh grid', id: 'Refresh', prefixIcon: 'e-refresh', align: 'Left'}, ];

this.infiniteOptions = { initialBlocks: 5 };

this.selectedRowIndex = 0;

this.detaileditSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, showDeleteConfirmDialog: true, mode: 'Normal' };

this.detailedittoolbar = ['Add', 'Cancel' ];

this.filterSettings = { type: "Menu" };

this.query = new Query().addParams('ej2grid', 'true').addParams("CustomValue", '123').addParams('Value', 'Test');

}

rowSelected(args:any) {

let selRecord = args.data;

let selecteMessage: any = document.getElementsByClassName(

"e-statustext"

)[0];

let message: HTMLElement = selecteMessage.querySelector("b");

message.textContent = selRecord.InvoiceNo;

let id: any = (args.data as any).InvoiceNo;

let detaildata: any = new DataManager({

url: 'Invoice2/UrlDatasource',

updateUrl: 'Invoice2/Update',

insertUrl: 'Invoice2/Insert',

removeUrl: 'Invoice2/Delete',

adaptor: new UrlAdaptor(),

})

let query = new Query().where('InvoiceNo', 'equal', id);

(this.detailGrid as any).dataSource = [];

(this.detailGrid as any).query = query;

(this.detailGrid as any).dataSource = detaildata;

}

}


html

<div class="control-section">

<div class='e-mastertext'>Edit Invoicediv>

<ejs-grid #grid [dataSource]='data' [selectedRowIndex]='selectedRowIndex' (rowSelected)='rowSelected($event)' allowSorting="true"

allowPaging='true' [pageSettings]='pageSettings' [editSettings]='editSettings' [toolbar]='toolbar' allowResizing='true'>

<e-columns>

<e-column field='InvoiceNo' headerText='Invoice#' isPrimaryKey='true' width='90' [visible]="false"> e-column>

<e-column field="Customer" headerText="Customer" width="130" > e-column>

<e-column field="OrderDate" headerText="Order Date" width="110" editType='datepickeredit' [format]="{type: 'date', skeleton: 'medium'}" >e-column>

<e-column field="ShipDate" headerText="Ship Date" width="115" editType='datepickeredit' [format]="{type: 'date', skeleton: 'medium'}">e-column>

<e-column field='Address' headerText='Ship Address' width='130'> e-column>

<e-column field='Shipping' headerText='Ship Charge' width='110' editType='numericedit' textAlign="right" format='N2'>e-column>

<e-column field='GrandTotal' headerText='Grand Total' width='80' editType='numericedit' textAlign="right" format='N2'> e-column>

e-columns>

ejs-grid>

<div class='e-statustext'>Showing details of Invoice: <b>{{key}}b>div>

<ejs-grid #detailgrid [dataSource]='detail' [allowSelection]='false' [editSettings]='detaileditSettings' (change)='change($event)'

[toolbar]='detailedittoolbar' (actionBegin)="actionBegin($event)">

<e-columns>

<e-column field='Id' headerText='ID'[isPrimaryKey]='true' width='60' [visible]="false">e-column>

<e-column field='InvoiceNo' headerText='Invoice#' [visible]="false" width='90'>e-column>

<e-column field='Product' headerText='Product Name' width='200'>e-column>

<e-column field='UnitPrice' headerText='Unit Price' width='110' editType='numericedit' [edit]="edParams" textAlign="right" format='N2' >e-column>

<e-column field='Quantity' headerText='Quantity' width='90' textAlign="center" editType='numericedit' [edit]="edParams" format='N'>e-column>

<e-column field='Discount' headerText='Discount' width='90' editType='numericedit' textAlign="right" format='N2'>e-column>

<e-column field='Amount' headerText='Amount' width='90' textAlign="right" format='N2' isIdentity="true" allowEditing="false" >e-column>

<e-column headerText='Actions' width='80' [commands]='commands'>e-column>

e-columns>

ejs-grid>

div>


Regards

Charles



RR Rajapandi Ravi Syncfusion Team November 15, 2022 07:30 AM

Hi Charles,


Query#: During editing whenever l enters a value in any of UnitPrice or Quantity it should multiply and display the result in the Amount column.


You can update the column value based on another column edited value by using the Cell Edit Template feature. We have already discussed about your requirement in our documentation, please refer the below documentation for more information.


https://ej2.syncfusion.com/angular/documentation/grid/editing/in-line-editing/#automatically-update-the-column-based-on-another-column-edited-value


Query#: When l delete a row let say InvoiceNo:1001


From your query we could see that you like to delete the detail grid records in the db while deleting the record in the Master Grid. While deleting the Master grid record, the Master Grid’s controller side Delete was triggered, so we suggest you delete the records here from the detail grid datasource.


public ActionResult Delete([FromBody]CRUDModel<OrdersDetails> value) //Master Delete

        {

            OrdersDetails.GetAllRecords().Remove(OrdersDetails.GetAllRecords().Where(or => or.OrderID == int.Parse(value.key.ToString())).FirstOrDefault()); //Master Delete

 

            Employee1Details.GetAllRecords().Remove(Employee1Details.GetAllRecords().Where(or => or.OrderID == int.Parse(value.key.ToString())).FirstOrDefault()); //Detail delete

            return Json(value);

        }

 


Query#: In my master grid l have a column called 'GrandTotal'.


We have achieved your requirement by using dataBound event of Detail Grid, please refer the below code example and sample for more information.


dataBound(args: any) { //dataBound event of Detail Grid

        if (this.detailGrid.currentViewData.length > 0) {

            for (var i = 0; i < this.detailGrid.currentViewData.length; i++) {

                this.sum = this.sum + (this.detailGrid.currentViewData[i] as any).Amount;

            }

            var masterGridindex = this.grid.getRowIndexByPrimaryKey((this.detailGrid.currentViewData[0] as any).OrderID); //get index

            var masterrow = this.grid.getRowByIndex(masterGridindex); //get row (tr)

            var masterrowInformation = this.grid.getRowInfo(masterrow); //pass the tr to this method

            (masterrowInformation as any).rowData.GrandTotal = this.sum;

            this.sum = 0;

             //use the updateRow method to update the GrandTotal column in the master

            (this.grid as any).updateRow(masterGridindex, (masterrowInformation as any).rowData);

        }

    }

    rowSelected(args: any) {//rowSelected event of Master Grid

        if (args.target != null) {

            let selRecord = args.data;

 

            let selecteMessage: any = document.getElementsByClassName(

                "e-statustext"

            )[0];

            let message: HTMLElement = selecteMessage.querySelector("b");

            message.textContent = selRecord.ShipCity;

            let id: any = (args.data as any).OrderID;

 

            let detaildata: any = new DataManager({

                url: 'Home/EmployeeDatasource',

                updateUrl: 'Home/EmpUpdate',

                insertUrl: 'Home/EmpInsert',

                removeUrl: 'Home/EmpDelete',

                adaptor: new UrlAdaptor

            })

 

            let query = new Query().where('OrderID', 'equal', id);

            (this.detailGrid as any).dataSource = [];

            (this.detailGrid as any).query = query;

            (this.detailGrid as any).dataSource = detaildata;

        }

       

    }


For your both queries we have prepared a sample, please refer the below sample for more information.


Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/update1430064082.zip


Regards,

Rajapandi R



CH Charles November 16, 2022 07:31 AM

Hi  Rajapandi,


Thant you for your updated answers. I still have issue with the question that you have answered below;

Query#: In my master grid l have a column called 'GrandTotal'.

With the help of your solution the sumation of 'Amount' column from detail grid to master grid 'GrandTotal' column works fine, but l can not longer perform editing. I cannot select any row for editing both in master and detail grid. Kindly assist

component.ts

 dataBound(args: any) { //dataBound event of Detail Grid

      if (this.detailgrid.currentViewData.length > 0) {

          for (var i = 0; i < this.detailgrid.currentViewData.length; i++) {

              this.sum = this.sum + (this.detailgrid.currentViewData[i] as any).Amount;

          }

          var masterGridindex = this.grid.getRowIndexByPrimaryKey((this.detailgrid.currentViewData[0] as any).InvoiceNo); //get index

          var masterrow = this.grid.getRowByIndex(masterGridindex); //get row (tr)

          var masterrowInformation = this.grid.getRowInfo(masterrow); //pass the tr to this method

          (masterrowInformation as any).rowData.OrderTotal = this.sum;

          this.sum = 0;

           //use the updateRow method to update the GrandTotal column in the master

          (this.grid as any).updateRow(masterGridindex, (masterrowInformation as any).rowData);

      }

    }

 

    rowSelected(args:any) {      

      let selRecord = args.data;      

      let selecteMessage: any = document.getElementsByClassName(

          "e-statustext"

      )[0];

      let message: HTMLElement = selecteMessage.querySelector("b");

      message.textContent = selRecord.InvoiceNo;

      let id: any = (args.data as any).InvoiceNo;      

      let detaildata: any = new DataManager({

        url: 'Invoice/UrlDatasource',  

        updateUrl: 'Invoice/Update',

        insertUrl: 'Invoice/Insert',

        removeUrl: 'Invoice/Delete',  

        adaptor: new UrlAdaptor(),

      })

      let query = new Query().where('InvoiceNo', 'equal', id);

      (this.detailgrid as any).dataSource = [];

      (this.detailgrid as any).query = query;

      (this.detailgrid as any).dataSource = detaildata;    

    }      

 


html

<div class="control-section">

    <div class='e-mastertext'>Manage Invoice</div>

    <ejs-grid #grid [dataSource]='data' [selectedRowIndex]='selectedRowIndex' (rowSelected)='rowSelected($event)'  allowSorting="true"

      allowPaging='true' [pageSettings]='pageSettings' [editSettings]='editSettings' [toolbar]='toolbar' allowResizing='true' (created)='created()'

     >

        <e-columns>            

            <e-column field='InvoiceNo' headerText='Invoice#' isPrimaryKey='true' width='90' [visible]="false"> </e-column>            

            <e-column field="Customer" headerText="Customer" width="130" > </e-column>                    

            <e-column field="OrderDate" headerText="Order Date" width="110" editType='datepickeredit' [format]="{type: 'date', skeleton: 'medium'}" ></e-column>

            <e-column field="ShipDate" headerText="Ship Date" width="115" editType='datepickeredit' [format]="{type: 'date', skeleton: 'medium'}"></e-column>

            <e-column field='Address' headerText='Ship Address' width='130'> </e-column>            

            <e-column field='Shipping' headerText='Shipping' width='110' editType='numericedit' textAlign="right" format='N2'></e-column>                      

            <e-column field='GrandTotal' headerText='Grand Total' width='80' editType='numericedit' textAlign="right" format='N2'> </e-column>        

        </e-columns>

    </ejs-grid>

 

    <div class='e-statustext'>Showing details of Invoice: <b>{{key}}</b></div>

 

    <ejs-grid #detailgrid [dataSource]='detail' [allowSelection]='false' (dataBound)="dataBound($event)" [editSettings]='detaileditSettings'  

        (change)='change($event)' [toolbar]='detailedittoolbar' (actionBegin)="actionBegin($event)" >    

        <e-columns>            

            <e-column field="Id" headerText=" ID" textAlign="Right" isPrimaryKey="true" width="100"></e-column>

            <e-column field='InvoiceNo' headerText='Invoice#' width='90' ></e-column>  

            <e-column field="ProductName" headerText="Product Name" width="120"></e-column>

            <e-column field="UnitPrice" headerText="Unit Price" editType="numericedit" [edit]="priceParams" width="150" format="N2" textAlign="Right"></e-column>

            <e-column field="Quantity" headerText="Units In Stock" editType="numericedit" [edit]="stockParams" width="150" textAlign="Right"></e-column>              

            <e-column field="Amount" headerText="Amount" width="150" [allowEditing]= 'false' format="N2" textAlign="Right"></e-column>    

        <e-column headerText='Actions' width='90' [commands]='commands'></e-column>

        </e-columns>

    </ejs-grid>

</div>

 

 


Regards

Charles



RR Rajapandi Ravi Syncfusion Team November 17, 2022 08:03 AM

Hi Charles,


We have checked your reported problem in our shared sample, and we are not able to edit the Master Grid. The rowSelected event get triggered on rowSelection and it will display the records in the detail. While performing edit operations, the rowSelected also triggers at this time and update the record in the GrandTotal. Since this was a recursive call process, the edit form is not opened. This was the cause of the problem.


So, before we start providing solution to your query, we need some more information for our clarification. So please share the below details that will be helpful for us to provide better solution.


1)              In your query you like to update the Master Grid Grand Total column based on the summation of Amount from Detail Grid, so please confirm you like to update the Grand Total column at case

                  of selecting the row from Master Grid or at the case of edit the Amount value from detail and saving the Amount column then update the Grand Total column in Master.


Regards,

Rajapandi R



CH Charles November 17, 2022 12:53 PM

Hi Rajapandi,


"at the case of edit the Amount value from detail and saving the Amount column then update the Grand Total column in Master."

That's what l want.


Regards

Charles



RR Rajapandi Ravi Syncfusion Team November 18, 2022 04:46 AM

Hi Charles,


Query#: at the case of edit the Amount value from detail and saving the Amount column then update the Grand Total column in Master


As per your requirement we have modify the sample and we have achieved your requirement by using actionComplete event of Grid. Please refer the below code example and sample for more information.


 

actionComplete(args: any) { //actionComplete event of Grid

        if (args.requestType === 'save') {

            for (var i = 0; i < this.detailGrid.currentViewData.length; i++) {

                this.sum = this.sum + (this.detailGrid.currentViewData[i] as any).Amount;

            }

            var masterGridindex = this.grid.getRowIndexByPrimaryKey((this.detailGrid.currentViewData[0] as any).OrderID);

            var masterrow = this.grid.getRowByIndex(masterGridindex);

            var masterrowInformation = this.grid.getRowInfo(masterrow);

            (masterrowInformation as any).rowData.GrandTotal = this.sum;

            this.sum = 0;

            (this.grid as any).updateRow(masterGridindex, (masterrowInformation as any).rowData);

        }

    }

 


Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/sample-695017629.zip


Video demo: https://www.syncfusion.com/downloads/support/directtrac/general/ze/vdgrnadtotal1606433563.zip


API: https://ej2.syncfusion.com/angular/documentation/api/grid/#actioncomplete


Regards,

Rajapandi R



CH Charles November 19, 2022 05:53 AM

Hi Rajapandi ,


Thank you for your solution.

  1. From the sample you have provided when l delete a row from the detail grid nothing change in the 'Grand Total' column of the master grid. The value of 'Grand Total' in the master grid changes when l add or update a row. So It is expected that when l delete a row from the detail grid the value of the 'Grand Total' would change there by decrease but no change occur.
  2. I want the editing tool (Add) to be disable on the detail grid unless a row is selected from the master grid. It should also not save any row that have empty 'InvoiceNo' column of the detail grid. See codes below;
rowDataBound (args) {
var rowIndex = parseInt(args.row.getAttribute('aria-rowIndex'));
var page = this.grid.pageSettings.currentPage - 1;
var totalPages = this.grid.pageSettings.pageSize;
var startIndex = page * totalPages;
var sno = startIndex + (rowIndex + 1);
args.row.cells[0].innerText = sno;
}


actionBegin(args: any) { //actionBegin event of detail Grid
console.log(args);
if (args.requestType === 'add') {
args.data.InvoiceNo = (this.grid.getSelectedRecords()[0] as any).InvoiceNo; //based on master Grid row selection we can get the unique field and set the value to the detail Grid
}
}

actionComplete(args: any) { //actionComplete event of Grid
if (args.requestType === 'save') {
for (var i = 0; i < this.detailgrid.currentViewData.length; i++) {
this.sum = this.sum + (this.detailgrid.currentViewData[i] as any).Amount;
}
var masterGridindex = this.grid.getRowIndexByPrimaryKey((this.detailgrid.currentViewData[0] as any).InvoiceNo);
var masterrow = this.grid.getRowByIndex(masterGridindex);
var masterrowInformation = this.grid.getRowInfo(masterrow);
(masterrowInformation as any).rowData.OrderTotal = this.sum;
this.sum = 0;
(this.grid as any).updateRow(masterGridindex, (masterrowInformation as any).rowData);
}
}

rowSelected(args:any) {
let selRecord = args.data;
let selecteMessage: any = document.getElementsByClassName(
"e-statustext"
)[0];
let message: HTMLElement = selecteMessage.querySelector("b");
message.textContent = selRecord.InvoiceNo;
let id: any = (args.data as any).InvoiceNo;
let detaildata: any = new DataManager({
url: 'Invoice2/UrlDatasource',
updateUrl: 'Invoice2/Update',
insertUrl: 'Invoice2/Insert',
removeUrl: 'Invoice2/Delete',
adaptor: new UrlAdaptor(),
})
let query = new Query().where('InvoiceNo', 'equal', id);
(this.detailgrid as any).dataSource = [];
(this.detailgrid as any).query = query;
(this.detailgrid as any).dataSource = detaildata;
}


html

<div class="control-section">

<div class='e-mastertext'>Manage Invoicediv>

<ejs-grid #grid [dataSource]='data' [selectedRowIndex]='selectedRowIndex' (rowSelected)='rowSelected($event)' allowSorting="true"

allowPaging='true' [pageSettings]='pageSettings' [editSettings]='editSettings' [toolbar]='toolbar' allowResizing='true' (created)='created()'

>

<e-columns>

<e-column field='InvoiceNo' headerText='Invoice#' isPrimaryKey='true' width='90' [visible]="false"> e-column>

<e-column field="Customer" headerText="Customer" width="130" > e-column>

<e-column field="OrderDate" headerText="Order Date" width="110" editType='datepickeredit' [format]="{type: 'date', skeleton: 'medium'}" >e-column>

<e-column field="ShipDate" headerText="Ship Date" width="115" editType='datepickeredit' [format]="{type: 'date', skeleton: 'medium'}">e-column>

<e-column field='Address' headerText='Ship Address' width='130'> e-column>

<e-column field='Shipping' headerText='Shipping' width='110' editType='numericedit' textAlign="right" format='N2'>e-column>

<e-column field='GrandTotal' headerText='Grand Total' width='80' editType='numericedit' textAlign="right" format='N2'> e-column>

e-columns>

ejs-grid>

<div class='e-statustext'>Showing details of Invoice: <b>{{key}}b>div>

<ejs-grid #detailgrid [dataSource]='detail' [allowSelection]='false' (dataBound)="dataBound($event)" [editSettings]='detaileditSettings'

(change)='change($event)' [toolbar]='detailedittoolbar' (actionBegin)="actionBegin($event)" >

<e-columns>

<e-column field="Id" headerText=" ID" textAlign="Right" isPrimaryKey="true" width="100">e-column>

<e-column field='InvoiceNo' headerText='Invoice#' width='90' >e-column>

<e-column field="ProductName" headerText="Product Name" width="120">e-column>

<e-column field="UnitPrice" headerText="Unit Price" editType="numericedit" [edit]="priceParams" width="150" format="N2" textAlign="Right">e-column>

<e-column field="Quantity" headerText="Units In Stock" editType="numericedit" [edit]="stockParams" width="150" textAlign="Right">e-column>

<e-column field="Amount" headerText="Amount" width="150" [allowEditing]= 'false' format="N2" textAlign="Right">e-column>

<e-column headerText='Actions' width='90' [commands]='commands'>e-column>

e-columns>

ejs-grid>

div>


3. I was not able to reproduce the sample found on the link below using grid Dialog mode. It works for grid Normal mode

https://ej2.syncfusion.com/angular/documentation/grid/editing/in-line-editing/#automatically-update-the-column-based-on-another-column-edited-value


Regards

Charles



RR Rajapandi Ravi Syncfusion Team November 22, 2022 07:40 AM

Charles,


Query#: when l deletes a row from the detail grid the value of the 'Grand Total'


From your query we could see that, when deleting a row from the detail Grid you like to update a Grand Total in the Master Grid. Based on your query we have prepared a sample and we suggest you use the below way to achieve your requirement.


 

actionComplete(args: any) { //actionComplete event of Detail Grid

        if (args.requestType === 'save' || args.requestType === 'delete') {

            for (var i = 0; i < this.detailGrid.currentViewData.length; i++) {

                this.sum = this.sum + (this.detailGrid.currentViewData[i] as any).Amount;

            }

            var masterGridindex = this.grid.getRowIndexByPrimaryKey((this.detailGrid.currentViewData[0] as any).OrderID);

            var masterrow = this.grid.getRowByIndex(masterGridindex);

            var masterrowInformation = this.grid.getRowInfo(masterrow);

            (masterrowInformation as any).rowData.GrandTotal = this.sum;

            this.sum = 0;

            (this.grid as any).updateRow(masterGridindex, (masterrowInformation as any).rowData);

        }

    }

 


Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/sample371374257.zip


Query#: I want the editing tool (Add) to be disable on the detail grid unless a row is selected from the master grid.


We have analyzed your query and we could see that you like to disable the Detail Grid toolbar Add button when the Master Grid has no selected records. You can enable and disable the toolbar Items by using the enableItems method. To enable Toolbar items, set the enable property in argument to true and vice-versa. Please refer the below code example and sample for more information.


 

dataBound(args: any) { //dataBound event of Master Grid

        if ((this.grid as any).getSelectedRecords().length < 1) {

            var toolbar = (this.detailGrid as any).toolbarModule.element.ej2_instances[0];

            toolbar.enableItems((this.detailGrid.toolbarModule as any).element.querySelector('.e-toolbar-items').querySelector('[title="Add"]'), false);

        }

    }

 

rowSelected(args: any) { //rowSelected event of Master Grid

        if (args.target != null) {

            var toolbar = (this.detailGrid as any).toolbarModule.element.ej2_instances[0];

            toolbar.enableItems((this.detailGrid.toolbarModule as any).element.querySelector('.e-toolbar-items').querySelector('[title="Add"]'), true);

            let selRecord = args.data;

 

            let selecteMessage: any = document.getElementsByClassName(

                "e-statustext"

            )[0];

            let message: HTMLElement = selecteMessage.querySelector("b");

            message.textContent = selRecord.ShipCity;

            let id: any = (args.data as any).OrderID;

 

            let detaildata: any = new DataManager({

                url: 'Home/EmployeeDatasource',

                updateUrl: 'Home/EmpUpdate',

                insertUrl: 'Home/EmpInsert',

                removeUrl: 'Home/EmpDelete',

                adaptor: new UrlAdaptor

            })

 

            let query = new Query().where('OrderID', 'equal', id);

            (this.detailGrid as any).dataSource = [];

            (this.detailGrid as any).query = query;

            (this.detailGrid as any).dataSource = detaildata;

        }

       

    }

 


Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/sample371374257.zip


Query#:  I was not able to reproduce the sample found on the link below using grid Dialog mode.


Please follow the documentation step by step and achieve your requirement , it was also work for the dialog mode. To get the form instance in the change event of numerictext box, please use the below code,


 

change: function(args) {

            var formEle = document.querySelector('.e-gridform').ej2_instances[0]; //get the form instance for dialog mode

            var totalCostFieldEle = formEle.getInputElement('TotalCost');

            totalCostFieldEle.value = this.priceObj.value * this.stockObj.value;

          }.bind(this)

 

 


https://ej2.syncfusion.com/angular/documentation/grid/editing/in-line-editing/#automatically-update-the-column-based-on-another-column-edited-value



CH Charles November 23, 2022 09:44 AM

Hi Rajapandi,


Thank you for your solutions. In respect to the solution you have provided for Query#: I was not able to reproduce the sample found on the link below using grid Dialog mode. https://ej2.syncfusion.com/angular/documentation/grid/editing/in-line-editing/#automatically-update-the-column-based-on-another-column-edited-value ,It only works for inline grid editing. Each time l switch from Normal to dialog mode it doesn't work as TotalCost is showing empty 


Regards

Charles



RR Rajapandi Ravi Syncfusion Team November 24, 2022 04:22 AM

Charles,


Based on your query we have prepared a sample and tried to reproduce your reported problem, but it was unsuccessful. Please refer the below code example and sample for more information.


 

this.priceParams = {

      create: () => {

        this.priceElem = document.createElement('input');

        return this.priceElem;

      },

      read: () => {

        return this.priceObj.value;

      },

      destroy: () => {

        this.priceObj.destroy();

      },

      write: args => {

        this.priceObj = new NumericTextBox({

          value: args.rowData[args.column.field],

          change: function(args) {

            var formEle = (document.querySelector('.e-gridform') as any).ej2_instances[0];

            var totalCostFieldEle = formEle.getInputElement('TotalCost');

            totalCostFieldEle.value = this.priceObj.value * this.stockObj.value;

          }.bind(this)

        });

        this.priceObj.appendTo(this.priceElem);

      }

    };

    this.stockParams = {

      create: () => {

        this.stockElem = document.createElement('input');

        return this.stockElem;

      },

      read: () => {

        return this.stockObj.value;

      },

      destroy: () => {

        this.stockObj.destroy();

      },

      write: args => {

        this.stockObj = new NumericTextBox({

          value: args.rowData[args.column.field],

          change: function(args) {

            var formEle = (document.querySelector('.e-gridform') as any).ej2_instances[0];

            var totalCostFieldEle = formEle.getInputElement('TotalCost');

            totalCostFieldEle.value = this.priceObj.value * this.stockObj.value;

          }.bind(this)

        });

        this.stockObj.appendTo(this.stockElem);

      }

    };

 


Sample: https://stackblitz.com/edit/angular-zknjcu-xfusjj?file=app.component.ts,app.component.html


If you still face the issue, please try to reproduce the issue with our above attached sample.


Marked as answer

CH Charles December 6, 2022 01:14 PM

Hi Rajapandi ,


Thank you for your solution.

  1. In the above sample, the master grid lost focus on its selected row as soon as l have updated a row in the detail grid. I want when l have either added or updated a row in the detail grid then the master grid should retain its focus so that l can add more rows in the detail grid without going back to the master grid to select the same row again.
  2. How to delete detail grid row(s) from master grid delete action? When l click on delete button from master grid l also want it to delete the row(s) in detail grid at once.
  3. In my project there is a Ship Cost, Sub Total, and Grand Total. Saving the Amount column in the detail grid then update the Sub Total column in Master grid works fine. Unless l manually enter value into Ship cost column otherwise the Grand Total column would remain unchanged. I want whenever there in change in Sub Total then the Grand Total should be updated automatic i.e. SubTotal + ShipCost = GrandTotal. See codes below
component.ts
public dataManager: DataManager = new DataManager({
url: 'Invoice/UrlDatasource',
updateUrl: 'Invoice/Update',
insertUrl: 'Invoice/Insert',
removeUrl: 'Invoice/Delete',
adaptor: new UrlAdaptor()
});


ngOnInit(): void {
this.data = this.dataManager;
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, showDeleteConfirmDialog: true, mode: 'Dialog' };
this.toolbar = ['Add', 'Edit', 'Delete','Update','Cancel', 'Search'];
this.pageSettings = { pageSize: 5};
this.selectedRowIndex = 0;
this.detaileditSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, showDeleteConfirmDialog: true, mode: 'Normal' };
this.detailedittoolbar = ['Add', 'Cancel' ];
this.filterSettings = { type: "Menu" };
this.query = new Query().addParams('ej2grid', 'true').addParams("CustomValue", '123').addParams('Value', 'Test');

this.pricepParams = {
create: () => {
this.pricepElem = document.createElement('input');
return this.pricepElem;
},
read: () => {
return this.pricepObj.value;
},
destroy: () => {
this.pricepObj.destroy();
},
write: args => {
this.pricepObj = new TextBox({
value: args.rowData[args.column.field],
change: function(args) {
var formEle = (document.querySelector('.e-gridform') as any).ej2_instances[0];
var totalCostFieldEle = formEle.getInputElement('GrandTotal');
totalCostFieldEle.value = this.pricepObj.value + this.stockpObj.value;
}.bind(this),
placeholder: 'Sub Total',
floatLabelType: 'Always',
});
this.pricepObj.appendTo(this.pricepElem);
}
};
this.stockpParams = {
create: () => {
this.stockpElem = document.createElement('input');
return this.stockpElem;
},
read: () => {
return this.stockpObj.value;
},
destroy: () => {
this.stockpObj.destroy();
},
write: args => {
this.stockpObj = new NumericTextBox({
value: args.rowData[args.column.field],
change: function(args) {
var formEle = (document.querySelector('.e-gridform') as any).ej2_instances[0];
var totalCostFieldEle = formEle.getInputElement('GrandTotal');
totalCostFieldEle.value = this.pricepObj.value + this.stockpObj.value;
}.bind(this),
placeholder: 'Shipping Cost',
floatLabelType: 'Always',
});
this.stockpObj.appendTo(this.stockpElem);
}
};
}

actionBegin(args: any) { //actionBegin event of detail Grid
console.log(args);
if (args.requestType === 'add') {
args.data.InvoiceNo = (this.grid.getSelectedRecords()[0] as any).InvoiceNo; //based on master Grid row selection we can get the unique field and set the value to the detail Grid
}
}

actionComplete(args: any) { //actionComplete event of Grid
if (args.requestType === 'save' || args.requestType === 'delete') {
for (var i = 0; i < this.detailgrid.currentViewData.length; i++) {
this.sum = this.sum + (this.detailgrid.currentViewData[i] as any).Amount;
}
var masterGridindex = this.grid.getRowIndexByPrimaryKey((this.detailgrid.currentViewData[0] as any).InvoiceNo);
var masterrow = this.grid.getRowByIndex(masterGridindex);
var masterrowInformation = this.grid.getRowInfo(masterrow);
(masterrowInformation as any).rowData.SubTotal = this.sum;
this.sum = 0;
(this.grid as any).updateRow(masterGridindex, (masterrowInformation as any).rowData);
}
}

rowSelected(args:any) {
var toolbar = (this.detailgrid as any).toolbarModule.element.ej2_instances[0];
toolbar.enableItems((this.detailgrid.toolbarModule as any).element.querySelector
('.e-toolbar-items').querySelector('[title="Add"]'), false);

let selRecord = args.data;
let selecteMessage: any = document.getElementsByClassName(
"e-statustext"
)[0];
let message: HTMLElement = selecteMessage.querySelector("b");
message.textContent = selRecord.InvoiceNo;
let id: any = (args.data as any).InvoiceNo;
let detaildata: any = new DataManager({
url: 'order/UrlDatasource',
updateUrl: 'order/Update',
insertUrl: 'order/Insert',
removeUrl: 'order/Delete',
adaptor: new UrlAdaptor(),
})
let query = new Query().where('InvoiceNo', 'equal', id);
(this.detailgrid as any).dataSource = [];
(this.detailgrid as any).query = query;
(this.detailgrid as any).dataSource = detaildata;
}


<div class="control-section">
<ejs-grid #grid id="grid" [dataSource]='data' [selectedRowIndex]='selectedRowIndex' (rowSelected)='rowSelected($event)' allowSorting="true"
[pageSettings]='pageSettings' [editSettings]='editSettings' [toolbar]='toolbar' >
<e-columns>
<e-column field='InvoiceNo' headerText='Invoice#' isPrimaryKey='true' width='125' [visible]="false" > e-column>
<e-column field="Customer" headerText="Customer" width="200" editType='dropdownedit' [edit]='custParams' [validationRules]='customerrules'> e-column>
<e-column field="SubTotal" headerText="Sub Total" isIdentity="true" [edit]="pricepParams" width="150" defaultValue="0.00" textAlign="Right" format="N2">e-column>
<e-column field="ShipCost" headerText="Ship Cost" [edit]="stockpParams" width="140" defaultValue="0.00" format="N2" textAlign="Right">e-column>
<e-column field="GrandTotal" headerText="Grand Total" width="150" [allowEditing]= 'false' format="N2" textAlign="Right" defaultValue="0.00">e-column>
e-columns>
ejs-grid>

<div class='e-statustext'>Showing order details: <b>{{key}}b>div>

<ejs-grid #detailgrid [dataSource]='detail' [allowSelection]='true' [editSettings]='detaileditSettings'
[toolbar]='detailedittoolbar' (actionBegin)="actionBegin($event)" (actionComplete)="actionComplete($event)">
<e-columns>
<e-column field='InvoiceNo' headerText='Invoice#' width='100'[isPrimaryKey]='true'>e-column>
<e-column field='Name' headerText='Item details' width='170' editType='dropdownedit' [edit]='itemParams' [validationRules]='itemrules' defaultValue="Select Item">e-column>
<e-column field='UnitPrice' headerText='Unit Price' width='120' [edit]="priceParams" textAlign="right" format='N2' [validationRules]='pricerules'>e-column>
<e-column field='Quantity' headerText='Quantity' width='120' textAlign="center" editType='numericedit' textAlign="right" [edit]="stockParams" format='N' [validationRules]='qtyrules' defaultValue="0">e-column>
<e-column field='Amount' headerText='Amount' width='120' [allowEditing]= 'false' textAlign="right" format='N2' defaultValue="0.00">e-column>
e-columns>
ejs-grid>
div>


Regards
Charles



Loader.
Live Chat Icon For mobile
Up arrow icon