-
Available since OmniFaces 3.2
The <o:hashParam>
is a component that extends the standard <f:viewParam>
with support for setting hash query parameter values in bean and automatically reflecting updated model values in hash query string.
The "hash query string" is the part in URL after the #
which could be formatted in the same format as a regular request query string (the part in URL after the ?
). An example:
https://example.com/page.xhtml#foo=baz&bar=kaz
This specific part of the URL (also called hash fragment identifier) is by default not sent to the server. This component will on page load and on every window.onhashchange
event send it anyway so that the Faces model gets updated, and on every Faces ajax request update the hash query string in client side when the Faces model value has changed.
Usage
It's very similar to the <o:viewParam>
.
<f:metadata>
<o:hashParam name="foo" value="#{bean.foo}" />
<o:hashParam name="bar" value="#{bean.bar}" />
</f:metadata>
You can use the render
attribute to declare which components should be updated when a hash parameter value is present.
<f:metadata>
<o:hashParam name="foo" value="#{bean.foo}" render="fooResult" />
<o:hashParam name="bar" value="#{bean.bar}" />
</f:metadata>
...
<h:body>
...
<h:panelGroup id="fooResult">
...
</h:panelGroup>
...
</h:body>
In case you need to invoke a bean method before rendering, e.g. to preload the rendered contents based on new hash param values, then you can observe the HashChangeEvent
. See the "Events" section for an usage example.
You can use the default
attribute to declare a non-null value which should be interpreted as the default value. In other words, when the current model value matches the default value, then the hash parameter will be removed.
<f:metadata>
<o:hashParam name="foo" value="#{bean.foo}" />
<o:hashParam name="bar" value="#{bean.bar}" default="kaz" />
</f:metadata>
When #{bean.foo}
is "baz"
and #{bean.bar}
is "kaz"
or empty, then the reflected hash query string will become https://example.com/page.xhtml#foo=baz
. If #{bean.bar}
is any other value, then it will appear in the hash query string.
Note that as it extends from the standard <f:viewParam>
, its built-in conversion and validation functionality is also supported on this component.
Events
When the hash query string is changed by the client side, e.g. by following a #foo=baz&bar=kaz
link, or by manually manipulating the URL, then a CDI HashChangeEvent
will be fired which can be observed in any CDI managed bean as below:
public void onHashChange(@Observes HashChangeEvent event) {
String oldHashString = event.getOldValue();
String newHashString = event.getNewValue();
// ...
}
This is useful in case you want to preload the model for whatever is rendered by <o:hashParam render>
.
See how these plain HTML links which change the hash string will let <o:hashParam>
reflect changes in the hash string into the Faces model.
Note that the above messages are rendered by <o:hashParam render="messages">
.
- #foo=bar
- #foo=baz
- #foo=bak&bar=42
- #foo=baz&bar=invalid - this should show a conversion error message
And see how these Faces command links which change the Faces model will let <o:hashParam>
reflect changes in the Faces model into the hash string.
Note that the above messages are rendered by the command links themselves and not by the <o:hashParam>
.
<f:metadata>
<o:hashParam id="foo" name="foo" value="#{hashParamBean.foo}" render="messages" />
<o:hashParam id="bar" name="bar" value="#{hashParamBean.bar}" render="messages" />
</f:metadata>
<h:messages id="messages" styleClass="messages" infoClass="info" errorClass="error" />
<p>
See how these plain HTML links which change the hash string will let <code><o:hashParam></code> reflect changes in the hash string into the Faces model.
Note that the above messages are rendered by <code><o:hashParam render="messages"></code>.
</p>
<ul>
<li><a href="#foo=bar">#foo=bar</a></li>
<li><a href="#foo=baz">#foo=baz</a></li>
<li><a href="#foo=bak&bar=42">#foo=bak&bar=42</a></li>
<li><a href="#foo=baz&bar=invalid">#foo=baz&bar=invalid</a> - this should show a conversion error message</li>
</ul>
<p>
And see how these Faces command links which change the Faces model will let <code><o:hashParam></code> reflect changes in the Faces model into the hash string.
Note that the above messages are rendered by the command links themselves and not by the <code><o:hashParam></code>.
</p>
<o:form>
<ul>
<li><h:commandLink value="setFoo('bar'); setBar(null);" action="#{hashParamBean.action('bar', null)}"><f:ajax render=":messages" /></h:commandLink></li>
<li><h:commandLink value="setFoo('baz'); setBar(null);" action="#{hashParamBean.action('baz', null)}"><f:ajax render=":messages" /></h:commandLink></li>
<li><h:commandLink value="setFoo('bak'); setBar(42);" action="#{hashParamBean.action('bak', 42)}"><f:ajax render=":messages" /></h:commandLink></li>
</ul>
</o:form>
package org.omnifaces.showcase.components;
import static org.omnifaces.util.Messages.addGlobalInfo;
import java.io.Serializable;
import java.util.Objects;
import jakarta.enterprise.event.Observes;
import jakarta.inject.Named;
import org.omnifaces.cdi.ViewScoped;
import org.omnifaces.event.HashChangeEvent;
@Named
@ViewScoped
public class HashParamBean implements Serializable {
private static final long serialVersionUID = 1L;
private String foo;
private Long bar;
public void action(String foo, Long bar) {
setFoo(foo);
setBar(bar);
}
public void onHashChange(@Observes HashChangeEvent event) {
addGlobalInfo("hash string changed from ''{0}'' to ''{1}''", event.getOldValue(), event.getNewValue());
}
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
if (!Objects.equals(foo, this.foo)) {
addGlobalInfo("hash param ''foo'' value changed from ''{0}'' to ''{1}''", this.foo, foo);
}
this.foo = foo;
}
public Long getBar() {
return bar;
}
public void setBar(Long bar) {
if (!Objects.equals(bar, this.bar)) {
addGlobalInfo("hash param ''bar'' value changed from ''{0}'' to ''{1}''", this.bar, bar);
}
this.bar = bar;
}
}
VDL documentation
API documentation
Java source code
org.omnifaces.util.Faces
org.omnifaces.event.HashChangeEvent
org.omnifaces.component.input.HashParam
org.omnifaces.component.input.OnloadParam