(Quick Reference)

3 Concepts and Usage - Reference Documentation

Authors: Ondrej Kvasnovsky, Francis McKenzie

Version: 1.6.2.2-SNAPSHOT

3 Concepts and Usage

3.1 Usage Styles

The plugin supports two styles of usage:
  • Base-Style: Simply exposes the base Vaadin Application, leaving the developer to build the interface programmatically using Java/Groovy classes.
  • Grails-Style: Allows the developer to construct an application using Grails-style Controllers and GSP Views, supported by a Vaadin tag library.

This guide assumes the user prefers to utilise the Grails-Style architectural pattern. See a comparison of the styles and further details here.

3.2 Controllers, Views and Fragments

The Vaadin plugin adopts the Grails convention of structuring an application into Controllers and Views. However, since Vaadin is an AJAX-based framework rather than a conventional Request-Response framework, we do not map URLs to controllers but instead map Fragments to controllers.

As an example, say we want to create a screen for displaying a list of books. In Grails, we would create a BookController.groovy file containing a list() method, and a book/list.gsp file. This would then be accessible from a browser via http://localhost:8080/myapp/book/list

With the Vaadin plugin, we do something very similar. We create a BookVaadinController.groovy file containing a list() method, and a vaadin/book/list.gsp file. This is then accessible from a browser via http://localhost:8080/myapp/vaadin#book/list. Note the '#' in the URL to denote the fragment!

The context path for a vaadin app defaults to /vaadin. This can be changed in the Configuration

3.3 A Simple Tutorial

In this section, we will create a simple "Hello World" screen using Vaadin. If you are new to Grails, it might be useful to familiarise yourself with the concepts in the getting-started section of the Grails User Guide.

We will assume you have already installed Vaadin following the instructions in the Installation section. Now follow these steps:

1. Create the Controller

Create a VaadinController by entering the following at the command line:

grails create-vaadin-controller myapp.Hello

This simply creates an empty groovy class under the grails-app/controllers folder. Note that VaadinController is automatically appended to the class name.

2. Add an Action

In the HelloVaadinController class, add a greetings method as follows:

class HelloVaadinController {
	def greetings() {}
}

3. Create the View

Create file grails-app/views/vaadin/hello/greetings.gsp with the following contents:

<div>
  <v:label>Hello world!</v:label>
</div>

4. Run the App

Finally, run the application using grails run-app and then browse to http://localhost:8080/myapp/vaadin#hello/greetings. You should see the "Hello World!" message displayed.

(Note that you will need to replace 'myapp' in the above URL with the name of your grails project.)

5. Use the Grails Theme

Let's improve the appearance of our new page. Change the text in file grails-app/views/vaadin/hello/greetings.gsp to the following:

<v:layout name="main">
  <v:label location="body">Hello world!</v:label>
</v:layout>

Now refresh your browser page - you should see your "Hello World!" message again, but this time within the familiar Grails theme.

Notice we used the special tag <v:layout name="main"> in the final step. This layout tag looks for a .gsp file with the specified name in grails-app/views/vaadin/layouts. Take a look at main.gsp in this directory in your app!

3.4 Scaffolding a Domain Class

One of Grails's (and indeed other frameworks such as Ruby) most useful features is its support for very quickly generating useable CRUD screens for your domain model. In Grails, this can be done by running the generate-controller, generate-views and generate-all commands.

The Vaadin plugin provides the exact equivalent of the standard grails scaffolding scripts, as follows:

CommandDescription
generate-vaadin-controllerGenerates a new VaadinController in the grails-app/controllers dir
for the specified domain class.
generate-vaadin-viewsGenerates the Vaadin CRUD GSP views in the grails-app/views dir
for the specified domain class.
generate-vaadin-allGenerates the Controller and Views for the specified domain class.
create-vaadin-controllerCreates an empty VaadinController in the grails-app/controllers dir
install-vaadin-templatesInstalls the templates used for the above scaffolding commands into
src/templates/vaadin

For example, if you have a Domain Class called com.somepackage.Author, you should run the following at the command line to scaffold a CRUD interface:

grails generate-vaadin-all com.somepackage.Author

You can then browse the CRUD interface by visiting http://localhost:8080/myapp/vaadin#author.

Some of the benefits of Vaadin should now become apparent! Notice the lazy-loading, infinitely scrollable table on the list screen. Also, for any Date fields in your domain class, notice the Date Picker that gets automatically inserted. If that is not enough, you should definitely visit the Vaadin Sampler page and check out all the other ways you can spruce up your user interface!

3.5 Views and Tags

In the Vaadin view GSPs, you can use all of the Grails tags as you would in a normal Grails GSP.

Sitemesh layout tags are currently not supported. Please use the Vaadin layout tag instead.

In addition, you can embed Vaadin components in GSPs using the tag library provided by this plugin:

TagDescription
LAYOUTS 
accordionAdds a Accordion component to the parent container.
horizontalLayoutAdds a HorizontalLayout component to the parent container.
includeIncludes the output of another controller/action in the current Gsp.
layoutRenders the tag's body using another Gsp as a template.
locationAdds the tag's body to the specified location in the parent container.
mainWindowAllows configuring the Vaadin application's main Window.
tabConfigures a single tab of the parent TabSheet component.
tabsAdds a TabSheet component to the parent container.
verticalLayoutAdds a VerticalLayout component to the parent container.
  
TABLES 
tableAdds a Table component to the parent container.
columnConfigures a single column of the parent Table component.
  
FORMS 
formAdds a Form component to the parent container.
fieldAdds a Field to the parent container.
checkBoxAdds a CheckBox field to the parent container.
comboBoxAdds a ComboBox field to the parent container.
currencySelectAdds a Currency-populated Select field to the parent container.
customFieldAdds a DefaultCustomField to the parent container.
dateAdds a DateField to the parent container.
fileAdds a DefaultUploadField to the parent container.
listSelectAdds a ListSelect field to the parent container.
localeSelectAdds a Locale-populated Select field to the parent container.
optionGroupAdds a OptionGroup field to the parent container.
passwordAdds a PasswordField to the parent container.
selectAdds a Select field to the parent container.
textAdds a TextField field to the parent container.
textAreaAdds a TextArea field to the parent container.
timeZoneSelectAdds a TimeZone-populated Select field to the parent container.
  
MISC 
labelAdds a Label component to the parent container.
linkAdds a GrailsButton component to the parent container.
warningShows a warning-type Window.Notification in the application's main window.
errorShows an error-type Window.Notification in the application's main window.

3.6 Mixing Vaadin and Grails

For any Domain class, you can easily create a regular-Grails CRUD interface and a Vaadin CRUD interface for it in the same app. E.g. for Domain class mypackage.Book:

 Scaffolding CommandURL
Grails:generate-all mypackage.Bookhttp://localhost:8080/myapp/book
Vaadin:generate-vaadin-all mypackage.Bookhttp://localhost:8080/myapp/vaadin#book

The default configuration is for Vaadin to be served from path /vaadin - see the contextRelativePath setting in the Configuration.

If you set contextRelativePath to '/' it will prevent any requests from reaching 'regular' Grails controllers.

3.7 Vaadin Controllers

A Vaadin controller is very similar to a regular Grails controller. It must exist under grails-app/controllers and must have a name ending with VaadinController.

Grails treats Vaadin controllers like regular controllers. Therefore in general the features available to regular controllers should also be available to Vaadin controllers. See the controllers section of the Grails user guide for further details about controllers.

However, note that Vaadin controllers do not operate within the standard servlet request/response lifecycle. As such, some under-the-hood differences do exist, therefore not all controller functionality may work as expected in Vaadin controllers. Some key differences to be aware of are described in the following sections.

URIs and Fragments

As previously discussed, Vaadin Controllers are accessed in the browser by placing the controller name at the start of the browser fragment, rather than in the URI. So:

// Regular Grails Controller
http://localhost:8080/grailsapp/book/list

// Vaadin Controller http://localhost:8080/grailsapp/vaadin#book/list

Controller API

Grails methods render, redirect, params, flash are specifically overridden in Vaadin controllers, to provide support for the plugin's page-dispatching mechanism. However, they can be treated like the corresponding regular Grails methods.

Vaadin Controllers can also render Vaadin Components directly, as in the following example:

import com.vaadin.ui.Label

class MyVaadinController { def index() { render new Label("Hello World!") } }

Controllers can reference vaadinApplication to get the Vaadin Application object for the current session.

Passing Domain Instances

Unlike regular controllers, Vaadin controllers can receive Grails domain instances (and any other Java object) in their params map. By contrast, the params in a standard servlet request can only be strings.

This means that we can pass a domain instance from our controller to our view, which can then pass it to another controller in the params map of a link tag.

However, note that the second controller must merge the domain instance into its persistence session before using it. For example:

class BookController {
  def update {

// Get the book instance passed in the params def book = params.instance

// Attempt to merge Book instance into current persistence context def bookMergedAndValidated = book.merge()

// Merging failed, possibly due to validation error if (!bookMergedAndValidated) { render(view: "edit", model: [bookInstance: book]) return }

// Merging succeeded, now you can save the instance bookMergedAndValidated.save(flush:true) [bookInstance: bookMergedAndValidated] } }

3.8 Home Page and Error Page

Home Page

The Vaadin plugin includes a controller called HomeVaadinController. The index() method of this controller is called when the user's browser contains an empty fragment, or contains the fragment #home.

This controller simply renders your application's grails-app/views/vaadin/index.gsp view. You can edit this file directly to customise the home page.

For even more flexibility, you could create a HomeVaadinController in your app by running the following command:

grails create-vaadin-controller mypackage.Home

You could then customise this controller by for example redirecting to another controller as the default home page:

package mypackage

class HomeVaadinController { def index() { redirect controller:"book" } }

Error Page

The Vaadin plugin includes a controller called ErrorVaadinController. The index() method of this controller is called whenever a Vaadin Controller or View throws an error.

This controller simply renders your application's grails-app/views/vaadin/error.gsp view. You can edit this file directly to customise the error page.

For even more flexibility, you could create a ErrorVaadinController in your app by running the following command:

grails create-vaadin-controller mypackage.Error

You could then customise this controller by for example redirecting to another controller as the default error page:

package mypackage

class ErrorVaadinController { def index() { redirect url:"http://google.com" } }

3.9 Vaadin API

The Vaadin plugin automatically injects an API into an application's Vaadin classes.

A Vaadin Class must:
  • Exist under the grails-app/vaadin directory
  • Have vaadin in its package name, or the package name of any of its superclasses.

The injected API is as follows:

FieldDescription
vaadinApplicationGets the Vaadin Application object for this session.
getBean( name )Specify a Spring bean to retrieve by name.
i18n( args )Provides same functionality as the Grails g:message tag.

Preventing API Injection

This can be easily achieved by moving a class to src/groovy instead of grails-app/vaadin

Accessing Vaadin Application

The following table summarises how to access the VaadinApplication object, in different contexts:

ContextHow to Obtain VaadinApplication
Vaadin ControllerVariable vaadinApplication
Vaadin GSP ViewVariable vaadinApplication
Vaadin ClassVariable vaadinApplication
TaglibVariable request.vaadinApplication
All OthersUse VaadinApplicationContextHolder

Example: Using VaadinApplicationContextHolder

import org.grails.plugin.vaadin.VaadinApplicationContextHolder

class MyClass { def myMethod() {

// Gets the session's Vaadin Application def app = VaadinApplicationContextHolder.vaadinApplication } }

3.10 Embedding Vaadin

The plugin provides the create-vaadin-embedded command which allows you to easily embed your Vaadin application in a Grails page.

The benefit of this approach is that your Vaadin Application is then hosted inside a <div> in a regular Grails view. You can then customize the 'host' view like any other Grails view - e.g use Sitemesh, or include other javascript and CSS resources using the <r:resource> tag. The Vaadin Application then just becomes one section of the page.

3.11 Base-Style vs Grails-Style

As previously discussed, the Vaadin plugin supports two styles of usage, which are compared in the below sections.

Base-Style

Aspect of StyleDescription
OverviewSimply exposes the base Vaadin Application, leaving the developer to
build the interface programmatically using Java/Groovy classes.
How to UseSubclass com.vaadin.Application in your app's Vaadin application class
located in grails-app/vaadin
Typical CodeForm form = new Form();
TextField textField = new TextField();
textField.name = "myField";
textField.caption = "My Field";
form.addComponent(textField);
Architecture PatternNone
Pros- May be suitable for developers familiar with GWT but not with Grails.
Cons- More difficult to build HTML interfaces, due to separation of HTML layout code
and Vaadin Component code.

Grails-Style

Aspect of StyleDescription
OverviewAllows the developer to construct an application using Grails-style Controllers and
GSP Views, supported by a Vaadin tag library.
How to UseSubclass org.grails.plugin.vaadin.GrailsVaadinApplication in your app's
Vaadin application class located in grails-app/vaadin
Typical Code<v:form>
<v:text name="myField">My Field</v:text>
</v:form>
Architecture PatternGrails and Spring Model-View-Controller
Pros- Full CRUD scaffolding supported
- Easier to build HTML interfaces using Grails & Vaadin tags in GSPs
- MVC separation of application logic and presentation
- Browser fragment and history handling
- Grails error screens for easy debugging
- Automatic wrapping of controller code in persistence transactions
Cons- Adding custom Vaadin Components requires writing tag libraries or else writing
code scriptlets in GSPs.