Search code examples
cuba-platform

CUBA platform how to dynamically change field color


I'm trying to dynamically change some field color when it has changed due to some processing.

CUBA documentation explains how to do it statically through web theme extension (https://doc.cuba-platform.com/manual-6.2/web_theme_extension.html), but not dynamically. Although it is possible in Vaadin (https://vaadin.com/wiki/-/wiki/Main/Dynamically%20injecting%20CSS) on which platform web gui is built upon.

I suppose that if I use the Vaadin way of injecting CSS it will work (which I will try) but I will then have Vaadin specific code, which I'm trying to avoid.

Is there a CUBA way of doing so I'm missing ?

Edit:

I'm trying to have any field of a form to change background color when it has changed from its initial value. As per CUBA documentation (https://doc.cuba-platform.com/manual-6.2/web_theme_extension.html) I need to : - create a SCSS mixin with background color - inject the field in the editor class in order to have access to it - react to a field change event and then define the style name of the field

I did create the SCSS mixin, but two issues I have : 1) I would like to retrieve the field instance dynamically instead of injecting it (keep code clean and light) 2) I would like to avoid defining the background color statically so that the color could be parameterized at runtime

For 1) I tried to injected the fieldGroup and used getFieldComponent(), then applied the style with setStyleName on it when it is changed. It worked but I would prefer to define this behavior for every field that is an input field.

For 2) apart from using Vaadin specific feature of injecting CSS (and tighing my code to Vaadin (and so leading me away of generic interface) I do not see how to do

Hope it's more clear


Solution

  • You cannot set truly dynamic color (any RGBA) from code to field but you can create many predefined colors for your field:

    @import "../halo/halo";
    
    @mixin halo-ext {
      @include halo;
    
      .v-textfield.color-red {
        background: red;
      }
      .v-textfield.color-blue {
        background: blue;
      }
      .v-textfield.color-green {
        background: green;
      }
    }
    

    I do not recommend using styles injected from code (as Vaadin Page does) since it is a mixing of logic and presentation. Instead you can create all predefined styles (30-50 styles should be enough) and assign it depending on some conditions using setStyleName method:

    public class ExtAppMainWindow extends AppMainWindow {
        @Inject
        private TextField textField;
    
        private int steps = 0;
    
        public void changeColor() {
            if (steps % 2 == 0) {
                textField.setStyleName("color-red");
            } else {
                textField.setStyleName("color-blue");
            }
            steps++;
        }
    }
    

    If you want to apply the logic of color change for all TextFields inside of FieldGroup you can iterate FieldGroup fields in the following way:

    for (FieldGroup.FieldConfig fc : fieldGroup.getFields()) {
        Component fieldComponent = fieldGroup.getFieldComponent(fc);
        if (fieldComponent instanceof TextField) {
            TextField textField = (TextField) fieldComponent;
            textField.addValueChangeListener(e -> 
                    textField.setStyleName("color-red")
            );
        }
    }