Premium support for our pure JavaScript UI components


Post by jk@datapult.dk »

Hi there,

In this video you will notice that I render rows where city is not Paris, which works fine until I start filtering:
https://www.dropbox.com/s/katajpyjdk7fkft/Screen%20Recording%202023-05-28%20at%2020.48.05.mov?dl=0

import { Model, Grid, Toast, DataGenerator } from '../../build/grid.module.js?468078';
import shared from '../_shared/shared.module.js?468078';

function renderDate(row, value, record) {
    if(record.city === "Paris") {
        return;
    }
    row.eachElement(el => el.style.background = '#fffe0085');
}
class CityModel extends Model {
    static idField = 'name';
    static fields = [
        'name',
        'region'
    ];
}

const cityCombo = {
    type         : 'combo',
    valueField   : 'name',
    displayField : 'name',
    cls          : 'city-combo',
    chipView     : {
        iconTpl : () => '<i class="b-icon b-fa-city"></i>'
    },
    listItemTpl : ({ name }) => `<i class="b-icon b-fa-city"></i>${name}`,
    picker      : {
        cls              : 'city-list',
        allowGroupSelect : false
    },
    store : {
        modelClass : CityModel,
        groupers   : [
            { field : 'region', ascending : true }
        ],
        data : [
            { name : 'Stockholm', region : 'Europe' },
            { name : 'Barcelona', region : 'Europe' },
            { name : 'Paris', region : 'Europe' },
            { name : 'Dubai', region : 'Middle East' },
            { name : 'Istanbul', region : 'Middle East' },
            { name : 'Riyadh', region : 'Middle East' },
            { name : 'New York', region : 'US' },
            { name : 'San Francisco', region : 'US' },
            { name : 'Washington', region : 'US' },
            { name : 'Moscow', region : 'Russia' },
            { name : 'St Petersburg', region : 'Russia' }
        ]
    }
};

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

features : {
    filterBar : {
        compactMode : false,
        filter      : { property : 'city', value : 'Paris' }
    },
    stripe    : true,
    quickFind : true
},

columns : [
    {
        text  : 'Name (custom)',
        field : 'name',
        width : 150,
        // This column has a custom filtering function that matches the first letter in each word (JBA -> John B Adams)
        filterable({ value, record }) {
            const matches = record.name.match(/\b(\w)/g);
            return matches ? matches.join('').startsWith(value) : false;
        },
        renderer({row, value, record}) {
            return renderDate(row, value, record)
        }
    },
    { text : 'Age', field : 'age', width : 100, type : 'number' },
    {
        text       : 'City',
        field      : 'city',
        flex       : 1,
        editor     : cityCombo,
        filterable : {
            filterField : Object.assign(cityCombo, { multiSelect : true })
        }
    },
    { text : 'When', field : 'start', flex : 1, type : 'date' },
    // This column has filtering turned off
    { text : 'Team (not filterable)', field : 'team', flex : 1, filterable : false }
],

data : DataGenerator.generateData(100),

tbar : [
    {
        type        : 'button',
        ref         : 'useCompact',
        text        : 'Use compact mode',
        icon        : 'b-fa-square',
        pressedIcon : 'b-fa-check-square',
        toggleable  : true,
        onToggle    : ({ pressed }) => {
            if (pressed) {
                Toast.show({
                    html    : 'Compact mode - Click a column header and type to filter',
                    timeout : 5000
                });
            }
            grid.features.filterBar.compactMode = pressed;
        }
    },
    {
        type     : 'button',
        ref      : 'removeAll',
        text     : 'Remove all filters',
        icon     : 'b-fa-times',
        onAction : () => grid.store.clearFilters()
    }
]
});


Post by mats »

What is the problem? Yellow coloring of Paris rows?


Post by jk@datapult.dk »

Yes :-)


Post by alex.l »

Hi, you need to clear background also, not only set. Because cells re-used for other data when you filtering, but background you set remain old. So fix your renderDate to not only set custom bg, but also clear it. Something like

if(record.city === "Paris") {
        row.eachElement(el => el.style.background = '#ffffff');
    } else {
        row.eachElement(el => el.style.background = '#fffe0085');
    }
    

All the best,
Alex


Post by jk@datapult.dk »

Thanks! And when using stripe: true, how should I proceed with your fix?


Post by alex.l »

Yes, your code will definitely override stripe feature behaviour. Here is the code from stripe feature renderer in Stripe.js. You can review it to make your code better

    onRenderRow({ row }) {
        const
            { disabled } = this,
            even         = row.dataIndex % 2 === 0;

    row.assignCls({
        'b-even' : !disabled && even,
        'b-odd'  : !disabled && !even
    });
}

Btw I would also suggest you to use classes instead of direct styling. You can simply add/remove custom class, which is easier to manage.

All the best,
Alex


Post Reply