New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Split layout get splitter-position after moving the splitter manually #1517
Comments
Currently, |
Would suggest that the SplitterDragendEvent for SplitLayout.addSplitterDragendListener would be provided with changed split position. Otherwise this is not possible to get split position at server when it has been changed by the client as accessing the style wont work if that has not been changed from the server. |
Now that |
Correct me if I am wrong, but this seems not possible as SplitterDragendEvent is fired as a CustomEvent with no extra details. |
Yes, but you can have the PS. I'm not sure at this time of the evening, whether it should be offset, client or scroll size that one will be interested in. |
Actually, you can even replace |
Since there is the setSplitterPosition(double) method with percentage, one would think that the event would give also changed value in same unit (double %) |
Very good point Samuli! That will be easy enough to calculate from the widths/heights of the two parts. And I think it should be |
@pleku Thank's I'll definitely check this out, as now I'm using workaround that establishes MutationObserver on client-side, that launches custom event when style changes (the flex attr), but only if there is no pointerEvents attr. This gives me one event, exactly on dragend of the splitter :). The one benefit of this is that I calculate the percentage also on client side, so it is a little bit cleaner in event handling section in Java code :). |
@pleku I'm not sure what you meant with "accessing the event". The addSplitterDragendListener does not return com.vaadin.flow.dom.DomListenerRegistration, but com.vaadin.flow.shared.Registration. Also the event object passed to the registered listener in addSplitterDragendListener is not DomEvent. The only way I see is to (or equivalent using @eventdata): getElemenet().addEventListener("splitter-dragend").addEventData("element"). Is that what you've had in mind? EDIT: Both options returned a Vaadin error:
EDIT2: Ok, so there is a bug for this? |
Actually @Duncol I did have that in mind, but I meant that the implementation of
|
@Duncol Would you share your workaround? We're also in need to get the actual SplitterPosition, but we're no JavaScript experts to write this ourselves. |
@voodoohoo Well, I am not an JS expert either, but sure. I cannot share with you the code, but I can point out what I've done to achieve this. When you drag the the splitter, the the 'flex' style property of both primary and secondary component change. When you receive the style change, you refer to the 'flex-basis' which is in pixels. In order to align with the Java-side API you need to calculate the proportion (percentage) according to the primaryComponent.parent.offsetWidth/offsetHeight. Crucial thing here is to dispatch such event only if the style has no 'pointer-events' attribute, as this is when the drag ends (i.e. it will fire only once, when user drops the splitter). Next, you launch a custom event with this value, for which you listen using getElement().addEventListener() on the Java side. EDIT: Actually given the fact that you can launch this event from the e.g. primary component context, and then you listen for it in the same component (just on Java side this time) I think you do not need more than one custom event. TL;DR
Hope that helps. If you'll have some sample code yourself, but still having trouble at some point I can help. |
@Duncol Thanks for your in detail description. We're going to check if this will working for us. |
Here is some example workaround code (pure Java based with server side set JS) - without any warranties of working everywhere and under each circumstance ;) The example uses custom split class (tbh I did not get it work with element dom event listeners), some custom dom event and a listener. Init code, e.g. in constructor, post construct or on attach. It currently sends only the primary component's width, but is easily extendible to have also the secondary component's one:
Custom class and custom dom event. Please be aware that the dom listener currently only handles "px" endings. Extend, if you need also initially other values or init your components with px based flex-basis values..
|
this still hasn't been resolved? What is the point of The more I try to work with vaadin flow, the more I find that half of stuff is half baked and missing... why? |
I'm support the comment of @Enerccio |
Hi, we've subclassed SplitterLayout to add the needed functionality.
this calls the
Some constants:
There is some specific code around like savePosition (position is saved per user) and the publishing of an EventSizeChanged via Guava EventBus. This works well for us and the subclass can easily be used around the projects. I'd also really appreciated that this essential things get done before adding lots of other functionalities. The API quality and completeness of Vaadin 6-8 has never been reached with Vaadin 10-14. It is well over a year since we opened this issue :-/ Erik |
@voodoohoo Thanks a lot for the code. This really helps. We are also facing a lot of issues like Spring integration that are very long open. |
@voodoohoo Thank you for your solution. We have slightly modified it to fit our needs. Hope it helps someone. public class SplitLayoutP extends SplitLayout {
private static final String PRIMARY_OFFSET_HEIGHT = "element._primaryChild.offsetHeight";
private static final String SECONDARY_OFFSET_HEIGHT = "element._secondaryChild.offsetHeight";
private static final String PRIMARY_OFFSET_WIDTH = "element._primaryChild.offsetWidth";
private static final String SECONDARY_OFFSET_WIDTH = "element._secondaryChild.offsetWidth";
private String PRIMARY_SIZE = PRIMARY_OFFSET_WIDTH;
private String SECONDARY_SIZE = SECONDARY_OFFSET_WIDTH;
private double splitterPosition;
private double primarySizePixel;
private double secondarySizePixel;
public SplitLayoutP() {
super();
init();
}
private void init() {
getElement().addEventListener("splitter-dragend", e -> {
this.primarySizePixel = e.getEventData().getNumber(PRIMARY_SIZE);
this.secondarySizePixel = e.getEventData().getNumber(SECONDARY_SIZE);
double totalSize = this.primarySizePixel + this.secondarySizePixel;
this.splitterPosition = Math.round((this.primarySizePixel / totalSize) * 100.0);
})
.addEventData(PRIMARY_SIZE)
.addEventData(SECONDARY_SIZE);
}
@Override
public void setOrientation(Orientation orientation) {
super.setOrientation(orientation);
if (orientation == Orientation.HORIZONTAL) {
PRIMARY_SIZE = PRIMARY_OFFSET_WIDTH;
SECONDARY_SIZE = SECONDARY_OFFSET_WIDTH;
} else {
PRIMARY_SIZE = PRIMARY_OFFSET_HEIGHT;
SECONDARY_SIZE = SECONDARY_OFFSET_HEIGHT;
}
}
@Override
public void setSplitterPosition(final double position) {
super.setSplitterPosition(position);
this.splitterPosition = position;
}
public double getSplitterPosition() {
return splitterPosition;
}
public double getPrimarySizePixel() {
return primarySizePixel;
}
public double getSecondarySizePixel() {
return secondarySizePixel;
}
} |
Dear @vaadin-bot , please remove the 'enhancement' label as it is a severe usability bug, which I am encountering in a migration project from Vaadin 7 (!) to Vaadin 20 (!). |
@voodoohoo and @cjpelaezrivas Thanks for your code, it helped a lot. A minor addition I had to make for |
For me this is also a missing feature during a Vaadin 7/8 migration (to 23). As others have pointed out, the |
Thanks for the cookbook entry. Nevertheless, I think that the splitter position should be available in |
I am trying to get the position of the splitter after moving the splitter manually.
I know how to set the position. And I know that I can get the position with e.g.
primaryComponent.getElement.getStyle.get(ElementConstants.STYLE_HEIGHT)
. But that's just the position I set on server-side.I need the new position after moving the splitter.
The text was updated successfully, but these errors were encountered: