11.11. Managing URI Fragments

A major issue in AJAX applications is that as they run in a single web page, bookmarking the application URL (or more generally the URI) can only bookmark the application, not an application state. This is a problem for many applications, such as product catalogs and discussion forums, in which it would be good to provide links to specific products or messages. Consequently, as browsers remember the browsing history by URI, the history and the Back button do not normally work. The solution is to use the fragment identifier part of the URI, which is separated from the primary part (address + path + optional query parameters) of the URI with the hash (#) character. For example:

http://example.com/path#myfragment

The exact syntax of the fragment identifier part is defined in RFC 3986 (Internet standard STD 66) that defines the URI syntax. A fragment may only contain the regular URI path characters (see the standard) and additionally the slash and the question mark.

Vaadin offers two ways to enable the use of URI fragments: the high-level Navigator utility described in Section 11.9, “Navigating in an Application” and the low-level API described here.

11.11.1. Setting the URI Fragment

You can set the current fragment identifier with the setUriFragment() method in the Page object.

Page.getCurrent().setUriFragment("mars");

Setting the URI fragment causes an UriFragmentChangeEvent, which is processed in the same server request. As with UI rendering, the URI fragment is changed in the browser after the currently processed server request returns the response.

Prefixing the fragment identifier with an exclamation mark enables the web crawler support described in Section 11.11.4, “Supporting Web Crawling”.

11.11.2. Reading the URI Fragment

The current URI fragment can be acquired with the getUriFragment() method from the current Page object. The fragment is known when the init() method of the UI is called.

// Read initial URI fragment to create UI content
String fragment = getPage().getUriFragment();
enter(fragment);

To enable reusing the same code when the URI fragment is changed, as described next, it is usually best to build the relevant part of the UI in a separate method. In the above example, we called an enter() method, in a way that is similar to handling view changes with Navigator.

11.11.3. Listening for URI Fragment Changes

After the UI has been initialized, changes in the URI fragment can be handled with a UriFragmentChangeListener. The listeners are called when the URI fragment changes, but not when the UI is initialized, where the current fragment is available from the page object as described earlier.

For example, we could define the listener as follows in the init() method of a UI class:

public class MyUI extends UI {
    @Override
    protected void init(VaadinRequest request) {
        getPage().addUriFragmentChangedListener(
               new UriFragmentChangedListener() {
           public void uriFragmentChanged(
                   UriFragmentChangedEvent source) {
               enter(source.getUriFragment());
            }
        });

        // Read the initial URI fragment
        enter(getPage().getUriFragment());
    }

    void enter(String fragment) {
        ... initialize the UI ...
    }
}

Figure 11.12, “Application State Management with URI Fragment Utility” shows an application that allows specifying the menu selection with a URI fragment and correspondingly sets the fragment when the user selects a menu item.

Figure 11.12. Application State Management with URI Fragment Utility

Application State Management with URI Fragment Utility

11.11.4. Supporting Web Crawling

Stateful AJAX applications can not normally be crawled by a search engine, as they run in a single page and a crawler can not navigate the states even if URI fragments are enabled. The Google search engine and crawler support a convention where the fragment identifiers are prefixed with exclamation mark, such as #!myfragment. The servlet needs to have a separate searchable content page accessible with the same URL, but with a _escaped_fragment_ parameter. For example, for /myapp/myui#!myfragment it would be /myapp/myui?_escaped_fragment_=myfragment.

You can provide the crawl content by overriding the service() method in a custom servlet class. For regular requests, you should call the super implementation in the VaadinServlet class.

public class MyCustomServlet extends VaadinServlet
    @Override
    protected void service(HttpServletRequest request,
                           HttpServletResponse response)
            throws ServletException, IOException {
        String fragment = request
            .getParameter("_escaped_fragment_");
        if (fragment != null) {
            response.setContentType("text/html");
            Writer writer = response.getWriter();
            writer.append("<html><body>"+
                "<p>Here is some crawlable "+
                "content about " + fragment + "</p>");
            
            // A list of all crawlable pages
            String items[] = {"mercury", "venus",
                              "earth", "mars"};
            writer.append("<p>Index of all content:</p><ul>");
            for (String item: items) {
                String url = request.getContextPath() +
                    request.getServletPath() +
                    request.getPathInfo() + "#!" + item;
                writer.append("<li><a href='" + url + "'>" +
                              item + "</a></li>");
            }
            writer.append("</ul></body>");
        } else
            super.service(request, response);
    }
}

The crawlable content does not need to be human readable. It can provide an index of links to other application states, as we did in the example above. The links should use the "#!" notation, but can not be relative to avoid having the _escaped_fragment_ parameter.

You need to use the custom servlet class in the web.xml deployment descriptor instead of the normal VaadinServlet class, as described in Section 4.8.4, “Using a web.xml Deployment Descriptor”.

Preface
I. Introduction
1. Introduction
1.1. Overview
1.2. Example Application Walkthrough
1.3. Support for the Eclipse IDE
1.4. Goals and Philosophy
1.5. Background
2. Getting Started with Vaadin
2.1. Overview
2.2. Setting up the Development Environment
2.3. Overview of Vaadin Libraries
2.4. Installing Vaadin Plugin for Eclipse
2.5. Creating and Running a Project with Eclipse
2.6. Using Vaadin with Maven
2.7. Creating a Project with NetBeans IDE
2.8. Creating a Project with IntelliJ IDEA
2.9. Vaadin Installation Package
2.10. Using Vaadin with Scala
3. Architecture
3.1. Overview
3.2. Technological Background
3.3. Client-Side Engine
3.4. Events and Listeners
II. Server-Side Framework
4. Writing a Server-Side Web Application
4.1. Overview
4.2. Building the UI
4.3. Handling Events with Listeners
4.4. Images and Other Resources
4.5. Handling Errors
4.6. Notifications
4.7. Application Lifecycle
4.8. Deploying an Application
5. User Interface Components
5.1. Overview
5.2. Interfaces and Abstractions
5.3. Common Component Features
5.4. Field Components
5.5. Component Extensions
5.6. Label
5.7. Link
5.8. TextField
5.9. TextArea
5.10. PasswordField
5.11. RichTextArea
5.12. Date and Time Input with DateField
5.13. Button
5.14. CheckBox
5.15. Selecting Items
5.16. Table
5.17. Tree
5.18. MenuBar
5.19. Embedded Resources
5.20. Upload
5.21. ProgressBar
5.22. Slider
5.23. Calendar
5.24. Component Composition with CustomComponent
5.25. Composite Fields with CustomField
6. Managing Layout
6.1. Overview
6.2. UI, Window, and Panel Content
6.3. VerticalLayout and HorizontalLayout
6.4. GridLayout
6.5. FormLayout
6.6. Panel
6.7. Sub-Windows
6.8. HorizontalSplitPanel and VerticalSplitPanel
6.9. TabSheet
6.10. Accordion
6.11. AbsoluteLayout
6.12. CssLayout
6.13. Layout Formatting
6.14. Custom Layouts
7. Visual User Interface Design with Eclipse
7.1. Overview
7.2. Creating a New Composite
7.3. Using The Visual Editor
7.4. Structure of a Visually Editable Component
8. Themes
8.1. Overview
8.2. Introduction to Cascading Style Sheets
8.3. Syntactically Awesome Stylesheets (Sass)
8.4. Creating and Using Themes
8.5. Creating a Theme in Eclipse
8.6. Responsive Themes
9. Binding Components to Data
9.1. Overview
9.2. Properties
9.3. Holding properties in Items
9.4. Creating Forms by Binding Fields to Items
9.5. Collecting Items in Containers
10. Vaadin SQLContainer
10.1. Architecture
10.2. Getting Started with SQLContainer
10.3. Filtering and Sorting
10.4. Editing
10.5. Caching, Paging and Refreshing
10.6. Referencing Another SQLContainer
10.7. Using FreeformQuery and FreeformStatementDelegate
10.8. Non-implemented methods of Vaadin container interfaces
10.9. Known Issues and Limitations
11. Advanced Web Application Topics
11.1. Handling Browser Windows
11.2. Embedding UIs in Web Pages
11.3. Debug Mode and Window
11.4. Request Handlers
11.5. Shortcut Keys
11.6. Printing
11.7. Google App Engine Integration
11.8. Common Security Issues
11.9. Navigating in an Application
11.10. Advanced Application Architectures
11.11. Managing URI Fragments
11.12. Drag and Drop
11.13. Logging
11.14. JavaScript Interaction
11.15. Accessing Session-Global Data
11.16. Server Push
12. Portal Integration
12.1. Overview
12.2. Creating a Portlet Project in Eclipse
12.3. Portlet UI
12.4. Deploying to a Portal
12.5. Installing Vaadin in Liferay
12.6. Handling Portlet Requests
12.7. Handling Portlet Mode Changes
12.8. Non-Vaadin Portlet Modes
12.9. Vaadin IPC for Liferay
III. Client-Side Framework
13. Client-Side Vaadin Development
13.1. Overview
13.2. Installing the Client-Side Development Environment
13.3. Client-Side Module Descriptor
13.4. Compiling a Client-Side Module
13.5. Creating a Custom Widget
13.6. Debugging Client-Side Code
14. Client-Side Applications
14.1. Overview
14.2. Client-Side Module Entry-Point
14.3. Compiling and Running a Client-Side Application
14.4. Loading a Client-Side Application
15. Client-Side Widgets
15.1. Overview
15.2. GWT Widgets
15.3. Vaadin Widgets
16. Integrating with the Server-Side
16.1. Overview
16.2. Starting It Simple With Eclipse
16.3. Creating a Server-Side Component
16.4. Integrating the Two Sides with a Connector
16.5. Shared State
16.6. RPC Calls Between Client- and Server-Side
16.7. Component and UI Extensions
16.8. Styling a Widget
16.9. Component Containers
16.10. Creating Add-ons
16.11. Migrating from Vaadin 6
16.12. Integrating JavaScript Components and Extensions
IV. Vaadin Add-ons
17. Using Vaadin Add-ons
17.1. Overview
17.2. Downloading Add-ons from Vaadin Directory
17.3. Installing Add-ons in Eclipse with Ivy
17.4. Using Add-ons in a Maven Project
17.5. Troubleshooting
18. Vaadin Charts
18.1. Overview
18.2. Installing Vaadin Charts
18.3. Basic Use
18.4. Chart Types
18.5. Chart Configuration
18.6. Chart Data
18.7. Advanced Uses
18.8. Timeline
19. Vaadin JPAContainer
19.1. Overview
19.2. Installing
19.3. Defining a Domain Model
19.4. Basic Use of JPAContainer
19.5. Entity Providers
19.6. Filtering JPAContainer
19.7. Querying with the Criteria API
19.8. Automatic Form Generation
19.9. Using JPAContainer with Hibernate
20. Mobile Applications with TouchKit
20.1. Overview
20.2. Considerations Regarding Mobile Browsing
20.3. Installing Vaadin TouchKit
20.4. Importing the Vornitologist Demo
20.5. Creating a New TouchKit Project
20.6. Elements of a TouchKit Application
20.7. Mobile User Interface Components
20.8. Advanced Mobile Features
20.9. Offline Mode
20.10. Building an Optimized Widget Set
20.11. Testing and Debugging on Mobile Devices
21. Vaadin TestBench
21.1. Overview
21.2. Installing Vaadin TestBench
21.3. Preparing an Application for Testing
21.4. Using Vaadin TestBench Recorder
21.5. Developing JUnit Tests
21.6. Taking and Comparing Screenshots
21.7. Running Tests in a Distributed Environment
21.8. Headless Testing
21.9. Known Issues
A. Songs of Vaadin
Index