Docs

Documentation versions (currently viewingVaadin 25 (prerelease))

Component Enabled State

How enabling and disabling UI components affects user interaction and server communication in Vaadin applications.

Components that allow user interaction, such as TextField or Button, can have three different enabled states:

  • Enabled: An enabled component allows the user to interact with it. This is the default state.

  • Explicitly disabled: A component is explicitly disabled when setEnabled(false) is called directly on it. The user can’t interact with the component, and communication from the client to the server is blocked.

  • Implicitly disabled: A component is implicitly disabled when it’s a child of an explicitly disabled container. The component behaves exactly like an explicitly disabled component, except that it’s automatically enabled again as soon as it detaches from the disabled container.

Explicitly Enabling and Disabling Components

Any component that implements the HasEnabled interface can be explicitly enabled or disabled.

Example 1. Disabling a component using the component.setEnabled() method
Source code
Java
TextField name = new TextField("Name");
name.setEnabled(false);
// Users can no longer interact with the name field.
// The server doesn't handle status updates or events from the component,
// even if the component is changed manually in the browser
// (for example by a client-side script or via a developer console).
Important
There are restrictions when using the enabled state and Lit templates. See Template Limitations for details.

By default, disabling a component adds a disabled property to the client HTML element. You can change this behavior by overriding the Component:onEnabledStateChanged(boolean) method.

Example 2. Overriding the default disabled behavior
Source code
Java
@Override
public void onEnabledStateChanged(boolean enabled) {
    setDisabled(!enabled); 1
    refreshButtons(); 2
}
  1. Calls a custom method that marks the component as disabled in a different way.

  2. Calls a custom method that refreshes the buttons in the component.

Component Container Children

When you disable a container component, all child components are automatically implicitly disabled.

Example 3. Disabling all components in a container by using the same API
Source code
Java
FormLayout form = new FormLayout();

TextField name = new TextField("Name");
TextField email = new TextField("E-mail");
Button submit = new Button("Submit");

form.add(name, email, submit);
// all children are implicitly disabled
form.setEnabled(false);
System.out.println(name.isEnabled()); // prints false

If a child component doesn’t implement HasEnabled, it is still disabled from the server’s point of view. However, visually, it does not appear disabled. Fix this by overriding the Component.onEnabledStateChanged() method. In this case, it is important to call super.onEnabledStateChanged(enabled) as it contains common logic that applies to all components.

Example 4. Setting a child component as disabled by overriding the onEnabledStateChanged() method
Source code
Java
@Override
public void onEnabledStateChanged(boolean enabled) {
    super.onEnabledStateChanged(enabled);
    if (enabled) {
        childElement.removeAttribute("disabled");
    } else {
        childElement.setAttribute("disabled", true);
    }
}

Implicitly Enabled and Disabled Components

When an implicitly disabled component is detached from a disabled container, it’s automatically enabled again. Similarly, if an enabled component is attached to a disabled container, it’s automatically implicitly disabled.

Example 5. Implicitly enabled and disabled components
Source code
Java
FormLayout form = new FormLayout();
form.setEnabled(false); // the entire form is disabled

TextField name = new TextField("Name");
// prints true, since it isn't attached yet
System.out.println(name.isEnabled());

Button submit = new Button("Submit");
// the submit button is explicitly disabled
submit.setEnabled(false);
System.out.println(submit.isEnabled()); // prints false

form.add(name, submit); // attaches children

System.out.println(name.isEnabled()); // prints false
System.out.println(submit.isEnabled()); // prints false

form.remove(name); // the name field gets detached
System.out.println(name.isEnabled()); // prints true

form.remove(submit); // the submit button gets detached

// prints false, since it was explicitly disabled
System.out.println(submit.isEnabled());

Overriding Default Disabled Behavior

By default, disabled components are effectively unusable: no user interaction is allowed on the client side, and server-side communication is blocked. However, it’s sometimes necessary for complex components to remain partially functional, even in the disabled state.

Allowing Property Changes

By default, the server ignores property change events from disabled components. You can override this behavior in two ways:

  1. with a call to addPropertyChangeListener() on the disabled Element, or

  2. with the @Synchronize annotation.

Example 6. Using addPropertyChangeListener() to synchronize the prop property of a disabled component
Source code
Java
Element element = myDisabledComponent.getElement();
element.addPropertyChangeListener("prop", "prop-changed", e -> {
    // This code is executed when the 'prop-changed' event occurs, even if the
    // component is disabled.
});
Example 7. Using the @Synchronize annotation to synchronize the prop property of a disabled component
Source code
Java
// Inside the disabled component class:

@Synchronize(property = "prop", value = "prop-changed",
             allowUpdates = DisabledUpdateMode.ALWAYS)
public String getProp() {
    return getElement().getProperty("prop");
}

Allowing DOM Events

You can enable DOM events from disabled components in two ways:

  1. by specifying the disabledUpdateMode of the DomListenerRegistration returned by a call to addEventListener() on the disabled Element, or

  2. with the @DomEvent annotation.

Example 8. Unblocking a DOM event for a disabled element using the addEventListener() method
Source code
Java
public Notification() {
    getElement().addEventListener("opened-changed",
            event -> System.out.println("Opened"))
      .setDisabledUpdateMode(DisabledUpdateMode.ALWAYS);
}
Example 9. Unblocking a DOM event for a disabled component using the @DomEvent annotation
Source code
Java
@DomEvent(value = "click",
          allowUpdates = DisabledUpdateMode.ALWAYS)
public class CustomEvent
        extends ComponentEvent<Component> {
}

Allowing Remote Procedure Calls

If there are Java methods annotated with @ClientCallable or @EventHandler, you can unblock them for disabled components by specifying DisabledUpdateMode.ALWAYS as a value.

Example 10. Specifying DisabledUpdateMode.ALWAYS
Source code
Java
@EventHandler(DisabledUpdateMode.ALWAYS)
private void eventHandler() {
}

@ClientCallable(DisabledUpdateMode.ALWAYS)
private void clientRequest() {
}

02D183A6-D516-4232-B4BE-851D50B73DBA