Styling individual cells in a Grid V24

Folks, I’m trying to figure out if there is a way to style individual cells in a grid. The use case is marking cells “invalid” color on form validation. I’ve tried the following, and the lamda seems to be called and correct value returned, but the style is not added. Is something missing? TIA

getColumnByKey(VALUE_KEY).setClassNameGenerator(vo -> isBlank(vo.getValue()) ? "eem-invalid-value" : null);

Hi @imeshev,

This cookbook recipe should help you get a better idea of how to achieve this.

Let me know if you still need any further help.

1 Like

Also note that PartNameGenerator is now the recommended approach, as seen in the docs here: Grid | Components | Vaadin Docs ; ClassNameGenerator still exists but only for backwards compability.

Does it mean that ClassNameGenerator is not supposed to work? The Javadocs don’r say anything about it:

  /**
         * Sets the function that is used for generating CSS class names for
         * cells in this column. Returning {@code null} from the generator
         * results in no custom class name being set. Multiple class names can
         * be returned from the generator as space-separated.
         * <p>
         * If {@link Grid#setClassNameGenerator(SerializableFunction)} is used
         * together with this method, resulting class names from both methods
         * will be effective. Class names generated by grid are applied to the
         * cells before the class names generated by column. This means that if
         * the classes contain conflicting style properties, column's classes
         * will win.
         *
         * @param classNameGenerator
         *            the class name generator to set, not {@code null}
         * @return this column
         * @throws NullPointerException
         *             if {@code classNameGenerator} is {@code null}
         * @see Grid#setClassNameGenerator(SerializableFunction)
         */
        public Column<T> setClassNameGenerator()

I did exactly that. Here is my CSS, but I don’t beleive it matters because I don’t see “eem-invalid-value” anywhere in the DOM inspector.

.eem-invalid-value {
    background-color: #ffeeee;
}

Here is the cookbook code:

expensesGrid
            .getColumnByKey("expense")
            .setClassNameGenerator(monthlyExpense -> monthlyExpense.getExpense() > 500 ? "warn" : null);

Here is my code:

getColumnByKey(VALUE_KEY).setClassNameGenerator(vo -> isBlank(vo.getValue()) ? "eem-invalid-value" : null);

I feel like I’m missing something.

It works but it is freaking difficult to use. You, me and everybody else not familiar with Vaadin front-end build mechanism and shadow DOM styling should use the partname generater instead. Probably the classnamegenerater should be depracated so that people would find the partnamegenerator instead, but I guess there is some reason why that is not done. Made a proposal to change the javadocs at least:

The classname should appear in the shadowDOM of vaadin-grid. That’s why the styling needs to also be applied in the shadowDOM scope of the vaadin-grid component.

In the cookbook example this is done with @CssImport.

In V24 you can create a new stylesheet in /frontend/themes/my-app/components/vaadin-grid.css and place your styles in there. It will automatically be loaded in the shadowDOM scope of the component.

If you suspect that the classname is not applied anywhere, you can try viewing the DOM with browser’s inspector and hit Ctrl/Cmd+F to enable search.
image

1 Like

OK, I checked the example using PartNameGenerator, and seems to style the entire row or column. I’d like to style a cell.

If you use the setPartNameGenerator method from Column, you can apply the part name conditionally, which allows you to target an individual cell, for example

grid.addColumn(...).setPartNameGenerator(person -> {
    if (person.getId() == 3) {
        return "special";
    } else { 
        return null;
    }
});

I’ve created grid like this

Grid<Unit> grid = new Grid<>(Unit.class);
        grid.setSizeFull();
        grid.addClassName("custom-styling");
        grid.setItems(query -> unitService.fetchAll(query));
        grid.setPartNameGenerator(unit -> "recently-edited-row");

and the CSS is


vaadin-grid.custom-styling::part(recently-edited-row) {
    background-color: lightblue; /* Customize the background color as needed */
    transition: background-color 0.5s; /* Add a smooth transition effect */
}

I do not see any change.


The grid is same with and without setPartNameGeneratir(). What am I missing ?

Tried your sample and it worked for me (24.6.0).

image

Have you checked, if the style appears in the dom? Is the rest of your theme working?

I see them here


and my styless.css contains

@import url('./main-layout.css');

@import url('./mobile.css');
@import url('./grid-styling.css');
```.

Shoud I move this to components dir inside frontend ?

Looks the below is preventing the above styles

vaadin-grid::part(row):hover {
  background: var(--lumo-primary-color-10pct);

}

vaadin-grid::part(body-cell) {
  background-color: unset !important;
   cursor:pointer;
}

This one I’ve to show some color when hovering on a row. Looks both are colliding on each other

If you set the value with an !important, then this will be the reason, that

vaadin-grid.custom-styling::part(recently-edited-row) {
    background-color: lightblue; /* Customize the background color as needed */
    transition: background-color 0.5s; /* Add a smooth transition effect */
}

is not working, since both are targeting the same element, but the !important wins.

You should use !important only in rare cases, when you have no other way to apply your styles. In normal cases, any !important means, that the selectors or styles order is incorrect and should be corrected.

1 Like

No. ::part selector is light dom styling, while anything in the components folder will be injected to the shadow dom styles.

Thanks. That was the issue. Now I can see the changes

the new css is

/* Add this to your global CSS file */
vaadin-grid.custom-styling::part(recently-edited-row) {
    background-color: lightblue; /* Customize the background color as needed */
    transition: background-color 0.5s; /* Add a smooth transition effect */
}

/* Add this to your global CSS file */
vaadin-grid.custom-styling::part(mouse-over) {
    background: var(--lumo-primary-color-10pct); /* Customize the background color as needed */
    transition: background 0.5s; /* Add a smooth transition effect */
     cursor:pointer;
}