FlexGrid GroupChanged event in React

Posted by: scott.chinn on 7 February 2020, 4:10 am EST

  • Posted 7 February 2020, 4:10 am EST

    Hello. I've seen other posts about this topic, but none seem to work for me in Reactjs.

    I have FlexGrid with a group panel.

    After the grid is ready, I'm attaching different handlers. The resizingColumn and sortedColumn handlers work fine, but the groupDescriptions.collectionChanged handled never seems to fire. I'm expecting it to change as I drag or remove columns to the group panel.


    grid.resizingColumn.addHandler(grid => {
    this.saveGridState();
    });
    grid.sortedColumn.addHandler(grid => {
    this.saveGridState();
    });
    grid.collectionView.groupDescriptions.collectionChanged.addHandler( grid => {
    console.log('group changed');
    this.saveGridState();
    });


    Any ideas? Thanks!
  • Replied 7 February 2020, 4:17 am EST

    Forgot to mention, we are using "@grapecity/wijmo.all": "^5.20193.637".

    Also, we are attaching the group panel in componentDidMount(), like this:

    groupPanel = new wjGroup.GroupPanel('.group-panel');
    groupPanel.placeholder = "Drag columns here to create groups.";
    groupPanel.grid = this.flexGrid;


    This is so we can access the state later in order to save it (and this all works fine):

    let gridState = {
    columns: this.flexGrid.columnLayout,
    filterDefinition: this.state.gridFilter.filterDefinition,
    sortDescriptions: this.flexGrid.collectionView.sortDescriptions.map(
    function(sortDesc) {
    return { property: sortDesc.property, ascending: sortDesc.ascending };
    },
    ),
    groupDescriptions: this.flexGrid.collectionView.groupDescriptions.map(
    function(groupDesc) {
    return groupDesc.propertyName;
    },
    )

    };
  • Replied 9 February 2020, 3:35 pm EST

    Hi Scott,

    Could you please let us know how you have created the FlexGrid and how are you getting the reference of the grid on the JS side. It may be possible that the grid is not created in the componentDidMount callback. Due to this, the GroupPanel may not get the correct reference to the grid. Please make sure that this.flexGrid is defined while creating the GroupPanel.
    You may also try to create the GroupPanel in the initialized event of the FlexGrid as shown in the sample below:

    https://stackblitz.com/edit/react-8x69qw

    Regards,
    Ashwin
  • Replied 10 February 2020, 3:49 am EST

    Thanks. I tried putting everything under the grid init handler, but the event still won't fire (everything else works fine). Here is the source: index.zip
  • Replied 10 February 2020, 4:51 pm EST

    Hi Scott,

    The groupDescriptions.collectionChanged event is only fired when we add a new column to the Grouppanel or we remove a column from it.
    Since you only provided a single file, we were not able to run it. Could you please provide a working sample so that we may easily run it at our end and find the cause of the issue?

    ~regards
  • Replied 12 February 2020, 8:28 am EST

    Hi Ashwin, I tried to create a simple example here in a single file, but for some reason the grouping isn't working now. When I try to drag a column to the group panel, nothing happens. Any idea why?

    https://codesandbox.io/s/awesome-darkness-87q0s?fontsize=14&hidenavigation=1&theme=dark
  • Replied 12 February 2020, 11:29 pm EST

    Hi Scott,

    I downloaded the sample and was able to run it on my local machine. I found out that the collectionChanged event is not firing because the groupDescriptions array, on which you have added the event handler, is different from the actual groupDescriptions array. This means that it is reassigned somewhere.
    I am still looking for a solution to this and will update you as soon as I have further information.

    ~regards
  • Replied 13 February 2020, 3:25 pm EST

    Hi Scott,

    The reason for the collectionChanged event handler is not firing is because you have set the itemsSource of the grid as follows:
    itemsSource={this.getRowData()}

    When this component will be re-rendered, the itemsSource will be reassigned to the new array returned by the getRowData method, which in turn will create a new CollectionView.
    To avoid this issue, simply save the data to the state of the component instead of using the method directly:
    this.state = {
    data: this.getRowData(),
    colDef: this.getColumnDefs()
    };

    <FlexGrid
    itemsSource={this.state.data}
    >
    {this.state.colDef.map((col, index) => (
    <FlexGridColumn
    header={col.headerName}
    binding={col.field}
    width={col.width}
    visible={!col.hide}
    isReadOnly={true}
    key={`${col.field}-${index}`}
    />
    ))}
    </FlexGrid>

    Please refer to the updated sample attached.

    ~regards

    group-panel-issue.zip
  • Replied 14 February 2020, 4:37 am EST

    Thanks! I got it to work now, but I wasn't able to simply store the row data in the state. My example that I gave you is too simple. Our app uses Redux Saga and the component that uses the grid doesn't fetch the data until it has been mounted (data is passed through props). The reason for this is so we can render the page + grid and display a progress spinner while the data is being fetched from the DB.

    Maybe you have a better solution, but my workaround was to simply attach the group change event listener in componentDidUpdate ( in the grid component ). I know this gets called several times, so I have to remove the previous listener first. The end result is just one listener attached to the latest data:

      componentDidUpdate(prevProps, prevState, snapshot) {

    // It's necessary to attached the group change listener here bc it has some dependency on
    // the row data (this.props.rowData) which gets set after to the component mounts.
    // Since this gets called more than once, we need to remove then add so only 1 ends up in the end.
    // If grid can be told to wait to render until the rowData is set, then this should be needed and groupChangeHandler
    // can be set in onGridReady like all the other handlers.
    if (this.flexGrid && this.flexGrid.collectionView) {
    this.flexGrid.collectionView.groupDescriptions.collectionChanged.removeHandler(this.groupChangeHandler);
    this.flexGrid.collectionView.groupDescriptions.collectionChanged.addHandler(this.groupChangeHandler, this);
    }
    }
  • Replied 16 February 2020, 5:12 pm EST

    Hi Scott,

    The workaround that you used looks good. If it is working at your end, then I would suggest you keep using this logic.

    Let me know in case you have any other issues.

    ~regards
Need extra support?

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

Learn More

Forum Channels