Handling User Events in a PolymerTemplate
To wire an event to a Polymer.Element
method you can write a template as:
HTML
Clicking on the <button>
will now show an alert in the browser. You can listen to any event using the on-*event*
syntax, it does not matter if it is a built-in browser event or a custom event from e.g. a web component.
Server-Side Event Handlers
To handle a DOM event in a template on the server side you can create a method with the event name and annotate it with @EventHandler
.
So to listen to the handleClick
event on the server you could have the template as:
HTML
<dom-module id="event-handler">
<template>
<button on-click="handleClick">Click me</button>
</template>
<script>
class EventHandler extends Polymer.Element {
static get is() { return 'event-handler' }
}
customElements.define(EventHandler.is, EventHandler);
</script>
</dom-module>
And define the server class as:
@Tag("event-handler")
@HtmlImport("/com/example/EventHandler.html")
public class EventHandlerPolymerTemplate extends PolymerTemplate<TemplateModel> {
@EventHandler
private void handleClick() {
System.out.println("Received a handle click event");
}
}
The framework will wire up the client-side event when having the @EventHandler
annotation on the method handleClick()
.
An event can also include additional information about what has happened, e.g. which mouse button was used for a click event. When you use @EventHandler
annotation, all constructor parameters should have an @EventData
annotation that tells the framework what data to send from the browser.
HTML
To get some extra data on event type and element tag name the server class definition could be built like:
Java
@Tag("event-handler")
@HtmlImport("/com/example/EventHandler.html")
public class EventDataHandlerPolymerTemplate extends PolymerTemplate<TemplateModel> {
@EventHandler
private void handleClick(@EventData("event.altKey") boolean altPressed,
@EventData("event.srcElement.tagName") String tag,
@EventData("event.offsetX") int offsetX,
@EventData("event.offsetY") int offsetY) {
System.out.println("Event alt pressed: " + altPressed);
System.out.println("Event tag: " + tag.toLowerCase(Locale.ENGLISH));
System.out.println("Click position on element: [" + offsetX + ", "+ offsetY +"]");
}
Now the client would send the extra information back to the server for , event.srcElement.tagName
and the event.offset[X/Y]
can then be used like normal variables.
There is a shorthand for getting model specific item as an object in your event handler. To be able to use it you should define your model (see ) in the template class.
@Tag("model-item-handler")
@HtmlImport("/com/example/ModelItemHandler.html")
public class ModelItemHandlerPolymerTemplate
extends PolymerTemplate<MessagesModel> {
public static class Message {
private String text;
public Message() {
}
public Message(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
public interface MessagesModel extends TemplateModel {
void setMessages(List<Message> messages);
}
@EventHandler
private void handleClick(@ModelItem Message message) {
System.out.println("Received a message: " + message.getText());
}
}
Now you can use the template repeater (dom-repeat) (see Using List of Items in a PolymerTemplate with template repeater) and handle click events on the server side with Message
as the parameter type.
HTML
The method handleClick
will be called in the server side with the data identified by event.model.item
once the item is clicked.
So if you have the following model definition and the event handler method:
Java
private String name;
return name;
}
public void setName(String name) {
this.name = name;
}
}
public interface Model extends TemplateModel {
void setUserInfo(UserInfo userInfo);
}
@EventHandler
private void onClick(
@ModelItem("event.detail.userInfo") UserInfo userInfo) {
System.err.println("contact : name = " + userInfo.getName());
}
Then the client side code below won’t update the name of the UserInfo
bean instance.
HTML
<dom-module id="contact-handler">
<template>
<input id="name" type="text">
<button on-click="onClick">Send the contact</button>
</template>
</dom-module>
<script>
class ContactHandler extends Polymer.Element {
static get is() { return 'contact-handler' }
onClick(event) {
this.userInfo.name = this.$.name.value;
event.detail = {
userInfo: this.userInfo,
};
}
customElements.define(ContactHandler.is, ContactHandler);
</script>
}