Setting Component readonly with normal design

Hi,

I’m trying to make a view where the User can see som details about the backend.
So I need textboxes and checkboxes to display but the user has no right/need to chenge the values (because it isn’t triggering some action).
So I made the fields readonly.
But the readonly-design of the fields doesn’t look nice and I want them to look like active fields.
Is it possible to change the design for those fields?

Best regards
Daniel

Hi Daniel

Styling the textfield is probably going to be a little more complicated than you may have anticipated, because the textfields are made in html using shadow DOM. [Here]
(https://github.com/vaadin/vaadin-themable-mixin/wiki) is a good documentation on styling shadow parts, if you are not yet familiar with it.

From the CSS perspective, this CSS will make a vaadin readonly textfield look like a normal vaadin textfield:

:host([readonly]
) [part="input-field"]
 {	
	background-color: var(--lumo-contrast-10pct) !important;
	color: var(--lumo-body-text-color) !important;
	cursor: text !important;
}

:host([readonly]
) [part="input-field"]
::after {
	border: none !important;
}

In order to apply this css to your text fields you will have to create your own TextField class by extending the existing TextField. There you can use @HtmlImport("path/to/myTextField.html) to supply your own styling for the shadow DOM that is generated for the textField.

I think the [documentation]
(https://vaadin.com/docs/v12/flow/creating-components/tutorial-extending-component.html) about all this is a bit confusing, which is why I will provide you with as much information about it as I can.

customTextField.html:

<dom-module id="custom-text-field" theme-for="vaadin-text-field">
    <template>
        <style>
            :host([readonly]
) [part="input-field"]
 {
                background-color: var(--lumo-contrast-10pct) !important;
                color: var(--lumo-body-text-color) !important;
                cursor: text !important;
            }

            :host([readonly]
) [part="input-field"]
::after {
                border: none !important;
            }
        </style>
    </template>
</dom-module>

CustomTextField class:

@HtmlImport("styles/components/customTextField.html") // styles is located in frontend folder
public class CustomTextField extends TextField {
    
    // All Constructor Overloads.
    // If you never use some of them, you can remove them if you want
    public CustomTextField(){
        super();
    }
    public CustomTextField(String label){
        super(label);
    }
    public CustomTextField(String label, String placeholder){
        super(label, placeholder);
    }
    public CustomTextField(String label, String initialValue, String placeholder) {
        super(label, initialValue, placeholder);
    }
    public CustomTextField(ValueChangeListener<? super ComponentValueChangeEvent<TextField, String>> listener){
        super(listener);
    }
    public CustomTextField(String label,
                           ValueChangeListener<? super ComponentValueChangeEvent<TextField, String>> listener){
        super(label, listener);
    }
    public CustomTextField(String label, String initialValue,
                     ValueChangeListener<? super ComponentValueChangeEvent<TextField, String>> listener) {
        super(label, initialValue, listener);
    }
}

Hi,

thanks for this much information. I’ll try that later (cause at the moment I have no clue where the frontendfolder should be located in a WLP Project).
But when this is so problematic, how is a page like mine supposed to be build, especally when I want to use checkboxes?

It’s not problematic, it’s just a little more complex :wink: I haven’t fully understood it myself before I wrote my answer, but that is because I haven’t had the need for custom styling yet. In my opinion, the stlyes that come with the lumo theme are very nice and thought through.
My recommendation - especially when you just started using Vaadin - is to leave the styles as they are if a custom style is not 100% necessary. If you still want to apply custom styles then go ahead - I hope I provided you with enough information to try it out yourself or read further into it.

I have no clue where the frontendfolder should be located in a WLP Project
Here is a link to a [blog post about the frontend folder]
(https://vaadin.com/blog/vaadin-10-and-static-resources) by Leif Åstrand. I believe that WLP works with .war files. If so, then your frontend folder should be located at src/main/webapp/frontend/.

I found out that it can be done a little simpler than I did in my answer - Extending TextField with an own class is in fact not needed. You can put the contents of the customTextField.html (see my first answer yesterday) directly into the global css file (which is usually called shared-styles.html and is imported by the MainView, just like it is done [here]
( https://vaadin.com/forum/thread/17367716/17367717))

The following shared-styles.html will apply our custom CSS to all TextFields in your view:

<link rel="import" href="../bower_components/polymer/lib/elements/custom-style.html">

<custom-style>
    <style>
        /* global css */
		/* for example make primary color darker. just an example of a global css block :) */
        html {
            /* --lumo-primary-color: #1053a9 !important; */
        }
    </style>
</custom-style>

<!-- this will apply to all TextFields because of 'theme-for="vaadin-text-field"' -->
<!-- if you want to style for example checkboxes, use 'theme-for="vaadin-checkbox"' (the used tag of Checkbox is vaadin-checkbox) -->
<dom-module id="custom-text-field" theme-for="vaadin-text-field">
    <template>
        <style>
            :host([readonly]
) [part="input-field"]
 {
                background-color: var(--lumo-contrast-10pct) !important;
                color: var(--lumo-body-text-color) !important;
                cursor: text !important;
            }

            :host([readonly]
) [part="input-field"]
::after {
                border: none !important;
            }
        </style>
    </template>
</dom-module>