Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve the fragment (hash) from a URL and inject the values into the bean

I am looking for a way to inject values from the fragment (#) of a URL into bean(JSF), in the same way query-parameter values are injected. I am using Ben Alman's Bookmarkable jQuery plugin (http://benalman.com/projects/jquery-bbq-plugin/) to create the URL fragments. I was hoping that Custom regex patterns from prettyFaces could be a way to solve my problem but until now I have been unsuccessful.

(http://ocpsoft.com/docs/prettyfaces/snapshot/en-US/html_single/#config.pathparams.regext)

I would like to define here my situation and if any one has an idea, i would love to try them out.

I am using
RichFaces: 3.3.3,
Spring: 3.0.2.RELEASE,
Hibernate: 3.5.3-Final,
JSF: 2.0.2-FCS,
PrettyFaces: 3.0.1

The web application generates, following kind of URL where parameters are listed after a hash(#). The idea is to have an ajax based Bookmarkable URL. So every time I click on an element that changes the state of the system, the value is sent to the server via ajax and the URL after the hash is rewritten. There can be 1 to 3 parameters after the hash, the number of parameters are optional.

My goal is, when the user bookmarks the URL (with hash) and than revisits the saved page, the page should inject the correct values into the system and visualize the page in the previous state (like query-parameter).

Below, I have a regular expression that would catch all the parameters after the hash.

//URL:   
http://localhost:8080/nymphaea/workspace/#node=b48dd073-145c-4eb6-9ae0-e1d8ba90303c&lod=75e63fcd-f94a-49f5-b0a7-69f34d4e63d7&ln=en

//Regular Expression:    
\#(\w*\=(\w{8}-\w{4}-\w{4}-\w{4}-\w{12}))|\&(\w*\=(\w{8}-\w{4}-\w{4}-\w{4}-\w{12}))|\&(\w*\=\w{2})

I know there are websites that some how send the URL fragment into there server side logic,

  • http://maps.yahoo.com/#mvt=m&lat=36.952736&lon=-95.84758&zoom=11&tt=starbucks&tp=1&ioride=us
  • http://www.cbc.ca/video/#/Shows/Death_Comes_to_Town/ID=1365210427

Is there anyway to inject values from the URL fragments into server side beans?

like image 607
Choesang Avatar asked Aug 13 '10 08:08

Choesang


People also ask

What is a hash fragment in URL?

A hash sign (#) in a URL is referred to as a fragment. Historically, URL fragments have been used to automatically set the browser's scroll position to a predefined location in the web page. In that sense, if a URL refers to a document, then the fragment refers to a specific subsection of that document.

Does URL fragment get sent to server?

Fragment identifiers are not sent to the server. The hash fragment is used by the browser to link to elements within the same page.

How do URL fragments work?

A fragment is an internal page reference, sometimes called a named anchor. It usually appears at the end of a URL and begins with a hash (#) character followed by an identifier. It refers to a section within a web page. In HTML documents, the browser looks for an anchor tag with a name attribute matching the fragment.


2 Answers

You can do this with help of window.onhashchange which fills an input field of a hidden form which submits itself asynchronously when the input field has changed.

Here's a kickoff example of the Facelets page:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>SO question 3475076</title>
        <script>
            window.onload = window.onhashchange = function() {
                var fragment = document.getElementById("processFragment:fragment");
                fragment.value = window.location.hash;
                fragment.onchange();
            }
        </script>
        <style>.hide { display: none; }</style>
    </h:head>
    <h:body>
        <h:form id="processFragment" class="hide">
            <h:inputText id="fragment" value="#{bean.fragment}">
                <f:ajax event="change" execute="@form" listener="#{bean.processFragment}" render=":showFragment" />
            </h:inputText>
        </h:form>
        <p>Change the fragment in the URL. Either manually or by those links:
            <a href="#foo">foo</a>, <a href="#bar">bar</a>, <a href="#baz">baz</a>
        </p>
        <p>Fragment is currently: <h:outputText id="showFragment" value="#{bean.fragment}" /></p>
    </h:body>
</html>

Here's how the appropriate bean look like:

package com.stackoverflow.q3475076;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.event.AjaxBehaviorEvent;

@ManagedBean
@RequestScoped
public class Bean {

    private String fragment;

    public void processFragment(AjaxBehaviorEvent event) {
        // Do your thing here. This example is just printing to stdout.
        System.out.println("Process fragment: " + fragment);
    }

    public String getFragment() {
        return fragment;
    }

    public void setFragment(String fragment) {
        this.fragment = fragment;
    }

}

That's all.

Note that the onhashchange event is relatively new and not supported by the older browsers. In absence of the browser support (undefinied and so on), you'd like to check window.location.hash at intervals using setInterval() instead. The above code example should at least give a good kickoff. It works at at least FF3.6 and IE8.

like image 124
BalusC Avatar answered Sep 25 '22 03:09

BalusC


Here's the most reliable way to extract a fragment from a syntactically valid URL / URI.

 URI uri = new URI(someString);
 String fragment = uri.getFragment();

How you inject this into a bean will depend on what server-side framework you are using, and whether you are doing the injection using XML or annotations, or doing it programmaticaly.

like image 21
Stephen C Avatar answered Sep 25 '22 03:09

Stephen C