Our blazing fast Grid component built with pure JavaScript


Post by muhammad faisal »

Description:
I've encountered an issue with grouping functionality in a grid that uses nested field. Here's the setup:

  1. I have two stores: teamStore and playersStore.
  2. There's a relation between these stores: each team record has an array of players.
  3. I've created a grid with two columns: "Player" and "Team".
  4. The grid is assigned to playerStore.
  5. The "Player" column is mapped to the record's name field.
  6. The "Team" column is mapped to the record's related team.name field.
  7. I've defined a groupRenderer function for the "Team" column to customize the group header.

Bug:
When I try to group by the "Team" column, the groupRenderer function is not being called, and the custom group header is not displayed.

Finding:
I've discovered that the group header record's meta object contains a groupField value of "name" instead of the expected "team.name".

Video:
https://www.loom.com/share/20f3f7201e9b4b178de065d539522e5a

Code Snippet:

import { Grid, Store, Model } from '../../build/grid.module.js?478334';
import shared from '../_shared/shared.module.js?478334';

class Player extends Model {
    static relations = {
        // Define a relation between a player and a team
        team : {
            foreignKey            : 'teamId',
            foreignStore          : 'teamStore',
            relatedCollectionName : 'players'
        }
    }
}

class Team extends Model {
    get playersValue() {
        return this.players?.map((player) => player.name)
    }
}

const teamStore = new Store({
    modelClass: Team,
    data : [
        { id : 1, name : 'Brynas' },
        { id : 2, name : 'Leksand' }
    ]
});

const playerStore = new Store({
    modelClass : Player,
    // Matches foreignStore, allowing records of playerStore to find the related store
    teamStore,
    data       : [
        // teamId is specified as foreignKey, will be used to match the team
        { id : 1, name : 'Nicklas Backstrom', teamId : 1  },
        { id : 2, name : 'Elias Lindholm',   teamId : 1  },
        { id : 3, name : 'Filip Forsberg',  teamId : 2  }
    ],
});

const grid = new Grid({
        appendTo : 'container',

features : {
    group: true,
},

columns : [
    { 
        text : 'Player',
        field : 'name',
        flex : 1
    },
    { 
        text : 'Team', 
        field : 'team.name', 
        flex : 1,
        groupRenderer(renderData) {
            console.log("===Team Group Renderer ===", renderData);
            return {
                 class : {
                     big   : true,
                     small : false
                 },
                 children : [
                     renderData.groupRowFor
                 ]
            };
        }
    },
],

store : playerStore
});


Post by alex.l »

Hi,

Thanks for notifying!
Try to add mapping into Model instead of column field.

fields : [{
     name : 'teamName', dataSource : 'team.name'
}]

All the best,
Alex


Post by muhammad faisal »

Here's a more simplified version of the code snippet.

import { Grid, Store, Model } from '../../build/grid.module.js?478334';
import shared from '../_shared/shared.module.js?478334';

class Player extends Model {
    static fields = [
        { name: "name" },
        { name: "team", type: "object" },
    ]
}

const playerStore = new Store({
    modelClass : Player,
    data       : [
        { id : 1, name : 'Nicklas Backstrom', team: { name: "Brynas" }  },
        { id : 2, name : 'Elias Lindholm',   team: { name: "Brynas" }  },
        { id : 3, name : 'Filip Forsberg',  team: { name: "Leksand" }  }
    ],
});

const grid = new Grid({
    appendTo : 'container',
    features : {
        group: true,
    },
    columns : [
        { 
            text : 'Player',
            field : 'name',
            flex : 1
        },
        { 
            text : 'Team', 
            field : 'team.name', 
            flex : 1,
            groupRenderer(renderData) {
                console.log("===Team Group Renderer ===", renderData);
                return {
                    class : {
                        big   : true,
                        small : false
                    },
                    children : [
                        renderData.groupRowFor
                    ]
                };
            }
        },
    ],
    store : playerStore
});

Even though I'm using an object field instead of relations, the groupRenderer function still isn't being triggered.


Post by tasnim »

Hi,

Please try testing with this code snippet here https://bryntum.com/products/grid/examples/grouping/

import { Grid, DataGenerator, StringHelper, Store, Model } from '../../build/grid.module.js?478334';
import shared from '../_shared/shared.module.js?478334';

class Player extends Model {
    static fields = [
        { name: "name" },
        { name: "team", type: "object" },
    ]
}

const playerStore = new Store({
    modelClass : Player,
    fields : [{
     name : 'teamName', dataSource : 'team.name'
}],
    data       : [
        { id : 1, name : 'Nicklas Backstrom', team: { name: "Brynas" }  },
        { id : 2, name : 'Elias Lindholm',   team: { name: "Brynas" }  },
        { id : 3, name : 'Filip Forsberg',  team: { name: "Leksand" }  }
    ],
});

const grid = new Grid({
    appendTo : 'container',
    features : {
        group: true,
    },
    columns : [
        { 
            text : 'Player',
            field : 'name',
            flex : 1
        },
        { 
            text : 'Team', 
            field : 'teamName', 
            flex : 1,
            groupRenderer(renderData) {
                console.log("===Team Group Renderer ===", renderData);
                return {
                    class : {
                        big   : true,
                        small : false
                    },
                    children : [
                        renderData.groupRowFor
                    ]
                };
            }
        },
    ],
    store : playerStore
});

Hope this helps.

Best regards,
Tasnim


Post by muhammad faisal »

I recently upgraded from 5.5.4 to 6.0.3. In the previous version (5.5.4), I didn't need to explicitly define object properties in either the Model or the Store. The code snippets I had were working fine without this. However, after the upgrade to 6.0.3, it seems this is no longer the case.


Post by ghulam.ghous »

Ok. There might be something that made it work out of the box maybe. But I believe it was never intended to work. You need mapping on the model level. Have you tried using the snippet provided by Tasnim, does it work for you?


Post by muhammad faisal »

Yes, the code snippet from Tasnim works well. Now, I just have the small task of adding 30 fields to my record's model. Should be a breeze, right? Any efficient methods you recommend for this challenge?


Post by marcio »

Hey muhammad faisal,

You can iterate between your object with the props that you want to add, then use https://bryntum.com/products/grid/docs/api/Core/data/Model#function-addField-static to add a DataField configuration
https://bryntum.com/products/grid/docs/api/Core/data/field/DataField.

Best regards,
Márcio


Post Reply