Set width of Dialog widget to a percentage of the page in Vaadin 14
How can I get a Dialog to fill most but not all of the browser window, and be dynamic resized as the user grows/shrinks the window's width/height?
By setting width/height to overlay
part of the vaadin-dialog-overlay
using CSS.
A longer version
The behavior you see is a consequence of style being applied to the div
inside a flow-component-renderer
, not the overlay
part as one would expect. The relevant tickets are:
- setWidth and setHeight either not working, or are wrongly documented
- Add a note that 'setWidth' sets a width to a 'flow-component-renderer', not an overlay/dialog itself
If you inspect the dialog having fixed width in DevTools, you will notice that the dialog itself is actually wider.
The correct (I mean it is correct, but not expected) way would be to style an overlay
part of the dialog via css using:
[part="overlay"]{
width:80%;
}
and
@CssImport(
value= "./styles/dialogOverlay.css",
themeFor = "vaadin-dialog-overlay"
)
After that, the width is taking 80%
as expected. I hope the screenshot above illustrates the issue better:
How to correctly specify dialog size in vaadin-flow
Fixed the problem by using Lumo theme instead of Material one.
How to layout a Dialog component in vaadin?
You do the layout of the dialog in the same manner that you would do the layout of any other component: you use the appropriate layout component, with whatever nested components and layouts give you the desired look. The styling of the dialog is done the same way as any other component.
Vaadin 14 dialog with tabs
Would something like this work?
@Route("dialogs-tabs")
public class DialogContainerTabs extends VerticalLayout {
public DialogContainerTabs(){
Dialog dialog=new Dialog();
Tab tab1 = new Tab("Tab one");
Div page1 = new Div();
page1.setText("Page#1");
Tab tab2 = new Tab("Tab two");
Div page2 = new Div();
page2.setText("Page#2");
page2.setVisible(false);
Tab tab3 = new Tab("Tab three");
Div page3 = new Div();
page3.setText("Page#3");
page3.setVisible(false);
Map<Integer, Component> tabsToPages = new HashMap<>();
tabsToPages.put(0, page1);
tabsToPages.put(1, page2);
tabsToPages.put(2, page3);
Tabs tabs = new Tabs(tab1, tab2, tab3);
Div pages = new Div(page1, page2, page3);
Set<Component> pagesShown = Stream.of(page1)
.collect(Collectors.toSet());
tabs.addSelectedChangeListener(event -> {
pagesShown.forEach(page -> page.setVisible(false));
pagesShown.clear();
Component selectedPage = tabsToPages.get(tabs.getSelectedIndex());
selectedPage.setVisible(true);
pagesShown.add(selectedPage);
});
Button back=new Button();
back.setIcon(VaadinIcon.ARROW_BACKWARD.create());
dialog.add(back);
back.addClickListener(e->{
if(tabs.getSelectedIndex()>0){
pagesShown.forEach(page -> page.setVisible(false));
pagesShown.clear();
tabs.setSelectedIndex(tabs.getSelectedIndex()-1);
Component selectedPage = tabsToPages.get(tabs.getSelectedIndex());
selectedPage.setVisible(true);
pagesShown.add(selectedPage);
}
else{
//Do what you want, maybe navigate to the last one? or NOOP
}
});
Button forward=new Button();
forward.setIcon(VaadinIcon.ARROW_FORWARD.create());
dialog.add(forward);
forward.addClickListener(e->{
if(tabs.getSelectedIndex()<tabsToPages.size()-1){
pagesShown.forEach(page -> page.setVisible(false));
pagesShown.clear();
tabs.setSelectedIndex(tabs.getSelectedIndex()+1);
Component selectedPage = tabsToPages.get(tabs.getSelectedIndex());
selectedPage.setVisible(true);
pagesShown.add(selectedPage);
}
else{
//Do what you want, maybe navigate to the first one one? or NOOP
}
});
dialog.add(tabs);
dialog.add(pages);
dialog.setOpened(true);
add(dialog);
}
}
I have buttons on top of tabs, but you could put them inside the view, if you want so, of course.
In Vaadin 14, tabs doesn't hold components, so once you have switched a tab, you should manually set previous component to hidden
and the new one to visible
The result dialog looks like this:
And tabs code is taken directly from here : Tabs : Java Examples
P.S.
It's just a POC and this might not be exactly 1:1 with what you want, but you could get an idea from here, how to follow :) And this code should be refactored to not re-use the same logic three times (in tabs listener and back/forward buttons)
Horizontally centering a popup window in Vaadin
Solution 1: Use SizeReporter
Indeed, setPositionY()
will reset the window's centered
property to false
. As the width of your pop-up and that of your browser window are not know before they appear on the screen, the only way I know to get those values is to use the SizeReporter add-on. Its use is quite straightforward:
public class MyUI extends UI {
private Window popUp;
private SizeReporter popUpSizeReporter;
private SizeReporter windowSizeReporter;
@Override
protected void init(VaadinRequest request) {
Button button = new Button("Content button");
VerticalLayout layout = new VerticalLayout(button);
layout.setMargin(true);
popUp = new Window("Pop-up", layout);
popUp.setPositionY(40);
addWindow(popUp);
popUpSizeReporter = new SizeReporter(popUp);
popUpSizeReporter.addResizeListenerOnce(this::centerPopUp);
windowSizeReporter = new SizeReporter(this);
windowSizeReporter.addResizeListenerOnce(this::centerPopUp);
}
private void centerPopUp(ComponentResizeEvent event) {
int popUpWidth = popUpSizeReporter.getWidth();
int windowWidth = windowSizeReporter.getWidth();
if (popUpWidth == -1 || windowWidth == -1) {
return;
}
popUp.setPositionX((windowWidth - popUpWidth) / 2);
}
}
This piece of code will be okay as long as you don't resize the pop-up. If you do, it will not be automatically recentered. If you replace addResizeListenerOnce()
by addResizeListener()
then it will automatically recenter the pop-up but you'll get some "UI glitches" as the add-on sends resize events almost continually while you're resizing your pop-up...
You could try to do it using CSS, but I personally avoid CSS as much as I can with Vaadin :).
You'll need to recompile the widgetset after you've added the add-on as a dependency.
Solution 2: Use com.vaadin.ui.JavaScript
I won't vouch for the portability of this solution but I guess it will work on most modern browsers.
public class MyUI extends UI {
private Window popUp;
@Override
protected void init(VaadinRequest request) {
Button button = new Button("Content button");
VerticalLayout layout = new VerticalLayout(button);
layout.setMargin(true);
popUp = new Window("Pop-up", layout);
popUp.setPositionY(40);
popUp.addStyleName("window-center");
addWindow(popUp);
// Add a JS function that can be called from the client.
JavaScript.getCurrent().addFunction("centerWindow", args -> {
popUp.setPositionX((int) ((args.getNumber(1) - args.getNumber(0)) / 2));
});
// Execute the function now. In real code you might want to execute the function just after the window is displayed, probably in your enter() method.
JavaScript.getCurrent().execute("centerWindow(document.getElementsByClassName('window-center')[0].offsetWidth, window.innerWidth)");
}
}
Related Topics
To Change Text-Color in Mat-List-Option
CSS Cursors Are Not Working in Webkit Browsers
CSS3 Selector Last Element That Is Not of Class X
How to Integrate a Thunderbird Extension with Lightning
Vertical Align Multiple Image with Different Height
CSS Variable with Fallback Value of Itself
CSS Doesn't Load After Migration of Magento Website
Google Fonts Font Doesn't Load
Is Globally Defined Position:Relative to Page Container a Good Practice
CSS Dropdown Menu Hidden Behind Content Ie7
Full Width Background, Without a Wrapper
Remove Scollbar When No Need to Scroll
Selenium Webdriver CSS Selector Help - for Selecting Date
CSS Change Border Color on Hover
Vertical and Horizontal Alignment of Text with CSS
How to Change The Color of The Text Cursor in an Input Field in Ie