I'm using Vaadin Deisgner 14.6.1 to create some super simple tabs. However, when I try to do some simple operations in the java class (eg selecting a tab), it throws an error which indicates that the "Tabs" object does not have the proper children "tab" components. Here's a simple test case below. (I discovered the issue when I was trying to add a addSelectedChangeListener()
to the tabs class and discovered that it would never fire, presumably since the "tabs" class never properly had any children.) I tried a bunch of hacks, but nothing worked. (I have in the past gotten tabs to work if I stuck purely to a programmatic approach, but I really really really like using Designer, since it saves me tonnes of times and keeps the code quite modular and clean....when it works....)
import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';
import '@vaadin/vaadin-ordered-layout/src/vaadin-vertical-layout.js';
import '@vaadin/vaadin-tabs/src/vaadin-tabs.js';
import '@vaadin/vaadin-tabs/src/vaadin-tab.js';
class MyTabtest extends PolymerElement {
static get template() {
return html`
<style include="shared-styles">
:host {
display: block;
height: 100%;
}
</style>
<vaadin-vertical-layout theme="spacing" style="width: 100%; height: 100%;">
<vaadin-tabs theme="equal-width-tabs" id="tabs" orientation="horizontal" selected="0">
<vaadin-tab id="tab1" selected>
Tab one
</vaadin-tab>
<vaadin-tab id="tab2">
Tab two with a longer title
</vaadin-tab>
<vaadin-tab id="tab3">
Tab three
</vaadin-tab>
</vaadin-tabs>
<label id="lbl1">page1</label>
<label id="lbl2">page2</label>
<label id="lbl3">page3</label>
</vaadin-vertical-layout>
`;
}
static get is() {
return 'my-tabtest';
}
static get properties() {
return {
// Declare your properties here.
};
}
}
customElements.define(MyTabtest.is, MyTabtest);
and
package com.deepsearch.fe.tab2vizdb.fpsgraphicaldetails.spectratab.hslspectrachartandalts;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.polymertemplate.Id;
import com.vaadin.flow.component.tabs.Tab;
import com.vaadin.flow.component.tabs.Tabs;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.templatemodel.TemplateModel;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.polymertemplate.PolymerTemplate;
/**
* A Designer generated component for the my-tabtest template.
*
* Designer will add and remove fields with @Id mappings but
* does not overwrite or otherwise change this file.
*/
@Route("tabtest")
@Tag("my-tabtest")
@JsModule("./src/my-tabtest.js")
public class MyTabtest extends PolymerTemplate<MyTabtest.MyTabtestModel> {
@Id("tabs")
private Tabs tabs;
@Id("tab1")
private Tab tab1;
@Id("tab2")
private Tab tab2;
@Id("tab3")
private Tab tab3;
@Id("lbl1")
private Label lbl1;
@Id("lbl2")
private Label lbl2;
@Id("lbl3")
private Label lbl3;
/**
* Creates a new MyTabtest.
*/
public MyTabtest() {
// tabs.setSelectedTab(tab2); //throws error!
tabs.addSelectedChangeListener(e -> {
System.out.println("A tab got selected!"); //this never fires!!!!
});
}
/**
* This model binds properties between MyTabtest and my-tabtest
*/
public interface MyTabtestModel extends TemplateModel {
// Add setters and getters for template properties here.
}
}
Ultimately, I'm trying to capture a tab select event -- but it doens't seem to work when the tabs are created in Designer....is this true on Vaadin's side too? (ie is this reproducible?)
This is an unfortunate limitation of the component mapping to elements defined in a template. When mapping to Java, the parent-child relationships are not preserved and thus the
tabs
component does not realize that thetab
is one of its child components.See https://github.com/vaadin/flow/issues/7622
The way to make it work would be to create the
Tabs
andTab
instances in Java and the rest in Designer.