On the Column Visibility example on https://vaadin.com/docs/latest/ds/components/grid/#column-visibility the code shows a class ColumnToggleContextMenu which isn't part of the Vaadin API however it seems to somehow adjust how the button is hooked so that it can be left clicked rather than the default right click for a context menu. With that in mind the code below will only show the context menu on a right click, I cannot get it to work like the example code. My code is:
Button showHideColumnsButton = new Button("Show/Hide Columns");
showHideColumnsButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
ContextMenu contextMenu = new ContextMenu(showHideColumnsButton);
for(Grid.Column column : grid.getColumns()) {
contextMenu.addItem(getColumnName(column), e -> showHideColumn(column));
}
I'm considering using a MenuBar instead to see if that will work but I'd prefer to figure out how to use a Button if possible as that seems more appropriate (mainly because it allows the checkbox to show if a column is visible or hidden).
In order to make the context menu to open on left click use setOpenOnClick(true):
Button showHideColumnsButton = new Button("Show/Hide Columns");
showHideColumnsButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
ContextMenu contextMenu = new ContextMenu(showHideColumnsButton);
contextMenu.setOpenOnClick(true)
for(Grid.Column column : grid.getColumns()) {
contextMenu.addItem(getColumnName(column), e -> showHideColumn(column));
}
I am trying to add flag icons in a Vaadin Flow Combobox using a customer ComponentRenderer:
new ComponentRenderer<>(locale -> {
HorizontalLayout item = new HorizontalLayout();
item.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.BASELINE);
Span langIcon = new Span();
langIcon.addClassNames("flag-icon", "flag-icon-" + getTranslation("App.Language.Flag", locale));
item.add(langIcon);
item.add(new Span(locale.getDisplayLanguage(locale)));
return item;
});
The icons come from flag-icon-css (see here) included via gradle compile dependency "org.webjars.bowergithub.lipis:flag-icon-css:3.3.0" and annotation #StyleSheet("frontend://bower_components/flag-icon-css/css/flag-icon.min.css") on my main layout class. In a different place with ListBox component, icons are shown as expected. However, when used via ComponentRenderer in a combobox nothing shows up.
Inspecting the HTML, I see that the <vaadin-combo-box-item> within ComboBox renders everything under its shadow root in contrast to <vaadin-item> within ListBox which renders it as <slot>. Why is that? And how could I use the flag icon CSS styles in combo box items?
I created a customfield that was being used in form using Vaadin 13 beta1 prerelease. However, it creates this giant blank space at the top of the field (see my green markings below, and ignore the red and yellow background colors as they were just for my understanding of what's going on.)
How can I fix this? I tried to manually set the minHeight, maxHeight, height values, but nothing changed....Here's my code for the customfield. (The code for the formlayout is fairly standard and so was not included here.)
package com.deepsearch.fe.util;
import com.vaadin.flow.component.customfield.CustomField;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.textfield.TextField;
public class TextRangeFieldInt extends CustomField<StartToEndRangeInt> {
private final TextField start = new TextField();
private final Label lblTo = new Label("to");
private final TextField end = new TextField();
public TextRangeFieldInt(final StartToEndRangeInt startToEndRangeInt, final String startEndWidths) {
this.setHeight("10px");
this.setMinHeight("10px");
this.setMaxHeight("10px");
this.getElement().getStyle().set("background-color", "red");
//this.getStyle().set("background-color", "red");
setPresentationValue(startToEndRangeInt);
final HorizontalLayout hl = new HorizontalLayout();
hl.setWidth("100%");
hl.getStyle().set("background-color", "yellow");
hl.setMargin(false);
hl.setPadding(false);
hl.setAlignItems(FlexComponent.Alignment.CENTER);
lblTo.setWidth("1.5rem");
start.setWidth(startEndWidths);
end.setWidth(startEndWidths);
hl.add(start);
hl.add(lblTo);
hl.add(end);
add(hl);
}
#Override
protected StartToEndRangeInt generateModelValue() {
return new StartToEndRangeInt(Integer.parseInt(start.getValue()), Integer.parseInt(end.getValue()));
}
#Override
protected void setPresentationValue(StartToEndRangeInt newPresentationValue) {
start.setValue(newPresentationValue.getStartStr());
end.setValue(newPresentationValue.getEndStr());
}
}
On a different but related note, am I doing this right? There wasn't a good example yet for customfield (since it's still in beta), so I guessed that I am supposed to use a horizontal layout to add my individual components etc.
Update #1
Based on #Jouni comment below, I tried to create a much simpler formlayout which only had a few "simple" fields (eg all text fields, nothing fancy like a checkbox). But the problem remained. See screenshot below as well as the soure code for the formlayout. (Note: I even commented out the "responsiveStep" portion of the formlayout so that only default/simple scenarios were being used.)
And, here's the code snippet (it's nothing fancy):
final FormLayout nameLayout = new FormLayout();
// nameLayout.setResponsiveSteps(
// // new FormLayout.ResponsiveStep("0", 1),
//// new FormLayout.ResponsiveStep("21em", 2),
// new FormLayout.ResponsiveStep("0em", 3));
// nameLayout.add(uniqueExpName, sampleComplexity, gradientLength, numTechRepl, minMz, maxMz, enableVariableDiaWindow, densestMz, vlSampleCondit, useSettingsNextTime);
// nameLayout.add(uniqueExpName, sampleComplexity, gradientLength, numTechRepl, mzRange, enableVariableDiaWindow, densestMz, vlSampleCondit, useSettingsNextTime);
// nameLayout.add(uniqueExpName, sampleComplexity, gradientLength, numTechRepl, mzRange, enableVariableDiaWindow, densestMz, lblSampleAndConditionNumber, sampleAndCondNum);
nameLayout.add(uniqueExpName, gradientLength, numTechRepl, mzRange, densestMz);
nameLayout.setWidth("55rem");
add(nameLayout);
setAlignSelf(Alignment.CENTER, nameLayout);
The issue comes from CSS.
The default vertical alignment for inline content is baseline, which is also used by the core Vaadin layouts (including Form Layout). Baseline alignment works so that the first line of text inside an element is used for aligning that element.
In the case of Vaadin field components, that would be the label text. But, since we want to align the fields based on the field input element so that it aligns nicely with text, buttons, checkboxes, etc. on the same line (even when the field has a label and/or an error message), we have some additional CSS to move the baseline in the field elements. And apparently, this fix is missing from Custom Field.
Is it possible to add a buttons in Vaadin 7 to Accordion com.vaadin.ui.TabSheet.Tab caption ?
Right now I can only add a String into Tab caption.
This is my current screen:
I need to add the same Edit/Remove icons(as I have for Live Chat and WMA) near the General and Julia Group tab captions.
Unfortunately it's not possible.
You could create a server-side composition, which behaves like Accordion but then you could design the component so that you can add buttons to tab captions. You could start with something like this:
public class MyAccordion extends CustomComponent {
public MyAccordion() {
VerticalLayout layout = new VerticalLayout();
setCompositionRoot(layout);
// TODO layout should contain all tabs and tab captions
}
}
Another option would be to create an extension by using GWT or Javascript and on the client-side modify DOM so that there a two buttons on tab captions.
How do I make my panels extend the full width across the page and not just to where their components stop?
As also cfrick suggested, use setSizeFull(), if your component is nested inside other layouts/components, you need to set all of them to full size as follows.
VerticalLayout panelWrapper = new VerticalLayout();
Panel yourPanel = new Panel();
panelWrapper.addComponent(yourPanel);
yourPanel.setSizeFull();
panelWrapper.setSizeFull();
If you have more parent components, you need to setSizeFull() all of them back to the UI root.