Vaadin - Responsive Columns

Vaadin - Responsive Columns

You need to look into using a different Layout type. Vaadin offers you a CssLayout and CustomLayout as well as the standard Vertical and Horizontal.

My personal favourite at the moment is using a CssLayout and then using a custom CSS Grid to make the components responsive.

Java:

@StyleSheet("MyStyleSheet.css")
public class ResponsiveLayout extends CssLayout {

private static final long serialVersionUID = -1028520275448675976L;
private static final String RESPONSIVE_LAYOUT = "responsive-layout";
private static final String LABEL_ONE = "label-one";
private static final String LABEL_TWO = "label-two";

private Label labelOne = new Label();
private Label labelTwo = new Label();

public ResponsiveLayout() {
config();
addComponents(labelOne, labelTwo);
}

private void config() {
addStyleName(RESPONSIVE_LAYOUT);
labelOne.addStyleName(LABEL_ONE);
labelTwo.addStyleName(LABEL_TWO);
}
}

CSS:

.responsive-layout {
display: grid !important;
grid-template-rows: auto;
grid-template-columns: 1fr 1fr;
display: -ms-grid !important; /* IE */
-ms-grid-rows: auto; /* IE */
-ms-grid-columns: 1fr 1fr; /* IE */
}

.label-one {
grid-column: 1;
-ms-grid-column: 1; /* IE */
}

.label-two {
grid-column: 2;
-ms-grid-column: 2; /* IE */
}

@media all and (max-width : 992px) {
.responsive-layout {
grid-template-columns: 1fr;
-ms-grid-columns: 1fr; /* IE */
}

.label-one {
grid-column: 1;
-ms-grid-column: 1; /* IE */
}

.label-two {
grid-column: 1;
-ms-grid-column: 1; /* IE */
}
}

Responsive Vaadin Flow Grid

A common approach is to have separate columns for mobile and desktop.

On mobile, or other narrow screens, there might only be one column in a stacking manner. This is quite simple to do with template renders, and a template along the lines of

<div>Name: [[item.name]]</div><div>E-mail: [[item.email]]</div>"

It's even possible to define the template as a Polymer template web component, import it, and set a template renderer like this

<mobile-column item="[[item]]"></mobile-column>

To toggle columns, one can add a resize listener (preferably throttled), e.g. as defined here.

The MediaQuery add-on is also very useful for this. I recommend toggling the visibility on the server, to avoid sending unnecessary data and doing unnecessary rendering in the browser.

Responsive multicolumn MultiSelectListBox

There is no (-t yet) some API to do that with just some theme variant. So one option is to create your own
theme
and then provide some styling for the vaadin-list-box in
.../themes/my-theme/components/vaadin-list-box.css. E.g.

:host {
--responsive-size: 20em;
}

:host {
width: var(--responsive-size);
}

@media (min-width: 800px) {
:host {
width: calc(2*var(--responsive-size));
}
}

@media (min-width: 1000px) {
:host {
width: calc(3*var(--responsive-size));
}
}

[part="items"] {
display: flex;
flex-wrap: wrap;
flex-direction: row;
}

[part="items"] ::slotted(vaadin-item) {
width: var(--responsive-size);
}

Depending on your needs, you might want to make that a theme of your
component (then use :host([theme~="responsive"]) for selectors) and
adjust the width and the responsive steps. See Styling
Components

Vaadin 14 grid column width on mobile devices

 grid.getColumns().forEach(e -> e.setAutoWidth(true));

does the trick.

Horizontal and Vertical Layouts are Not Responsive in Vaadin 12

A horizontal or vertical layout is by definition not responsive. Its purpose is to put all children on the same line, either vertically or horizontally, regardless of screen size.

Individual components in Vaadin 10 and newer are responsive where appropriate. As an example, the calendar popup in Date Picker automatically switches between full screen and regular mode depending on the used device. Other components such as Grid cannot know what's appropriate in any given case. It's instead the application developer's responsibility to e.g. configure which columns to use depending on the circumstances.

Positioning different components relative to each other depending on the screen size is always depending on per-application design that cannot be handled by generic components. There are some components that help achieving this for some specific cases, e.g Form Layout, App Layout and Board.

If the generic patterns offered by the provided layouts are not suitable, then the application developer needs to manually configure components differently depending on the case or write CSS that adapts to the screen size. This is still much easier in Vaadin 10+ compared to older version since older versions were heavily relying on pixel calculations that were applied as inline styles that conflicted with attempts of more dynamic definitions applied from CSS.

Vaadin Grid recalculateColumnWidths problems - how to make it more consistant

Let me preface this answer by saying that column width (re)calculation is a complex and relatively expensive task. It needs to be done at the right time - not too early and not too late. If it's done too early, subsequent changes to layouting will mean that size calculation will need to be done again. If it's done too late, it means that the UI will take longer to become responsive again. Trying to "play it safe" by doing column width recalculation more often than needed is an easy source of performance degradation - a Grid can have a LOT of columns, so the cost of recalculation compounds easily.

  1. There are many cases when column width recalculation is triggered. A couple of basic cases are during the layouting phase of the UI, or when a Grid is reattached, or when the inner width of the Grid changes (e.g. due to browser window resize), or when something is done to column sizes (e.g. min or max-width or expand ratio are set). Resizing is indeed queued as you can see here: https://github.com/vaadin/framework/blob/7.7/client/src/main/java/com/vaadin/client/widgets/Grid.java#L3280. It's definitely possible that there's a timing issue. Without the exact conditions of how a calculation goes wrong, it's hard to say when would be a good place to retry - there's no place where "everything is truly finally rendered so that you can schedule a little bit more rendering".
  2. The size of fixed-width columns will not need to be calculated, so these columns should be ignorable from this point of view. In fact, if you can set a fixed width to all or most columns, it will most likely mean a significant performance improvement.
  3. Yes, it could work.

Vaadin 8 Grid scrollbars behave erratically when CSS is used for column widths

Vaadin 8 Grid doesn't support configuring column widths via CSS, you should set any and all column width configurations programmatically (via myColumn.setWidth(pixelWidth);) or the client-side calculations break. Those calculations are crucial for determining the expected width for any columns that don't have a fixed width, and are consequently tightly tied into the scrollbar logic.

Unfortunately there is no built-in solution for setting a percentual width for a column, or for getting Grid's actual size from the server side, or for listening to Grid's size change. However, you can use SizeReporter add-on to help with the latter two (check the Code Samples tab for usage instructions), and calculate the required pixel width from there. GridScrollerExtension add-on also offers both functionalities, as well as querying the current column widths and other Grid-specific features.

For a slightly hackier solution you could also use a JavaScript callback to query the width:

        ui.getPage().getJavaScript().addFunction("gridSizeCallback",
new JavaScriptFunction() {
@Override
public void call(JsonArray arguments) {
// set myColumn width as 30%
myColumn.setWidth(arguments.getNumber(0) * 0.30);
}
});
ui.getPage().getJavaScript()
.execute("gridSizeCallback(document.getElementById('"
+ grid.getId() + "').clientWidth);");

Note that this only gives you the initial width, and doesn't help with the resize problem. The solution for that depends on what all can trigger the Grid resize (e.g. repeating the second JavaScript call through ui.getPage().addBrowserWindowResizeListener when the browser is resized).

How do I add empty spaces in FormLayout in Vaadin Flow?

FormLayout is not purposed to be rigid grid. You can add empty components, or Br component to break a row, which will work better than empty Span.

You can also adjust col-span of FormItem to span it wider than a column. But FormLayout is also responsive, so if you make Browser narrower, it will reflow the fields. Empty components would make it look odd as there are not likely to be place as you want.

You can also set responsive steps to control whether four, three, two, .. columns are shown on different Browser widths:

formLayout.setResponsiveSteps(
new ResponsiveStep("25em", 1),
new ResponsiveStep("32em", 2),
new ResponsiveStep("40em", 3));

In theory you can adjust the responsive steps so that layout is more rigid.

I would assume that a Div component where you set css-grid styles according to what you want to achieve may server you better than FormLayout in this case.



Related Topics



Leave a reply



Submit