3.5.17.3.1. Using a Third-party Vaadin Component

This is an example of using the Stepper component available at http://vaadin.com/addon/stepper, in an application project. The component enables changing text field value in steps using the keyboard, mouse scroll or built-in up/down buttons.

Create a new project in CUBA Studio and name it addon-demo.

A Vaadin add-on may be integrated if the application project has a web-toolkit module. A convenient way to create it is to use CUBA Studio: in the main menu, click CUBA > Advanced > Manage modules > Create 'web-toolkit' Module.

Then add add-on dependencies:

  1. In build.gradle, for the web module add a dependency on the add-on that contains the component:

    configure(webModule) {
        ...
        dependencies {
            ...
            compile("org.vaadin.addons:stepper:2.4.0")
        }
  2. In AppWidgetSet.gwt.xml file of the web-toolkit module, indicate that the project’s widgetset inherits from the add-on widgetset:

    <module>
        <inherits name="com.haulmont.cuba.web.widgets.WidgetSet" />
    
        <inherits name="org.vaadin.risto.stepper.StepperWidgetset" />
    
        <set-property name="user.agent" value="safari" />
    </module>

    You can speed up the widgetset compilation by defining the user.agent property. In this example, widgetset will be compiled only for browsers based on WebKit: Chrome, Safari, etc.

Now the component from the Vaadin add-on is included to the project. Let’s see how to use it in the project screens.

  • Create a new entity Customer with two fields:

    • name of type String

    • score of type Integer

  • Generate standard screens for the new entity. Ensure that the Module field is set to Module: 'app-web_main' (this field is shown only if the gui module is added to the project). Screens that use Vaadin components directly must be placed in the web module.

    Actually, screens can be placed in the gui module as well, but then the code that uses the Vaadin component should be moved to a separate companion.

  • Next, we will add the stepper component to the screen.

    Replace the score field of the form component of the customer-edit.xml screen with a hBox that will be used as a container for a Vaadin component.

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd"
            caption="msg://editorCaption"
            focusComponent="form"
            messagesPack="com.company.demo.web.customer">
        <data>
            <instance id="customerDc"
                      class="com.company.demo.entity.Customer"
                      view="_local">
                <loader/>
            </instance>
        </data>
        <dialogMode height="600"
                    width="800"/>
        <layout expand="editActions" spacing="true">
            <form id="form" dataContainer="customerDc">
                <column width="250px">
                    <textField id="nameField" property="name"/>
                    <!-- A box that will be used as a container for a Vaadin component -->
                    <hbox id="scoreBox"
                          caption="msg://com.company.demo.entity/Customer.score"
                          height="100%"
                          width="100%"/>
                </column>
            </form>
            <hbox id="editActions" spacing="true">
                <button action="windowCommitAndClose"/>
                <button action="windowClose"/>
            </hbox>
        </layout>
    </window>

    Add the following code to the CustomerEdit.java controller:

    package com.company.demo.web.customer;
    
    import com.company.demo.entity.Customer;
    import com.haulmont.cuba.gui.components.HBoxLayout;
    import com.haulmont.cuba.gui.screen.*;
    import com.vaadin.ui.Layout;
    import org.vaadin.risto.stepper.IntStepper;
    
    import javax.inject.Inject;
    
    @UiController("demo_Customer.edit")
    @UiDescriptor("customer-edit.xml")
    @EditedEntityContainer("customerDc")
    @LoadDataBeforeShow
    public class CustomerEdit extends StandardEditor<Customer> {
        @Inject
        private HBoxLayout scoreBox;
    
        private IntStepper stepper = new IntStepper();
    
        @Subscribe
        protected void onInit(InitEvent event) {
            scoreBox.unwrap(Layout.class)
                    .addComponent(stepper);
    
            stepper.setSizeFull();
            stepper.addValueChangeListener(valueChangeEvent ->
                    getEditedEntity().setScore(valueChangeEvent.getValue()));
        }
    
        @Subscribe
        protected void onInitEntity(InitEntityEvent<Customer> event) {
            event.getEntity().setScore(0);
        }
    
        @Subscribe
        protected void onBeforeShow(BeforeShowEvent event) {
            stepper.setValue(getEditedEntity().getScore());
        }
    }

    The onInit() method initializes a stepper component instance, retrieves a link to the Vaadin container using the unwrap method, and adds the new component to it.

    Data binding is implemented programmatically by setting a current value to the stepper component from the edited Customer instance in the onBeforeShow() method. Additionally, the corresponding entity attribute is updated through the value change listener, when the user changes the value.

  • To adapt the component style, create a theme extension in the project. A convenient way to do this is to use CUBA Studio: in the main menu, click CUBA > Advanced > Manage themes > Create theme extension. Select the hover theme in the popup window. Another way is to use the extend-theme command in CUBA CLI. After that, open the themes/hover/com.company.demo/hover-ext.scss file located in the web module and add the following code:

    /* Define your theme modifications inside next mixin */
    @mixin com_company_demo-hover-ext {
      /* Basic styles for stepper inner text box */
      .stepper input[type="text"] {
        @include box-defaults;
        @include valo-textfield-style;
    
        &:focus {
          @include valo-textfield-focus-style;
        }
      }
    }
  • Start the application server. The resulting editor screen will look as follows:

customer edit result