> Markdown version of [Using Events with Components](https://vaadin.com/docs/v10/flow/creating-components/tutorial-component-events). Section index: [llms.txt](https://vaadin.com/docs/v10/flow/llms.txt)

# Using Events with Components

Your component class can provide an event handling API using the event bus provided by the `Component` base class. The event bus supports event classes extending `ComponentEvent`, and the listeners are of the type `ComponentEventListener<EventType>`.

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

Events used with the event bus should extend `ComponentEvent`. The base type is parameterized with the type of the component firing the event, so that `getSource()` can automatically return the right component type.

The second constructor parameter is used to let the user know whether the event has been triggered by a DOM event in the browser or through the component’s server-side API.

```java
public class ChangeEvent extends ComponentEvent<TextField> {
    public ChangeEvent(TextField source, boolean fromClient) {
        super(source, fromClient);
    }
}
```

Event listeners are of the generic type `ComponentEventListener<EventType>`, so you don’t need to create a separate interface for your event type.

You don’t need to implement a separate method for removing an event listener. Instead, the method for adding a listener returns a handle that can be used for removing the listener.

```java
@Tag("input")
public class TextField extends Component {
    public Registration addChangeListener(
            ComponentEventListener<ChangeEvent> listener) {
        return addListener(ChangeEvent.class, listener);
    }

    // Other component methods omitted
}
```

The user can then add and remove listeners like this.

```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 can fire an event on the server by creating the event instance and passing it to the `fireEvent` method. The event should be created with `false` as the second constructor parameter to indicate that the event does not come from the client.

```java
@Tag("input")
public class TextField extends Component {

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

    // Other component methods omitted
}
```

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

You can connect a component event to a DOM event that will be fired by the element in the browser. To do this, you only need to tell the framework the name of the DOM event to listen to by adding a `@DomEvent` annotation to your event class. The framework will automatically add a DOM listener to the element when a component event listener is added.

```java
@DomEvent("change")
public class ChangeEvent extends ComponentEvent<TextField> {
    public ChangeEvent(TextField source, boolean fromClient) {
        super(source, fromClient);
    }
}
```

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

An event can also include additional information about what has happened, e.g. which mouse button was used for a click event. If you use `@DomEvent`, any additional constructor parameters should have an `@EventData` annotation that tells the framework what data to send from the browser.

```java
@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;
    }
}
```

The `@EventData` definition is run as JavaScript in the browser with the DOM event available as `event` and the element to which the listener was added available as `element`. See the javadocs for `DomListenerRegistration.addEventData` for more information about how event data is collected and sent to the server.

> **Tip:** See <https://developer.mozilla.org/en-US/docs/Web/API/Event> for an overview of the standard DOM events and their properties.

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

It is sometimes not appropriate to send all DOM events to the server, but instead determine whether to send an event based on something related to the event. To achieve this, you can add define a `filter` in the `@DomEvent` annotation.

```java
@DomEvent(value = "keypress", filter = "event.key == 'Enter'")
public class EnterPressEvent extends ComponentEvent<TextField> {
    public EnterPressEvent(TextField source, boolean fromClient) {
        super(source, fromClient);
    }
}
```

The `filter` definition is run as JavaScript in the browser with the DOM event available as `event` and the element to which the listener was added available as `element`. See the docs for [`DomListenerRegistration.setFilter`](https://demo.vaadin.com/javadoc/com.vaadin/vaadin-core/10.0.0/com/vaadin/flow/dom/DomListenerRegistration.html#setFilter-java.lang.String-) for more information about how the filter is used.

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

Some kinds of events are fired very frequently while the user is doing something, like text input events while the user is typing. The rate of sending events to the server can be configured using different `debounce` settings in the `@DomEvent` annotation. Debouncing always requires a `timeout` in milliseconds and one or several phases of a burst for which an event should be sent to the server.

- Listening for the `LEADING` phase means that an event will be sent to the server at the beginning of a burst, but subsequent events will be dropped until one timeout period has passed without any new events. This may be useful for things like button clicks if you want to prevent accidental double submissions.

- With the `INTERMEDIATE` phase, there will be periodical events to the server while a burst is ongoing. Another event will not be sent to the server until the timeout period has passed since the last event was sent. This may be useful for tings like text input if you want to react continuously while the user is typing.

- The `TRAILING` phase is triggered at the end of a burst, when the timeout period has passed without any further events. This may be useful for things like text input if you want to react only when the user stops typing.

In this example, an `input` event will be sent to the server when the user has been typing, but there has been half a second since the last time some input was made.

```java
@DomEvent(value = "input",
          debounce = @DebounceSettings(
              timeout = 250,
              phases = DebouncePhase.TRAILING))
public class InputEvent extends ComponentEvent<TextField> {
    private 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 your event to be active for several phases at once, e.g. to both receive an event for the `LEADING` phase immediately when a burst starts but also `INTERMEDIATE` events while the burst goes on.

```java
@DomEvent(value = "input",
          debounce = @DebounceSettings(
              timeout = 500,
              phases = {DebouncePhase.LEADING,
                        DebouncePhase.INTERMEDIATE }))
public class ContiniousInputEvent extends ComponentEvent<TextField> {
    private String value;

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

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

See the docs for [`DomListenerRegistration.debounce`](https://demo.vaadin.com/javadoc/com.vaadin/vaadin-core/10.0.0/com/vaadin/flow/dom/DomListenerRegistration.html#setFilter-java.lang.String-) for more information about how the filter is used.

> **Note:** If both `filter` and `debounce` are configured at once, only events that pass the filter are considered when determining whether a burst has ended.
