Reputation: 6808
I have a text area with long text and I want when the view shows up to be scrolled to maximum bottom:
TextArea textArea = new TextArea();
textArea.setValue(createLongText());
textArea.setHeight("500px");
textArea.setMaxHeight("500px");
textArea.setWidthFull();
textArea.setReadOnly(false);
textArea.getElement().executeJs("this.inputElement.scrollTop = 500");
//text.setReadOnly(true);
textArea.getStyle().set("overflow-y", "auto ! important");
add(currentComponent = textArea);
I tried all of the followings based on things I found on the web:
text.getElement().executeJs("this.inputElement.scrollTop = 1000"); //or scrollHeight
text.getElement().executeJs("this.scrollTop = 1000"); //or scrollHeight
text.getStyle().set("overflow-y", "auto ! important");
textArea.getElement()
.executeJs("this.inputElement.selectionStart= 1000;this.inputElement.selectionEnd= 1001;");
but none of these works.
Here is my complete view:
@Route("")
@PWA(name = "Project Base for Vaadin Flow with Spring", shortName = "Project Base")
@Secured("ROLE_ADMIN")
public class DashboardView extends VerticalLayout {
private Component currentComponent;
@Autowired
public DashboardView() {
Button longButtonText = new Button("Long textarea");
longButtonText.addClickListener(e -> {
if (currentComponent != null)
remove(currentComponent);
TextArea textArea = new TextArea();
textArea.setValue(createLongText());
textArea.setHeight("500px");
textArea.setMaxHeight("500px");
textArea.setWidthFull();
textArea.setReadOnly(false);
textArea.getElement().executeJs("this.inputElement.scrollTop = 500");
// text.setReadOnly(true);
textArea.getStyle().set("overflow-y", "auto ! important");
add(currentComponent = textArea);
});
Button logoutButton = new Button("logout");
logoutButton.addClickListener(e -> {
UI.getCurrent().getSession().close();
SecurityContextHolder.getContext().setAuthentication(null);
SecurityContextHolder.clearContext();
UI.getCurrent().getPage().setLocation("/login");
});
add(new HorizontalLayout(longButtonText, logoutButton));
longButtonText.click();
}
private String createLongText() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 2000; i++) {
sb.append(UUID.randomUUID().toString());
sb.append(System.lineSeparator());
}
return sb.toString();
}
}
My vaadin.version: <vaadin.version>14.1.17</vaadin.version>
What should I do in order to achieve it?
Upvotes: 0
Views: 417
Reputation: 8001
The element that actually scrolls is in the middle of the DOM hierarchy rather than either the top-level component or the inputElement
. I didn't spot any direct way of accessing this element, so you need to use a little indirection in the form of this.inputElement.parentElement.parentElement
.
To scroll to the end, you thus need to do textArea.getElement().executeJs("this.inputElement.parentElement.parentElement.scrollTop = this.inputElement.parentElement.parentElement.scrollHeight");
.
It should also be mentioned this approach is dependent on implementation details related to the internal structure of the component. This means that there's a risk that the structure is changed in some future version without that change being treated as a breaking change.
Upvotes: 1