* Move onClick logic to the Connector Move onClick event handling from 'VNativeButton' to NativeButtonConnector. Now works as for regular button. Also, adding propagation of the `enabled` value to the state on disableOnClick being true Fixes https://github.com/vaadin/framework/issues/11188tags/8.7.0.beta1
<ul> | <ul> | ||||
<li><tt>VaadinIcons.SEARCH_MINUS</tt> and <tt>VaadinIcons.SEARCH_PLUS</tt> codes were changed due to typo fix</li> | <li><tt>VaadinIcons.SEARCH_MINUS</tt> and <tt>VaadinIcons.SEARCH_PLUS</tt> codes were changed due to typo fix</li> | ||||
<li>Public <tt>disableOnClick</tt> variable in <tt>VNatiButton</tt> is removed due to the refactoring</li> | |||||
</ul> | </ul> | ||||
<h2>For incompatible or behavior-altering changes in 8.6, please see <a href="https://vaadin.com/download/release/8.6/8.6.0/release-notes.html#incompatible">8.6 release notes</a></h2> | <h2>For incompatible or behavior-altering changes in 8.6, please see <a href="https://vaadin.com/download/release/8.6/8.6.0/release-notes.html#incompatible">8.6 release notes</a></h2> |
import com.google.gwt.user.client.ui.Button; | import com.google.gwt.user.client.ui.Button; | ||||
import com.vaadin.client.ApplicationConnection; | import com.vaadin.client.ApplicationConnection; | ||||
import com.vaadin.client.BrowserInfo; | import com.vaadin.client.BrowserInfo; | ||||
import com.vaadin.client.MouseEventDetailsBuilder; | |||||
import com.vaadin.client.StyleConstants; | |||||
import com.vaadin.client.Util; | import com.vaadin.client.Util; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | import com.vaadin.client.WidgetUtil.ErrorUtil; | ||||
import com.vaadin.shared.MouseEventDetails; | |||||
import com.vaadin.shared.ui.button.ButtonServerRpc; | import com.vaadin.shared.ui.button.ButtonServerRpc; | ||||
public class VNativeButton extends Button | public class VNativeButton extends Button | ||||
* mouse while clicking it. In this case mouse leaves the button without | * mouse while clicking it. In this case mouse leaves the button without | ||||
* moving. | * moving. | ||||
*/ | */ | ||||
private boolean clickPending; | |||||
public boolean clickPending; | |||||
private boolean cancelNextClick = false; | private boolean cancelNextClick = false; | ||||
/** For internal use only. May be removed or replaced in the future. */ | |||||
public boolean disableOnClick = false; | |||||
public VNativeButton() { | public VNativeButton() { | ||||
setStyleName(CLASSNAME); | setStyleName(CLASSNAME); | ||||
// (#11854) | // (#11854) | ||||
setFocus(true); | setFocus(true); | ||||
} | } | ||||
if (disableOnClick) { | |||||
setEnabled(false); | |||||
// FIXME: This should be moved to NativeButtonConnector along with | |||||
// buttonRpcProxy | |||||
addStyleName(StyleConstants.DISABLED); | |||||
buttonRpcProxy.disableOnClick(); | |||||
} | |||||
// Add mouse details | |||||
MouseEventDetails details = MouseEventDetailsBuilder | |||||
.buildMouseEventDetails(event.getNativeEvent(), getElement()); | |||||
buttonRpcProxy.click(details); | |||||
clickPending = false; | |||||
} | } | ||||
@Override | @Override |
*/ | */ | ||||
package com.vaadin.client.ui.nativebutton; | package com.vaadin.client.ui.nativebutton; | ||||
import com.google.gwt.event.dom.client.ClickEvent; | |||||
import com.google.gwt.event.dom.client.ClickHandler; | |||||
import com.vaadin.client.MouseEventDetailsBuilder; | |||||
import com.vaadin.client.VCaption; | import com.vaadin.client.VCaption; | ||||
import com.vaadin.client.communication.StateChangeEvent; | import com.vaadin.client.communication.StateChangeEvent; | ||||
import com.vaadin.client.ui.AbstractComponentConnector; | import com.vaadin.client.ui.AbstractComponentConnector; | ||||
import com.vaadin.client.ui.ConnectorFocusAndBlurHandler; | import com.vaadin.client.ui.ConnectorFocusAndBlurHandler; | ||||
import com.vaadin.client.ui.Icon; | import com.vaadin.client.ui.Icon; | ||||
import com.vaadin.client.ui.VNativeButton; | import com.vaadin.client.ui.VNativeButton; | ||||
import com.vaadin.shared.MouseEventDetails; | |||||
import com.vaadin.shared.ui.Connect; | import com.vaadin.shared.ui.Connect; | ||||
import com.vaadin.shared.ui.button.ButtonServerRpc; | import com.vaadin.shared.ui.button.ButtonServerRpc; | ||||
import com.vaadin.shared.ui.button.NativeButtonState; | import com.vaadin.shared.ui.button.NativeButtonState; | ||||
import com.vaadin.ui.NativeButton; | import com.vaadin.ui.NativeButton; | ||||
@Connect(NativeButton.class) | @Connect(NativeButton.class) | ||||
public class NativeButtonConnector extends AbstractComponentConnector { | |||||
public class NativeButtonConnector extends AbstractComponentConnector | |||||
implements ClickHandler { | |||||
@Override | @Override | ||||
public void init() { | public void init() { | ||||
getWidget().client = getConnection(); | getWidget().client = getConnection(); | ||||
getWidget().paintableId = getConnectorId(); | getWidget().paintableId = getConnectorId(); | ||||
getWidget().addClickHandler(this); | |||||
ConnectorFocusAndBlurHandler.addHandlers(this); | ConnectorFocusAndBlurHandler.addHandlers(this); | ||||
} | } | ||||
public void onStateChanged(StateChangeEvent stateChangeEvent) { | public void onStateChanged(StateChangeEvent stateChangeEvent) { | ||||
super.onStateChanged(stateChangeEvent); | super.onStateChanged(stateChangeEvent); | ||||
getWidget().disableOnClick = getState().disableOnClick; | |||||
// Set text | // Set text | ||||
VCaption.setCaptionText(getWidget(), getState()); | VCaption.setCaptionText(getWidget(), getState()); | ||||
public NativeButtonState getState() { | public NativeButtonState getState() { | ||||
return (NativeButtonState) super.getState(); | return (NativeButtonState) super.getState(); | ||||
} | } | ||||
@Override | |||||
public void onClick(ClickEvent event) { | |||||
if (getState().disableOnClick) { | |||||
getState().enabled = false; | |||||
super.updateEnabledState(false); | |||||
getRpcProxy(ButtonServerRpc.class).disableOnClick(); | |||||
} | |||||
// Add mouse details | |||||
MouseEventDetails details = MouseEventDetailsBuilder | |||||
.buildMouseEventDetails(event.getNativeEvent(), | |||||
getWidget().getElement()); | |||||
getRpcProxy(ButtonServerRpc.class).click(details); | |||||
getWidget().clickPending = false; | |||||
} | |||||
} | } |
package com.vaadin.tests.components.nativebutton; | |||||
import com.vaadin.annotations.Widgetset; | |||||
import com.vaadin.server.VaadinRequest; | |||||
import com.vaadin.tests.components.AbstractTestUI; | |||||
import com.vaadin.ui.NativeButton; | |||||
import com.vaadin.ui.Button; | |||||
@Widgetset("com.vaadin.DefaultWidgetSet") | |||||
public class NativeButtonDisableOnClick extends AbstractTestUI { | |||||
public static String UPDATED_CAPTION = "Updated caption"; | |||||
@Override | |||||
protected void setup(VaadinRequest request) { | |||||
Button button = new NativeButton("Click Me"); | |||||
button.setId("buttonId"); | |||||
button.setDisableOnClick(true); | |||||
button.addClickListener(e -> { | |||||
if (UPDATED_CAPTION.equals(button.getCaption())) { | |||||
button.setCaption("Failed"); | |||||
} else { | |||||
button.setCaption(UPDATED_CAPTION); | |||||
} | |||||
}); | |||||
addComponent(button); | |||||
} | |||||
} |
package com.vaadin.tests.components.nativebutton; | |||||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||||
import org.junit.Test; | |||||
import org.openqa.selenium.By; | |||||
import org.openqa.selenium.WebElement; | |||||
import static org.junit.Assert.assertEquals; | |||||
public class NativeButtonDisableOnClickTest extends MultiBrowserTest { | |||||
@Test | |||||
public void testButtonIsDisabled() { | |||||
openTestURL(); | |||||
WebElement button = findElement(By.id("buttonId")); | |||||
assertEquals(true, button.isEnabled()); | |||||
button.click(); | |||||
assertEquals(NativeButtonDisableOnClick.UPDATED_CAPTION, | |||||
button.getText()); | |||||
assertEquals(false, button.isEnabled()); | |||||
button.click(); | |||||
assertEquals(NativeButtonDisableOnClick.UPDATED_CAPTION, | |||||
button.getText()); | |||||
} | |||||
} |