3 Concepts and Usage - Reference Documentation
Authors: Ondrej Kvasnovsky, Francis McKenzie
Version: 1.6.2.2-SNAPSHOT
Table of Contents
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.
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 aBookController.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
grails-app/controllers
folder. Note that
VaadinController
is automatically appended to the class name.2. Add an Action
In the HelloVaadinController class, add agreetings
method as follows:class HelloVaadinController { def greetings() {} }
3. Create the View
Create filegrails-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 usinggrails 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 filegrails-app/views/vaadin/hello/greetings.gsp
to the following:<v:layout name="main"> <v:label location="body">Hello world!</v:label> </v:layout>
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 ingrails-app/views/vaadin/layouts
. Take a look atmain.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:Command | Description |
---|---|
generate-vaadin-controller | Generates a new VaadinController in the grails-app/controllers dirfor the specified domain class. |
generate-vaadin-views | Generates the Vaadin CRUD GSP views in the grails-app/views dirfor the specified domain class. |
generate-vaadin-all | Generates the Controller and Views for the specified domain class. |
create-vaadin-controller | Creates an empty VaadinController in the grails-app/controllers dir |
install-vaadin-templates | Installs the templates used for the above scaffolding commands intosrc/templates/vaadin |
com.somepackage.Author
, you should run the following at the command line to
scaffold a CRUD interface:grails generate-vaadin-all com.somepackage.Author
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:
Tag | Description |
---|---|
LAYOUTS | |
accordion | Adds a Accordion component to the parent container. |
horizontalLayout | Adds a HorizontalLayout component to the parent container. |
include | Includes the output of another controller/action in the current Gsp. |
layout | Renders the tag's body using another Gsp as a template. |
location | Adds the tag's body to the specified location in the parent container. |
mainWindow | Allows configuring the Vaadin application's main Window. |
tab | Configures a single tab of the parent TabSheet component. |
tabs | Adds a TabSheet component to the parent container. |
verticalLayout | Adds a VerticalLayout component to the parent container. |
TABLES | |
table | Adds a Table component to the parent container. |
column | Configures a single column of the parent Table component. |
FORMS | |
form | Adds a Form component to the parent container. |
field | Adds a Field to the parent container. |
checkBox | Adds a CheckBox field to the parent container. |
comboBox | Adds a ComboBox field to the parent container. |
currencySelect | Adds a Currency-populated Select field to the parent container. |
customField | Adds a DefaultCustomField to the parent container. |
date | Adds a DateField to the parent container. |
file | Adds a DefaultUploadField to the parent container. |
listSelect | Adds a ListSelect field to the parent container. |
localeSelect | Adds a Locale-populated Select field to the parent container. |
optionGroup | Adds a OptionGroup field to the parent container. |
password | Adds a PasswordField to the parent container. |
select | Adds a Select field to the parent container. |
text | Adds a TextField field to the parent container. |
textArea | Adds a TextArea field to the parent container. |
timeZoneSelect | Adds a TimeZone-populated Select field to the parent container. |
MISC | |
label | Adds a Label component to the parent container. |
link | Adds a GrailsButton component to the parent container. |
warning | Shows a warning-type Window.Notification in the application's main window. |
error | Shows 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 classmypackage.Book
:Scaffolding Command | URL | |
---|---|---|
Grails: | generate-all mypackage.Book | http://localhost:8080/myapp/book |
Vaadin: | generate-vaadin-all mypackage.Book | http://localhost:8080/myapp/vaadin#book |
/vaadin
-
see the contextRelativePath
setting in the Configuration.If you setcontextRelativePath
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 undergrails-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.Labelclass MyVaadinController { def index() { render new Label("Hello World!") } }
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. Theindex()
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
package mypackageclass HomeVaadinController { def index() { redirect controller:"book" } }
Error Page
The Vaadin plugin includes a controller called ErrorVaadinController. Theindex()
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
package mypackageclass 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:The injected API is as follows:
- Exist under the
grails-app/vaadin
directory- Have
vaadin
in its package name, or the package name of any of its superclasses.
Field | Description |
---|---|
vaadinApplication | Gets 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 tosrc/groovy
instead of grails-app/vaadin
Accessing Vaadin Application
The following table summarises how to access the VaadinApplication object, in different contexts:Context | How to Obtain VaadinApplication |
---|---|
Vaadin Controller | Variable vaadinApplication |
Vaadin GSP View | Variable vaadinApplication |
Vaadin Class | Variable vaadinApplication |
Taglib | Variable request.vaadinApplication |
All Others | Use VaadinApplicationContextHolder |
Example: Using VaadinApplicationContextHolder
import org.grails.plugin.vaadin.VaadinApplicationContextHolderclass 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 Style | Description |
---|---|
Overview | Simply exposes the base Vaadin Application, leaving the developer to build the interface programmatically using Java/Groovy classes. |
How to Use | Subclass com.vaadin.Application in your app's Vaadin application class located in grails-app/vaadin |
Typical Code | Form form = new Form(); TextField textField = new TextField(); textField.name = "myField"; textField.caption = "My Field"; form.addComponent(textField); |
Architecture Pattern | None |
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 Style | Description |
---|---|
Overview | Allows the developer to construct an application using Grails-style Controllers and GSP Views, supported by a Vaadin tag library. |
How to Use | Subclass 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 Pattern | Grails 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. |