Our blazing fast Grid component built with pure JavaScript


Post by henrique »

I have a complex field map name, and I need to group a grid with this field, but it's no work.

I tried to add a field in the store, but the value I'm using is a Model class, and the field isn't exposed, because of this.

Exists any workaround for this?


Post by alex.l »

Could you please explain what exactly is the complexity of your field? Posting a test case would be great to assist you better.

All the best,
Alex


Post by henrique »

A simple complex field, like "MyField.MyValue", this sample does not group in the grid.

A suggestion, in the data generator of the samples, the return object could have some sub objects, to make easier to build the samples.


Post by tasnim »

Hi,
I've tried to reproduce but I wasn't able to reproduce it.

Here is my code

new Grid({
    appendTo : 'container',

features : {
    group : 'foodItem.foodType'
},

// Headers will ripple on tap in Material theme
ripple : {
    delegate : '.b-grid-header'
},

columns : [
    {
        text   : 'Name',
        field  : 'name',
        flex   : 2,
        editor : {
            type     : 'textfield',
            required : true
        }
    }, {
        text  : 'Age',
        field : 'age',
        width : 100,
        type  : 'number'
    }, {
        text  : 'City',
        field : 'city',
        flex  : 1
    }, {
        text  : 'Food',
        field : 'food',
        flex  : 1,
    }, {
        text     : 'Color (not sortable)',
        field    : 'color',
        flex     : 1,
        sortable : false,
        renderer({ cellElement, value }) {
            // renderer that sets text color = text
            cellElement.style.color = value;
            return value;
        }
    }
],

data : [
    { name : 'Anim', age : 20, city : 'SF', color : 'red', food : 'Burgger', foodItem : { 
        foodType : 'Junk Food'
    } },
    { name : 'Siam', age : 21, city : 'LA', color : 'blue', food : 'Apple', foodItem : { 
        foodType : 'Healthy Food'
    } }
]
});

Please check the video attached below

Attachments
grouping.mp4
(158.6 KiB) Downloaded 42 times

Post by henrique »

It works because the data used is a raw data, and in this case the store creates a field with de name that the group expect. If you change the sample, creating two model's classes, load these classes, the field will not be created, and the error will occur.


Post by Animal »

This seems to work too:

        class Diner extends Model {
            static fields = [{
                name       : 'foodType',
                dataSource : 'foodItem.foodType'
            }]
        }

    grid = new Grid({
        appendTo : document.body,
    
        features : {
            group : 'foodType'
        },

        columns : [
            {
                text   : 'Name',
                field  : 'name',
                flex   : 2,
                editor : {
                    type     : 'textfield',
                    required : true
                }
            }, {
                text  : 'Age',
                field : 'age',
                width : 100,
                type  : 'number'
            }, {
                text  : 'City',
                field : 'city',
                flex  : 1
            }, {
                text  : 'Food',
                field : 'food',
                flex  : 1,
            }, {
                text     : 'Color (not sortable)',
                field    : 'color',
                flex     : 1,
                sortable : false,
                renderer({ cellElement, value }) {
                    // renderer that sets text color = text
                    cellElement.style.color = value;
                    return value;
                }
            }
        ],
        store : {
            modelClass : Diner,
            data       : [{
                name     : 'Anim',
                age      : 20,
                city     : 'SF',
                color    : 'red',
                food     : 'Burger',
                foodItem : { 
                    foodType : 'Junk Food'
                }
            }, {
                name     : 'Siam',
                age      : 21,
                city     : 'LA',
                color    : 'blue',
                food     : 'Apple',
                foodItem : { 
                    foodType : 'Healthy Food'
                }
            }]
        }
    });

Post by henrique »

Works, because you used a data source in the field "foodType", if create two models, and don't use de data source property, the grouping does not work.

When I have a free time, I will make the sample that isn't work.


Post by Animal »

This passed too:

    t.iit('complex field dataSource', async t => {
        class FoodItem extends Model {
            static fields = [{
                name : 'foodType'
            }]
        }
        class Diner extends Model {
            static fields = [{
                name       : 'foodItem',
                type       : 'model',
                convert    : function(data) {
                    return new FoodItem(data);
                }
            }]
        }

    grid = new Grid({
        appendTo : document.body,
    
        features : {
            group : 'foodItem.foodType'
        },

        columns : [
            {
                text   : 'Name',
                field  : 'name',
                flex   : 2,
                editor : {
                    type     : 'textfield',
                    required : true
                }
            }, {
                text  : 'Age',
                field : 'age',
                width : 100,
                type  : 'number'
            }, {
                text  : 'City',
                field : 'city',
                flex  : 1
            }, {
                text  : 'Food',
                field : 'food',
                flex  : 1,
            }, {
                text     : 'Color (not sortable)',
                field    : 'color',
                flex     : 1,
                sortable : false,
                renderer({ cellElement, value }) {
                    // renderer that sets text color = text
                    cellElement.style.color = value;
                    return value;
                }
            }
        ],
        store : {
            modelClass : Diner,
            data       : [{
                name     : 'Anim',
                age      : 20,
                city     : 'SF',
                color    : 'red',
                food     : 'Burger',
                foodItem : { 
                    foodType : 'Junk Food'
                }
            }, {
                name     : 'Siam',
                age      : 21,
                city     : 'LA',
                color    : 'blue',
                food     : 'Apple',
                foodItem : { 
                    foodType : 'Healthy Food'
                }
            }]
        }
    });
    t.ok(grid.store.first.foodItem instanceof FoodItem);
});

How to create a problem?


Post by henrique »

The sample below doesn't work.

If you change the grouping field to "testField", everything work because of the data source configurated.

class Person extends Model {
    static get fields() {
        return [
            { name: "name", type: "string" },
            { name: "age", type: "number" },
            { name: "city", type: "string" },
            { name: "color", type: "string" },
            { name: "food", type: "string" },
            { name: "foodItem", type: "model" },
            { name: "testField", type: "string", dataSource: "foodItem.foodType" },
        ];
    }
}

class FoodType extends Model {
    static get fields() {
        return [
            { name: "foodType", type: "string" }
        ];
    }
}

let person1 = new Person({
    name: 'Anim', age: 20, city: 'SF', color: 'red', food: 'Burgger', foodItem: {
        foodType: 'Junk Food'
    }
});

let person2 = new Person({
    name: 'Siam', age: 21, city: 'LA', color: 'blue', food: 'Apple', foodItem: {
        foodType: 'Healthy Food'
    }
});

let MyStore = new Store({
    data: [person1, person2],
    modelClass: Person
});

new Grid({
    appendTo: 'container',

features: {
    group: 'foodItem.foodType'
},

// Headers will ripple on tap in Material theme
ripple: {
    delegate: '.b-grid-header'
},

columns: [
    {
        text: 'Name',
        field: 'name',
        flex: 2,
        editor: {
            type: 'textfield',
            required: true
        }
    }, {
        text: 'Age',
        field: 'age',
        width: 100,
        type: 'number'
    }, {
        text: 'City',
        field: 'city',
        flex: 1
    }, {
        text: 'Food',
        field: 'food',
        flex: 1,
    }, {
        text: 'Color (not sortable)',
        field: 'color',
        flex: 1,
        sortable: false,
        renderer({ cellElement, value }) {
            // renderer that sets text color = text
            cellElement.style.color = value;
            return value;
        }
    }
],

store: MyStore
});

Post by Animal »

This works:

    t.iit('complex field dataSource', async t => {
        class FoodItem extends Model {
            static fields = [{
                name : 'foodType'
            }]
        }
        class Diner extends Model {
            static fields = [{
                name       : 'foodItem',
                type       : 'model'
                // convert    : function(data) {
                //     return new FoodItem(data);
                // }
            }]
        }

    grid = new Grid({
        appendTo : document.body,
    
        features : {
            group : 'foodItem.foodType'
        },

        columns : [
            {
                text   : 'Name',
                field  : 'name',
                flex   : 2,
                editor : {
                    type     : 'textfield',
                    required : true
                }
            }, {
                text  : 'Age',
                field : 'age',
                width : 100,
                type  : 'number'
            }, {
                text  : 'City',
                field : 'city',
                flex  : 1
            }, {
                text  : 'Food',
                field : 'food',
                flex  : 1,
            }, {
                text     : 'Color (not sortable)',
                field    : 'color',
                flex     : 1,
                sortable : false,
                renderer({ cellElement, value }) {
                    // renderer that sets text color = text
                    cellElement.style.color = value;
                    return value;
                }
            }
        ],
        store : {
            modelClass : Diner,
            data       : [{
                name     : 'Anim',
                age      : 20,
                city     : 'SF',
                color    : 'red',
                food     : 'Burger',
                foodItem : { 
                    foodType : 'Junk Food'
                }
            }, {
                name     : 'Siam',
                age      : 21,
                city     : 'LA',
                color    : 'blue',
                food     : 'Apple',
                foodItem : { 
                    foodType : 'Healthy Food'
                }
            }]
        }
    });
});
Screenshot 2022-10-22 at 08.10.26.png
Screenshot 2022-10-22 at 08.10.26.png (63.25 KiB) Viewed 2608 times

If course without the convert, fieldItem doesn't get converted into a Model instance. It's still just the raw object.

What version are you using?


Post Reply