Access grid row within cell

Posted by: mark.goldin on 7 December 2019, 9:52 pm EST

    • Post Options:
    • Link

    Posted 7 December 2019, 9:52 pm EST

    I am creating a custom formatter for a column and need to access ow data. Other products supply the complete row object to custom column formatters.

    What about Wijmo grid?

    Thanks

  • Posted 7 December 2019, 10:10 pm EST

    I am already using the following code:

    <ng-template wjFlexGridCellTemplate [cellType]="'Cell'" let-cell="cell">
              <div>
                {{formatDate(cell)}}
              </div>
          </ng-template>
    

    And in formatDate cell.item would have complete row data. But when using the following code:

    <div [ngStyle]="{'background-color': statusStyle(cell) }">
                  {{cell.item.Status}}
              </div>
    

    the cell.item is an empty object. Please have a look into it.

    Thanks

  • Posted 8 December 2019, 6:11 pm EST

    Hi Mark,

    We are sorry but we were not able to replicate the issue at our end. Please refer to the sample below that we used to replicate the issue:

    https://stackblitz.com/edit/angular-fkysvu

    But, your issue may be related to the cell type that you are formatting. Could you please let us know the cellType you are using or you may modify the sample so that it replicates the issue?

    Regards,

    Ashwin

  • Posted 9 December 2019, 3:47 am EST

    In your example:

    getColor(cell) {
        return cell.item.amount > 5000 ? 'green' : 'red';
      }
    

    You are not accessing the row’s data in order to make a decision what color to return. But I need to access the whole row because to make a decision I need to analyse data that is not in any column.

  • Posted 9 December 2019, 4:36 pm EST

    Hi Mark,

    The cell.item object contains all the data in that particular row. Refer to the updated sample below:

    https://stackblitz.com/edit/angular-wftpmb

    In this sample, in the getColor method, I am using the ‘id’ key to determine the color of the cell. The ‘id’ key is not present in any of the columns, but we can use it because it is contained in the data.

    I hope this clears your doubts but if you have any further questions, feel free to ask.

    ~regards

  • Posted 20 December 2019, 6:45 am EST

    Doesn’t work.

    Here is my code:

    <wj-flex-grid-column [binding]="'Status'" [width]="300" align="center" [header]="'Status'">
          <ng-template wjFlexGridCellTemplate [cellType]="'Cell'" let-cell="cell">
              <div [ngStyle]="{'background-color': formatHomeStatus.[b]statusStyle[/b](cell) }">
                  {{cell.item.Status}}
              </div>
          </ng-template>
      </wj-flex-grid-column>
    
    statusStyle(cell) {
        let retVal: string;
        switch (cell) {
          case 'OK':
            retVal = 'green';
            break;
          case 'Unknown':
            retVal = 'gray';
            break;
          default:
              retVal = 'red';
        }
        return retVal;
      }
    

    cell from console:

    cell.item: Object

    proto: Object

  • Posted 20 December 2019, 7:00 am EST

    Ok, I got it. I had to use wjcCore.CollectionView. In your example you have import * as wjcCore from ‘@grapecity/wijmo’;. How can I import it just once in the module instead importing into every component?

    Thanks

  • Posted 20 December 2019, 8:59 am EST

    Another question. In your example you are using a local function to generate some data. In case getData() would request data from the server how would you assign getData() as a data source?

    Thanks

  • Posted 22 December 2019, 8:51 pm EST

    Hi Mark,

    To get the data from the server, I would suggest you use the HttpClientModule of Angular and create a service to get the data using this module. Please refer to the sample below that uses a DataService and HttpClient class to make a call and get the data from the server:

    https://stackblitz.com/edit/angular-fkysvu

    For more info on HttpClient and Services in angular, you can refer to the links below:

    Regarding importing of module:

    Yes, you will need to import the module in each of the component files because this is how angular works. Angular needs a reference to the module if you need to use it in a component file.

    Regarding the styling of the cell:

    The code is not working because you are using the whole cell object in the switch case. The cell object contains the reference to the Column and the Row to which it belongs and an item property that contains the current row’s dataItem. So, you will need to convert your code to use the dataItem instead of the cell object:

    statusStyle(cell) {
        let retVal: string;
        switch (cell.item.Status) {
          case 'OK':
            retVal = 'green';
            break;
          case 'Unknown':
            retVal = 'gray';
            break;
          default:
              retVal = 'red';
        }
        return retVal;
      }
    
  • Posted 22 December 2019, 8:57 pm EST

    But why do I have to import it as import * as wjcCore from ‘@grapecity/wijmo’;?

  • Posted 22 December 2019, 9:16 pm EST

    When we specify data for FlexGrid like this: [itemsSource]=“getData()” is it running getData() function multiple times?

  • Posted 23 December 2019, 2:56 pm EST

    Hi Mark,

    You need to import the module like that because it is the standard nodejs import statement. This syntax tells us that we need to import all the exported members as ‘wjcCore’ from the module ‘@grapecity/wijmo’.

    You can also import specific methods and classes from the modules:

    import { CollectionView } from '@grapecity/wijmo';
    

    Regarding the getData method:

    If you are using the getData method directly in the HTML, it will run every time the change detection of angular runs. Angular will run this method whenever it requires to check for the changes and this method will return different data every time because it generates data randomly. That is why we assign the return value of the getData method to a variable and then assign this variable as the data source of the grid.

    I hope this clears your doubts.

    ~regards

  • Posted 23 December 2019, 8:58 pm EST

    My architecture is different. HTML looks like this:

    [itemsSource]="getData()"
    

    Then in the component I have this:

    ngOnInit() {
        this.requestData();
      }
    
    getData() {
        return super.getData();
      }
    

    Then in the base class:

    private data = new BehaviorSubject<object>(null);
      constructor(private dataSvc: HomeService) {
      }
      public getData(param: Array<string>) {
        return new CollectionView(this.data.value);
      }
      public requestData() {
        this.subscription = this.dataSvc.data()
          .subscribe(data => {
            // Populate BehaviorSubject with data from the server
            this.data.next(data);
        });
      }
    

    I see that getData() is called constantly. Is it because of BehaviorSubject or it is the grid that constantly checks for new data?

  • Posted 25 December 2019, 4:55 pm EST

    Hi Mark,

    The getData method is called again and again because the angular constantly checks whether the data in the component file is updated so that it can be updated on the HTML side as well. This is called the angular change detection strategy. You can read more about it here:

    https://blog.angular-university.io/how-does-angular-2-change-detection-really-work/

    In your case, to prevent the getData being called multiple times, you can subscribe to the BehaviorSubject and set the source to the result:

    data: BehaviorSubject<object>;
    source: any;
    ngOnInit() {
    	this.data.subscribe(res => {
    		this.source = res;
    	});
    	this.requestData();
    }
    
    <wj-flex-grid [itemsSource]="source">..</wj-flex-grid>
    

    You may refer to the updated sample below:

    https://stackblitz.com/edit/angular-kuf2aq

    Also, could you explain your use case so that I can provide you a solution best suited for your requirements?

    ~regards

  • Posted 25 December 2019, 9:01 pm EST

    Thanks for the updated example. In the article I see the following code:

    constructor(private ref: ChangeDetectorRef) {
        ref.detach();
        setInterval(() => {
          this.ref.detectChanges();
        }, 5000);
      }
    

    Will ref.detach(); stop change detection for the grid too?

  • Posted 26 December 2019, 2:43 pm EST

    Hi Mark,

    The detach method can be used to stop the change detection but it stops the change detection in the whole DOM tree. This means that the change detection does not run in this component and for all the child components. Due to this, the change detection will also not run inside the FlexGrid and will cause the application to break.

    I tested with the provided code and it did not work properly at my end. Below is the link to the sample that I used:

    https://stackblitz.com/edit/angular-xwy1ps

    ~regards

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels