1

I would like to use FormLayout where one of the fields is visible depending on another field. Is there a way to keep the formatting the same, that is for all the fields after it to stay in their same position when another component is invisible.

Below is the code to reproduce as well as a screenshots of what I would like compared to the current behavior. In essence each time you select the combobox you make the "Year Joined Team" field invisible/visible.

TextField nameTextField = new TextField("Name");
ComboBox<String> teamComboBox = new ComboBox<>("Team");
DatePicker yearJoinedDatePicker = new DatePicker("Year Joined Team");
TextField moreFieldsTextFields = new TextField("More fields");

FormLayout formLayout = new FormLayout();
formLayout.setWidth("600px");
formLayout.setResponsiveSteps(new FormLayout.ResponsiveStep("0", 2, FormLayout.ResponsiveStep.LabelsPosition.TOP));

formLayout.add(nameTextField,
        teamComboBox, yearJoinedDatePicker,
        moreFieldsTextFields);

teamComboBox.setItems(List.of("One", "Two"));
teamComboBox.addValueChangeListener(change -> yearJoinedDatePicker.setVisible(!yearJoinedDatePicker.isVisible()));

formLayout.setColspan(nameTextField, 2);

add(formLayout);

Ideally the goal is to have the fields below the yearJoinedTeamDatePicker component to stay below so that all other components below continue to be aligned correctly when it's set to be invisible.

enter image description here

Instead what actually happens is that all the components are shifted on field to the left, as if the invisible component is no longer part of the FormLayout. Meaning the moreFieldsTextField is now on a different row, and if everything is setup for two columns every row will be incorrect. I understand that this makes sense in some context but in a FormLayout is there a way to keep the form formatted if a component is invisible?

enter image description here

If for example I had firstname and lastname as two side by side fields they would now be on different rows as shown below:

enter image description here

A very hacky solution would be to add in a Span component or something like that and make it invisible when the yearJoinedDatePicker field is visible, and invisible when it's visible. Basically fill it in with an empty field when it's invisible. That is a hacky workaround but it doesn't seem like an appropriate solution. With that in mind is there a way to keep the formatting/layout if a component is invisible?

Stephane Grenier
  • 15,527
  • 38
  • 117
  • 192

2 Answers2

0

What you are trying to achieve is sort of defying the purpose of FormLayout. FormLayout has css flex rules to wrap elements / components by row. Thus if you switch visibility of a component, the behavior is as you described.

One thing you could do, is to wrap "Team" and "Year joined team" inside e.g. HorizontalLayout and set

formLayout.setColspan(horizontalLayout, 2);

See, also my previous answer about FormLayout https://stackoverflow.com/a/69270190/8962195

Tatu Lund
  • 9,949
  • 1
  • 12
  • 26
  • FormLayout is honestly the best layout for forms, it's the simplest and easiest to use, results in the least amount of code, etc. The only thing is that if you want to keep formatting it's not the greatest. I've been trying to find an alternative layout but I can't see one. The only way is either to do some hacky stuff for special cases with FormLayout or to use a complex combination of HorizontalLayouts. By the way I like this page a lot: https://labs.vaadin.com/layout-examples/ – Stephane Grenier Oct 06 '21 at 18:24
0

If you want to keep the place, maybe it's vable for you to set the field ti disabled with setEnabled.

I'm not sure how it would behave, but you could try CSS display: none instead of the setVisibility(false).

Hawk
  • 2,042
  • 8
  • 16