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,
Is there anyway to inject values from the URL fragments into server side beans?
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.
Fragment identifiers are not sent to the server. The hash fragment is used by the browser to link to elements within the same page.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With