Integration of third-party Vaadin components is described in Section 4.5.10.1, “Using Third-Party Vaadin Components”.
Below is the example of using the Stepper component, available at http://vaadin.com/addon/stepper. This component allows changing text field value in steps using the keyboard, mouse scroll or built-in up/down buttons.
-
Assuming that the project has a
Customerentity with a String-typenameattribute. An editor screen (customer-edit.xml) was created in the web module with the following layout:<layout expand="windowActions" spacing="true"> <fieldGroup id="fieldGroup" datasource="customerDs"> <column width="250px"> <field id="name"/> </column> </fieldGroup> <iframe id="windowActions" screen="editWindowActions"/> </layout>Our task is to add an
Integer-typescoreattribute for step editing to the screen. -
Add the
scoreattribute to theCustomerentity in CUBA Studio:@Column(name = "SCORE") protected Integer score; public void setScore(Integer score) { this.score = score; } public Integer getScore() { return score; }Generate DB scripts and run the database update.
-
Run the command from the Project properties section of the Studio navigation panel.
-
Add a dependency on the component add-on to the web module in the project’s build.gradle:
configure(webModule) { ... dependencies { ... compile("org.vaadin.addons:stepper:2.1.2") } -
Re-create the IDE project files ( menu item).
-
Include the add-on widget set in the
AppWidgetSet.gwt.xmlof the project’s web-toolkit module after the platform widget set:<module> <inherits name="com.haulmont.cuba.web.toolkit.ui.WidgetSet" /> <inherits name="org.vaadin.risto.stepper.widgetset.StepperWidgetset" /> <set-property name="user.agent" value="safari" />Building of widgets can be accelerated by setting the
user.agentproperty. In this example, the widget set will be built only for WebKit-based browsers: Chrome, Safari, etc. -
Add a custom
scorefield to the fieldGroup component in thecustomer-edit.xmldescriptor:<fieldGroup id="fieldGroup" datasource="customerDs"> <column width="250px"> <field id="name"/> <field id="score" custom="true" caption="Score"/> </column> </fieldGroup> -
Add the following code to the
CustomerEditscreen controller:public class CustomerEdit extends AbstractEditor<Customer> { @Inject private ComponentsFactory componentsFactory; @Inject private FieldGroup fieldGroup; private IntStepper stepper = new IntStepper(); @Override public void init(Map<String, Object> params) { fieldGroup.addCustomField("score", new FieldGroup.CustomFieldGenerator() { @Override public Component generateField(final Datasource datasource, final String propertyId) { Component box = componentsFactory.createComponent(BoxLayout.VBOX); com.vaadin.ui.Layout layout = WebComponentsHelper.unwrap(box); layout.addComponent(stepper); stepper.setSizeFull(); stepper.addValueChangeListener(new Property.ValueChangeListener() { @Override public void valueChange(Property.ValueChangeEvent event) { datasource.getItem().setValue(propertyId, event.getProperty().getValue()); } }); return box; } }); } @Override protected void postInit() { stepper.setValue(getItem().getScore()); } }An instance of the component from the add-on is created in the
stepperfield. Theinit()method initializes the customscorefield. TheComponentsFactorycreates an instance of BoxLayout, retrieves a link to the Vaadin container via WebComponentsHelper, and adds the new component to it. TheBoxLayoutis then returned to be used in the custom field.Component data binding is implemented by setting its current value from the edited
Customerin thepostInit()method. Additionally, the corresponding entity attribute is updated through the implemented value change listener, when the user changes the value. -
The new component can be used in any part of the screen outside of the
FieldGroup. In order to do this, declare a container in the XML-descriptor:<hbox id="scoreBox" spacing="true"> <label value="Score"/> </hbox>Inject the container in the screen controller, retrieve a link to the Vaadin container and add the component to it:
public class CustomerEdit extends AbstractEditor<Customer> { @Inject private BoxLayout scoreBox; private IntStepper stepper = new IntStepper(); @Override public void init(Map<String, Object> params) { com.vaadin.ui.Layout box = WebComponentsHelper.unwrap(scoreBox); box.addComponent(stepper); stepper.addValueChangeListener(new Property.ValueChangeListener() { @Override public void valueChange(Property.ValueChangeEvent event) { getItem().setValue("score", event.getProperty().getValue()); } }); } @Override protected void postInit() { stepper.setValue(getItem().getScore()); } }Data binding is implemented in the same way as described above.
-
To adapt the component style, create a theme extension in the project. Run the command in the Project properties section of the Studio navigation panel. After that, open the
themes/havana/havana-ext.scssfile in the web module and add the following code:@import "../havana/havana"; @mixin havana-ext { @include havana; /* Basic styles for stepper */ .v-stepper { /* Use box-sizing: border-box; for all browsers */ @include box-defaults; height: 25px; border: 0; /* Use theme fonts */ font-family: $theme_fonts; } /* Basic styles for inner text box */ .v-stepper input[type="text"] { /* Use box-sizing: border-box; for all browsers */ @include box-defaults; height: 25px; padding: 1px; outline: 0; margin: 0; /* Use border color from theme */ border: 1px solid $theme_fieldBorderColor; } /* Focused styles */ .v-stepper.v-stepper input[type="text"]:focus { /* Use focused border color from theme */ border-color: $theme_fieldFocusedBorderColor; /* hide default focus outline */ outline: 0; } /* Readonly styles */ .v-readonly.v-stepper input[type="text"], .v-readonly.v-stepper input[type="text"]:focus { /* Use readonly border color from theme */ border-color: $theme_fieldReadonlyBorderColor; } }

