Browse Source

Fix ComboBox popup location on scrolled pages in IE/Firefox

Fixes #8778
tags/8.1.0.alpha1
Henri Sara 7 years ago
parent
commit
dc657b3208

+ 13
- 5
client/src/main/java/com/vaadin/client/ui/VComboBox.java View File

@@ -243,12 +243,12 @@ public class VComboBox extends Composite implements Field, KeyDownHandler,
return $entry(function(e) {
var deltaX = e.deltaX ? e.deltaX : -0.5*e.wheelDeltaX;
var deltaY = e.deltaY ? e.deltaY : -0.5*e.wheelDeltaY;
// IE8 has only delta y
if (isNaN(deltaY)) {
deltaY = -0.5*e.wheelDelta;
}
@com.vaadin.client.ui.VComboBox.JsniUtil::moveScrollFromEvent(*)(widget, deltaX, deltaY, e, e.deltaMode);
});
}-*/;
@@ -410,10 +410,13 @@ public class VComboBox extends Composite implements Field, KeyDownHandler,
// Add TT anchor point
getElement().setId("VAADIN_COMBOBOX_OPTIONLIST");

final int x = VComboBox.this.getAbsoluteLeft();
final int x = toInt32(WidgetUtil
.getBoundingClientRect(VComboBox.this.getElement())
.getLeft());

topPosition = tb.getAbsoluteTop();
topPosition += tb.getOffsetHeight();
topPosition = toInt32(WidgetUtil
.getBoundingClientRect(tb.getElement()).getBottom())
+ Window.getScrollTop();

setPopupPosition(x, topPosition);

@@ -449,6 +452,11 @@ public class VComboBox extends Composite implements Field, KeyDownHandler,
setPopupPositionAndShow(popup);
}

private native int toInt32(double val)
/*-{
return val | 0;
}-*/;

/**
* Should the next page button be visible to the user?
*

+ 25
- 0
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxEmbeddedInDiv.java View File

@@ -0,0 +1,25 @@
package com.vaadin.tests.components.combobox;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Label;
import com.vaadin.ui.VerticalLayout;

public class ComboBoxEmbeddedInDiv extends AbstractTestUI {

@Override
protected void setup(VaadinRequest request) {
VerticalLayout vl = new VerticalLayout();
for (int i = 0; i < 20; i++) {
vl.addComponent(new Label("" + i));
}
ComboBox<String> cb = new ComboBox<>();
vl.addComponent(cb);
for (int i = 0; i < 20; i++) {
vl.addComponent(new Label("" + i));
}
addComponent(vl);
}

}

+ 79
- 0
uitest/src/main/webapp/statictestfiles/ComboBoxEmbeddingHtmlPage.html View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible"
content="IE=9;chrome=1" />
<title>Embedding a Vaadin Application in HTML Page</title>
<!-- Set up the favicon from the Vaadin theme -->
<link rel="shortcut icon" type="image/vnd.microsoft.icon"
href="/VAADIN/themes/valo/favicon.ico" />
<link rel="icon" type="image/vnd.microsoft.icon"
href="/VAADIN/themes/valo/favicon.ico" />
</head>
<body>
<!-- Loads the Vaadin widget set, etc. -->
<script type="text/javascript"
src="/VAADIN/vaadinBootstrap.js"></script>
<h1>Embedding a Vaadin UI</h1>
<p>This is a static web page that contains an embedded Vaadin
application. It's here:</p>
<div style="width: 200px; overflow: auto; border: 2px solid green;">
<!-- So here comes the div element in which the Vaadin -->
<!-- application is embedded. -->
<div style="width: 300px;" id="embeddedcombobox" class="v-app">
<!-- Optional placeholder for the loading indicator -->
<div class=" v-app-loading"></div>
<!-- Alternative fallback text -->
<noscript>You have to enable javascript in your browser to
use an application built with Vaadin.</noscript>
</div>
</div>
<script type="text/javascript">//<![CDATA[
if (!window.vaadin)
alert("Failed to load the bootstrap JavaScript: "+
"/VAADIN/vaadinBootstrap.js");
/* The UI Configuration */
vaadin.initApplication("embeddedcombobox", {
"browserDetailsUrl": "/run/com.vaadin.tests.components.combobox.ComboBoxEmbeddedInDiv",
"serviceUrl": "/run/",
"widgetset": "com.vaadin.DefaultWidgetSet",
"theme": "valo",
"versionInfo": {"vaadinVersion": "8.0.1"},
"vaadinDir": "/VAADIN/",
"heartbeatInterval": 300,
"debug": true,
"standalone": false,
"authErrMsg": {
"message": "Take note of any unsaved data, "+
"and <u>click here<\/u> to continue.",
"caption": "Authentication problem"
},
"comErrMsg": {
"message": "Take note of any unsaved data, "+
"and <u>click here<\/u> to continue.",
"caption": "Communication problem"
},
"sessExpMsg": {
"message": "Take note of any unsaved data, "+
"and <u>click here<\/u> to continue.",
"caption": "Session Expired"
}
});//]] >
</script>
<p>Please view the page source to see how embedding works.</p>
</body>
</html>

+ 52
- 0
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxPopupPositionEmbeddedInDivTest.java View File

@@ -0,0 +1,52 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.combobox;

import org.apache.commons.lang3.StringUtils;
import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebElement;

import com.vaadin.testbench.elements.ComboBoxElement;
import com.vaadin.tests.tb3.MultiBrowserTest;

public class ComboBoxPopupPositionEmbeddedInDivTest extends MultiBrowserTest {

@Test
public void popupBelow() {
driver.get(StringUtils.strip(getBaseURL(), "/")
+ "/statictestfiles/ComboBoxEmbeddingHtmlPage.html");

// Chrome requires document.scrollTop (<body>)
// Firefox + IE wants document.documentElement.scrollTop (<html>)
executeScript(
"document.body.scrollTop=200;document.documentElement.scrollTop=200;document.body.scrollLeft=50;document.documentElement.scrollLeft=50;");

ComboBoxElement combobox = $(ComboBoxElement.class).first();
combobox.openPopup();
WebElement popup = $(ComboBoxElement.class).first()
.getSuggestionPopup();

Point comboboxLocation = combobox.getLocation();
Point popupLocation = popup.getLocation();
Assert.assertTrue("Popup should be below combobox",
popupLocation.getY() > comboboxLocation.getY());

Assert.assertTrue("Popup should be left aligned with the combobox",
popupLocation.getX() == comboboxLocation.getX());
}
}

Loading…
Cancel
Save