> Markdown version of [Events](https://vaadin.com/docs/next/flow/component-internals/events). Section index: [llms.txt](https://vaadin.com/docs/next/flow/llms.txt)

# Declaring and Firing Component Events

The `Component` base class provides an event bus for firing and listening to events. It supports event classes that extend `ComponentEvent`, and listeners that implement `ComponentEventListener`.

## <a id="defining-an-event"></a>Defining an Event

To use the event bus, your event should extend `ComponentEvent`. This class is parameterized with the type of the component firing the event, so that the `ComponentEvent.getSource()` method automatically returns the correct type.

Events can be fired either from the client side (in response to a DOM event) or from the server side (in response to server-side API calls). You indicate the origin of the event with the `fromClient` parameter in the event constructor.

Example 1. Creating an event by extending `ComponentEvent` to be published by a `TextField`

`ChangeEvent.java`

```java
package com.vaadin.demo.reference.componentinternals.events;

import com.vaadin.flow.component.ComponentEvent;

public class ChangeEvent extends ComponentEvent<TextField> {

    public ChangeEvent(TextField source, boolean fromClient) {
        super(source, fromClient);
    }
}
```

## <a id="defining-an-event-listener"></a>Defining an Event Listener

For each event type, you define a method in your component class to add event listeners. This method takes a parameterized `ComponentEventListener` as an argument, and returns a `Registration` handle for removing the listener.

Example 2. Declaring an `addChangeListener()` method for adding listeners to the `ChangeEvent` defined earlier

`TextField.java`

```java
public Registration addChangeListener(
        ComponentEventListener<ChangeEvent> listener) {
    return addListener(ChangeEvent.class, listener);
}
```

Example 3. Adding and removing event listeners

```java
TextField textField = new TextField();
Registration registration = textField
        .addChangeListener(e -> System.out.println("Event fired"));

// In some other part of the code
registration.remove();
```

## <a id="firing-events-from-the-server"></a>Firing Events from the Server

You fire an event from the server by creating the event instance and passing it to the `Component.fireEvent()` method. Use `false` as the `fromClient` constructor parameter to specify that the event doesn’t come from the client.

Example 4. Using the `fireEvent()` method to fire an event from the server

`TextField.java`

```java
public void setValue(String value) {
    getElement().setAttribute("value", value);
    fireEvent(new ChangeEvent(this, false));
}
```

## <a id="firing-events-from-the-client"></a>Firing Events from the Client

You can connect a component event to a client-side DOM event by using the `@DomEvent` annotation on your event class. Vaadin will automatically fire the server-side event when the specified DOM event occurs in the browser.

Example 5. Using the `@DomEvent` annotation to fire a server-side `ChangeEvent` when the client-side `change` DOM event occurs

`ChangeEvent.java`

```java
package com.vaadin.demo.reference.componentinternals.events.dom;

import com.vaadin.flow.component.ComponentEvent;
import com.vaadin.flow.component.DomEvent;

@DomEvent("change")
public class ChangeEvent extends ComponentEvent<TextField> {

    public ChangeEvent(TextField source, boolean fromClient) {
        super(source, fromClient);
    }
}
```

> **Important: Hidden and Disabled Components**
>
> If a component is hidden or disabled, client-side events are automatically blocked. See the [Component Enabled State](https://vaadin.com/docs/next/flow/component-internals/enabled-state.md) and [Component Visibility](https://vaadin.com/docs/next/flow/component-internals/visibility.md) reference guides for more information.

### <a id="adding-event-data"></a>Adding Event Data

An event can include additional information, such as the mouse button used in a click event. Use the `@EventData` annotation to specify which DOM event property to include in the server-side event.

This annotation takes a single parameter: a JavaScript expression that is evaluated in the browser to extract the desired value. In the expression, the DOM event is available as `event`. The element firing the DOM event is available as `element`.

Place the `@EventData` annotation on the constructor parameter that should receive the value. For multiple values, add multiple parameters with the annotation.

Example 6. Using the `@EventData` annotation to include the client-side `event.button` property in a server-side `ClickEvent`

`ClickEvent.java`

```java
package com.vaadin.demo.reference.componentinternals.events.dom;

import com.vaadin.flow.component.ComponentEvent;
import com.vaadin.flow.component.DomEvent;
import com.vaadin.flow.component.EventData;
import com.vaadin.flow.component.html.NativeButton;

@DomEvent("click")
public class ClickEvent extends ComponentEvent<NativeButton> {

    private final int button;

    public ClickEvent(NativeButton source, boolean fromClient,
            @EventData("event.button") int button) {
        super(source, fromClient);
        this.button = button;
    }

    public int getButton() {
        return button;
    }
}
```

See [`DomListenerRegistration.addEventData`](https://vaadin.com/api/platform/com/vaadin/flow/dom/DomListenerRegistration.html) in the Javadoc for more about how event data is collected and sent to the server.

> **Tip: Overview of standard DOM events and properties**
>
> See [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event) in the MDN web docs for an overview of standard DOM events and properties.

### <a id="filtering-events"></a>Filtering Events

Instead of sending all DOM events to the server, you can filter events by defining a `filter` in the `@DomEvent` annotation.

The filter is a JavaScript expression that is evaluated in the browser. If it returns `true`, the event is sent to the server; if it returns `false`, the event is ignored. In the expression, the DOM event is available as `event`. The element firing the DOM event is available as `element`.

Example 7. Firing a server-side `EnterPressEvent` only when the `Enter` key is pressed on the client side

`EnterPressEvent.java`

```java
package com.vaadin.demo.reference.componentinternals.events.dom;

import com.vaadin.flow.component.ComponentEvent;
import com.vaadin.flow.component.DomEvent;

@DomEvent(value = "keypress", filter = "event.key == 'Enter'")
public class EnterPressEvent extends ComponentEvent<TextField> {

    public EnterPressEvent(TextField source, boolean fromClient) {
        super(source, fromClient);
    }
}
```

See [`DomListenerRegistration.setFilter`](https://vaadin.com/api/platform/com/vaadin/flow/dom/DomListenerRegistration.html) in the Javadoc for more about how the filter is used.

### <a id="limiting-event-frequency"></a>Limiting Event Frequency

Certain events can fire very frequently when users interact with a component. For example, multiple text input events are triggered as the user types. These rapid sequences of events are called *bursts*. *Debouncing* controls which events in that burst get sent to the server.

You can configure debounce settings in the `@DomEvent` annotation. Debouncing always requires two parameters: a `timeout` (in milliseconds) and a burst `phase`.

There are three available burst phases:

- `LEADING` - Sends only the first event at the start of a burst, then ignores the rest while waiting for the burst to end. The burst has ended when a timeout period has passed with no new events. This is useful for scenarios such as button clicks, where you want to prevent accidental double submissions.

- `INTERMEDIATE` - Sends events periodically during the burst by splitting it into intervals defined by the timeout period. The last event in each interval gets sent to the server. This phase is well-suited for text input fields when you want to react continuously as the user types.

- `TRAILING` - Waits for the burst to end and then sends only the last event, ignoring all the others. The burst has ended when a timeout period has passed with no new events. This is often used for text input fields when you only want to react after the user has finished typing.

Example 8. Configuring an `input` event to be sent to the server half a second after the user’s last input

`InputEvent.java`

```java
package com.vaadin.demo.reference.componentinternals.events.dom;

import com.vaadin.flow.component.ComponentEvent;
import com.vaadin.flow.component.DebounceSettings;
import com.vaadin.flow.component.DomEvent;
import com.vaadin.flow.component.EventData;
import com.vaadin.flow.dom.DebouncePhase;

@DomEvent(
    value = "input",
    debounce = @DebounceSettings(
        timeout = 500,
        phases = DebouncePhase.TRAILING
    )
)
public class InputEvent extends ComponentEvent<TextField> {

    private final String value;

    public InputEvent(TextField source, boolean fromClient,
            @EventData("element.value") String value) {
        super(source, fromClient);
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}
```

You can configure more than one phase for an event. However, combining the `INTERMEDIATE` and `TRAILING` phases results in the final event being sent twice: once as the last intermediate event and once as the trailing event.

Example 9. Configuring an event for both the `LEADING` phase (immediately when the burst starts) and the `INTERMEDIATE` phase (while the burst is ongoing)

`ContinuousInputEvent.java`

```java
package com.vaadin.demo.reference.componentinternals.events.dom;

import com.vaadin.flow.component.ComponentEvent;
import com.vaadin.flow.component.DebounceSettings;
import com.vaadin.flow.component.DomEvent;
import com.vaadin.flow.component.EventData;
import com.vaadin.flow.dom.DebouncePhase;

@DomEvent(
    value = "input",
    debounce = @DebounceSettings(
        timeout = 500,
        phases = {
            DebouncePhase.LEADING,
            DebouncePhase.INTERMEDIATE
        }
    )
)
public class ContinuousInputEvent extends ComponentEvent<TextField> {

    private final String value;

    public ContinuousInputEvent(TextField source, boolean fromClient,
            @EventData("element.value") String value) {
        super(source, fromClient);
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}
```

See [`DomListenerRegistration.debounce`](https://vaadin.com/api/platform/com/vaadin/flow/dom/DomListenerRegistration.html) in the Javadoc for more about debouncing events.

> **Note:** If you configure both a `filter` and `debounce` settings, only events that pass the filter are included in a burst.

`34A83237-00CD-4EEE-A791-29AA776AD293`
