Capturing Textfield Content in Polymer Event

Hi, I am using the TemplateRenderer to generate servside UI components - the Java class is shown below.

public class ForceCapabilityCard {
	
	public static TemplateRenderer<CapabilityForce> getTemplate() {
		return TemplateRenderer.of(
				  "<force-capability-card"
				+ "  force-capability-card='[[item.forceCapabilityCard]
]'"
				+ "  on-force-capability-click='forceCapabilityClick'"
				+ "  on-capability-score-changed='capabilityScoreChanged'>"
				+ "</force-capability-card>");
	}
	
	private CapabilityForceSummary forceSummary;
	
	public static ForceCapabilityCard create(CapabilityForceSummary force) {
		return new ForceCapabilityCard(force);
	}
 
    public ForceCapabilityCard(CapabilityForceSummary force) {
        this.forceSummary = force;
    }
    
    public String getName() {
    	return forceSummary.getForce().getName();
    }
    
    public String getDescription() {
    	return forceSummary.getForce().getDescription();
    }
         
    public List<ForcePlatformDto> getPlatforms(){
    	return forceSummary.getForce().getAllPlatforms();
    }
    
    public String getCapabilityScore() {
    	return forceSummary.getCapabilityScore().toString();
    }
    
        
}

How am I supposed to capture the content associated with UI events and send them to the server side? In the UI side, I have a textfield where I want to send an update of the ‘CapabilityScore’ to the client side for handling.

<vaadin-text-field label="Capability Score" id="capabilityScore" colspan="5" value = "{{forceCapabilityCard.capabilityScore}}" on-change ="_capabilityScoreChanged"></vaadin-text-field>

My textfield currently fires a Custom Event:

 _capabilityScoreChanged() {
		this.dispatchEvent(new CustomEvent('capability-score-changed'));
	  }

which is handled on the client side using the Event Handler that listens for events from within the template.

grid.addColumn(ForceCapabilityCard.getTemplate()
					.withProperty("forceCapabilityCard", ForceCapabilityCard::create)
					.withEventHandler("forceCapabilityClick", forceCapability -> forceRemoved(forceCapability))
					.withEventHandler("capabilityScoreChanged", forceCapability -> capabilityChanged(forceCapability)));

The question is, for the ‘capabilityScoreChanged’ event, I would like to either

  1. Produce a 2 way binding to the property ‘capabilityScore’ OR:
  2. Transport the value of the textfield within the ‘capabilityScoreChanged’ event so that it might be handled on the server side.

Any help would be appreciated.

This is unfortunately not directly possible with the TemplateRenderer API.

I have prototyped an alternative JsRenderer that uses the same low-level functionality. It’s quite low-level but it does give more flexibility. You can find the prototype here: https://gist.github.com/Legioth/6fde19fe22b3135a9214ecdb055296c7

Specifically for passing field values back, I did this usage example:

        grid.addColumn(JsRenderer.<Person> of("let element = document.createElement('vaadin-text-field'); "
                        + "root.textContent = ''; root.appendChild(element); element.value = item.name; "
                        + "element.addEventListener('change', () => handleValueChange(element.value));")
                .withProperty("name", Person::getName).withClientCallable("handleValueChange", (item, args) -> {
                    String value = args.getString(0);
                    Notification.show("Set value to " + value + " for " + item);
                })).setHeader("Name");