From: Henri Sara Date: Wed, 16 Mar 2011 08:49:34 +0000 (+0000) Subject: Merged ComboBox related changes from 6.5 X-Git-Tag: 6.7.0.beta1~393 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=77097c8ba01d67599da48da1272f0966f1ede613;p=vaadin-framework.git Merged ComboBox related changes from 6.5 svn changeset:17801/svn branch:6.6 --- diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java index 2cd999fe19..a451af90e7 100644 --- a/src/com/vaadin/terminal/gwt/client/Util.java +++ b/src/com/vaadin/terminal/gwt/client/Util.java @@ -1188,4 +1188,18 @@ public class Util { } + /** + * Gets the currently focused element for Internet Explorer. + * + * @return The currently focused element + */ + public native static Element getIEFocusedElement() + /*-{ + if ($wnd.document.activeElement) { + return $wnd.document.activeElement; + } + + return null; + }-*/ + ; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java index 5dd06b75a6..ce96e44eb6 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java @@ -48,6 +48,7 @@ import com.vaadin.terminal.gwt.client.Focusable; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; +import com.vaadin.terminal.gwt.client.VConsole; import com.vaadin.terminal.gwt.client.VTooltip; /** @@ -175,7 +176,7 @@ public class VFilterSelect extends Composite implements Paintable, Field, DOM.appendChild(root, down); DOM.appendChild(root, status); DOM.setElementProperty(status, "className", CLASSNAME + "-status"); - + DOM.sinkEvents(root, Event.ONMOUSEDOWN); addCloseHandler(this); } @@ -326,15 +327,20 @@ public class VFilterSelect extends Composite implements Paintable, Field, */ @Override public void onBrowserEvent(Event event) { - final Element target = DOM.eventGetTarget(event); - if (DOM.compare(target, up) - || DOM.compare(target, DOM.getChild(up, 0))) { - filterOptions(currentPage - 1, lastFilter); - } else if (DOM.compare(target, down) - || DOM.compare(target, DOM.getChild(down, 0))) { - filterOptions(currentPage + 1, lastFilter); + if (event.getTypeInt() == Event.ONCLICK) { + final Element target = DOM.eventGetTarget(event); + if (target == up || target == DOM.getChild(up, 0)) { + filterOptions(currentPage - 1, lastFilter); + } else if (target == down || target == DOM.getChild(down, 0)) { + filterOptions(currentPage + 1, lastFilter); + } } - tb.setFocus(true); + + /* + * Prevent the keyboard focus from leaving the textfield by + * preventing the default behaviour of the browser. Fixes #4285. + */ + handleMouseDownEvent(event); } /** @@ -442,7 +448,6 @@ public class VFilterSelect extends Composite implements Paintable, Field, left = getPopupLeft(); } setPopupPosition(left, top); - } /** @@ -727,6 +732,7 @@ public class VFilterSelect extends Composite implements Paintable, Field, * Used when measuring the width of the popup */ private final HTML popupOpener = new HTML("") { + /* * (non-Javadoc) * @@ -740,6 +746,12 @@ public class VFilterSelect extends Composite implements Paintable, Field, if (client != null) { client.handleTooltipEvent(event, VFilterSelect.this); } + + /* + * Prevent the keyboard focus from leaving the textfield by + * preventing the default behaviour of the browser. Fixes #4285. + */ + handleMouseDownEvent(event); } }; @@ -829,7 +841,7 @@ public class VFilterSelect extends Composite implements Paintable, Field, }); tb.sinkEvents(VTooltip.TOOLTIP_EVENTS); - popupOpener.sinkEvents(VTooltip.TOOLTIP_EVENTS); + popupOpener.sinkEvents(VTooltip.TOOLTIP_EVENTS | Event.ONMOUSEDOWN); panel.add(tb); panel.add(popupOpener); initWidget(panel); @@ -1071,6 +1083,12 @@ public class VFilterSelect extends Composite implements Paintable, Field, updateRootWidth(); } + // Focus dependent style names are lost during the update, so we add + // them here back again + if (focused) { + addStyleDependentName("focus"); + } + initDone = true; } @@ -1370,9 +1388,8 @@ public class VFilterSelect extends Composite implements Paintable, Field, prompting = true; } DOM.eventPreventDefault(DOM.eventGetCurrentEvent()); - tb.setFocus(true); + focus(); tb.selectAll(); - } } @@ -1401,6 +1418,11 @@ public class VFilterSelect extends Composite implements Paintable, Field, return w; }-*/; + /** + * A flag which prevents a focus event from taking place + */ + boolean iePreventNextFocus = false; + /* * (non-Javadoc) * @@ -1409,6 +1431,17 @@ public class VFilterSelect extends Composite implements Paintable, Field, * .dom.client.FocusEvent) */ public void onFocus(FocusEvent event) { + + /* + * When we disable a blur event in ie we need to refocus the textfield. + * This will cause a focus event we do not want to process, so in that + * case we just ignore it. + */ + if (BrowserInfo.get().isIE() && iePreventNextFocus) { + iePreventNextFocus = false; + return; + } + focused = true; if (prompting && !readonly) { setPromptingOff(""); @@ -1420,6 +1453,12 @@ public class VFilterSelect extends Composite implements Paintable, Field, } } + /** + * A flag which cancels the blur event and sets the focus back to the + * textfield if the Browser is IE + */ + boolean preventNextBlurEventInIE = false; + /* * (non-Javadoc) * @@ -1427,7 +1466,34 @@ public class VFilterSelect extends Composite implements Paintable, Field, * com.google.gwt.event.dom.client.BlurHandler#onBlur(com.google.gwt.event * .dom.client.BlurEvent) */ + public void onBlur(BlurEvent event) { + + if (BrowserInfo.get().isIE() && preventNextBlurEventInIE) { + /* + * Clicking in the suggestion popup or on the popup button in IE + * causes a blur event to be sent for the field. In other browsers + * this is prevented by canceling/preventing default behavior for + * the focus event, in IE we handle it here by refocusing the text + * field and ignoring the resulting focus event for the textfield + * (in onFocus). + */ + preventNextBlurEventInIE = false; + + Element focusedElement = Util.getIEFocusedElement(); + if (getElement().isOrHasChild(focusedElement) + || suggestionPopup.getElement() + .isOrHasChild(focusedElement)) { + + // IF the suggestion popup or another part of the VFilterSelect + // was focused, move the focus back to the textfield and prevent + // the triggered focus event (in onFocus). + iePreventNextFocus = true; + tb.setFocus(true); + return; + } + } + focused = false; if (!readonly) { // much of the TAB handling takes place here @@ -1633,4 +1699,31 @@ public class VFilterSelect extends Composite implements Paintable, Field, } return componentPadding; } + + /** + * Handles special behavior of the mouse down event + * + * @param event + */ + private void handleMouseDownEvent(Event event) { + /* + * Prevent the keyboard focus from leaving the textfield by preventing + * the default behaviour of the browser. Fixes #4285. + */ + if (event.getTypeInt() == Event.ONMOUSEDOWN) { + event.preventDefault(); + event.stopPropagation(); + + /* + * In IE the above wont work, the blur event will still trigger. So, + * we set a flag here to prevent the next blur event from happening. + * This is not needed if do not already have focus, in that case + * there will not be any blur event and we should not cancel the + * next blur. + */ + if (BrowserInfo.get().isIE() && focused) { + preventNextBlurEventInIE = true; + } + } + } } diff --git a/tests/src/com/vaadin/tests/components/combobox/ComboFocusBlurEvents.html b/tests/src/com/vaadin/tests/components/combobox/ComboFocusBlurEvents.html new file mode 100644 index 0000000000..4d91ce7838 --- /dev/null +++ b/tests/src/com/vaadin/tests/components/combobox/ComboFocusBlurEvents.html @@ -0,0 +1,133 @@ + + + + + + +ComboFocusBlurEvents + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ComboFocusBlurEvents
open/run/com.vaadin.tests.components.combobox.ComboFocusBlurEvents?restartApplication
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[1]9,14
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::Root/VFilterSelect$SuggestionPopup[0]/VFilterSelect$SuggestionMenu[0]#item4142,2
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[1]17,12
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::Root/VFilterSelect$SuggestionPopup[0]/VFilterSelect$SuggestionMenu[0]#item7143,6
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[1]13,9
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::Root/VFilterSelect$SuggestionPopup[0]/VFilterSelect$SuggestionMenu[0]#item3147,11
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[1]16,11
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::Root/VFilterSelect$SuggestionPopup[0]/VFilterSelect$SuggestionMenu[0]#item5146,4
assertTextvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VLabel[0]exact:0: Focus event!
screenCaptureOneFocusEvent
pressSpecialKeyvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[0]down
pressSpecialKeyvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[0]down
pressSpecialKeyvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[0]down
pressSpecialKeyvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[0]down
pressSpecialKeyvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[0]down
pressSpecialKeyvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[0]enter
assertTextvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VLabel[0]exact:0: Focus event!
screenCaptureStillOneFocusEvent
focusvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VTextField[0]
assertTextvaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VLabel[0]0: Focus event!
1: Blur event!
screenCaptureOneFocusOneBlur
+ + diff --git a/tests/src/com/vaadin/tests/components/combobox/ComboFocusBlurEvents.java b/tests/src/com/vaadin/tests/components/combobox/ComboFocusBlurEvents.java new file mode 100644 index 0000000000..6681342ea6 --- /dev/null +++ b/tests/src/com/vaadin/tests/components/combobox/ComboFocusBlurEvents.java @@ -0,0 +1,74 @@ +package com.vaadin.tests.components.combobox; + +import java.util.ArrayList; +import java.util.List; + +import com.vaadin.data.util.ObjectProperty; +import com.vaadin.event.FieldEvents; +import com.vaadin.event.FieldEvents.BlurEvent; +import com.vaadin.event.FieldEvents.FocusEvent; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Label; +import com.vaadin.ui.TextField; + +public class ComboFocusBlurEvents extends TestBase { + + private int counter = 0; + + @Override + protected void setup() { + + List list = new ArrayList(); + for (int i = 0; i < 100; i++) { + list.add("Item " + i); + } + + ComboBox cb = new ComboBox("Combobox", list); + cb.setImmediate(true); + cb.setInputPrompt("Enter text"); + cb.setDescription("Some Combobox"); + addComponent(cb); + + final ObjectProperty log = new ObjectProperty(""); + + cb.addListener(new FieldEvents.FocusListener() { + public void focus(FocusEvent event) { + log.setValue(log.getValue().toString() + "
" + counter + + ": Focus event!"); + counter++; + } + }); + + cb.addListener(new FieldEvents.BlurListener() { + public void blur(BlurEvent event) { + log.setValue(log.getValue().toString() + "
" + counter + + ": Blur event!"); + counter++; + } + }); + + TextField field = new TextField("Some textfield"); + field.setImmediate(true); + addComponent(field); + + Label output = new Label(log); + output.setCaption("Events:"); + + output.setContentMode(Label.CONTENT_XHTML); + addComponent(output); + + } + + @Override + protected String getDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Integer getTicketNumber() { + return 6536; + } + +} diff --git a/tests/src/com/vaadin/tests/components/combobox/Comboboxes.html b/tests/src/com/vaadin/tests/components/combobox/Comboboxes.html index d639bbf3e4..1affc9a8a9 100644 --- a/tests/src/com/vaadin/tests/components/combobox/Comboboxes.html +++ b/tests/src/com/vaadin/tests/components/combobox/Comboboxes.html @@ -4,12 +4,12 @@ -New Test +Comboboxes - + @@ -273,6 +273,7 @@ +
New Test
Comboboxes
setSpeed