HOWTO: override ThemeSelector (valueChangeListener, cookie n
avbentem Mar 8, 2007 6:29 AMThough in fact quite easy, it took me some time to get this working (for example as at some point I forgot the #${ .. } to surround the EL statement...) -- so a mini HOWTO:
First of all: for the localeSelector auto-submit seems to be very easy:
<h:form> <h:selectOneMenu value="#{localeSelector.localeString}" onchange="submit();" valueChangeListener="#{localeSelector.select}"> <f:selectItems value="#{localeSelector.supportedLocales}" /> </h:selectOneMenu> </h:form>
However, I guess this works by accident; in fact org.jboss.seam.core.LocaleSelector#select() does not accept ValueChangeEvent as a parameter; so the above just works given the current implementation of select -- no guarantees for future releases. Any comment on that anyone?
And: the above does not work for ThemeSelector, as ThemeSelector#select() apparently does not know of any new value. So, an example of an extended ThemeSelector to implement a value change handler:
package my.package; import static org.jboss.seam.InterceptionType.NEVER; import static org.jboss.seam.annotations.Install.APPLICATION; import javax.faces.event.ValueChangeEvent; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Install; import org.jboss.seam.annotations.Intercept; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; import org.jboss.seam.theme.ThemeSelector; // Use the same @Name as the built-in selector @Name("org.jboss.seam.theme.themeSelector") @Scope(ScopeType.SESSION) @Intercept(NEVER) @Install(precedence = APPLICATION) public class ThemeOnChangeSelector extends ThemeSelector { private String cookieName = "theme"; // When overridden then this should NOT have @Create defined // again; it will inherit it. @Override public void initDefaultTheme() { // whatever, if needed. super.initDefaultTheme(); } @Override public String getCookieName() { return cookieName; } public void setCookieName(String cookieName) { this.cookieName = cookieName; } public void valueChanged(ValueChangeEvent event) { setTheme((String) event.getNewValue()); select(); } }
Having used the very same value for @Name above, the logs will show:
org.jboss.seam.init.Initialization
two components with same name, higher precedence wins: org.jboss.seam.theme.themeSelector
And, having used the very same value for @Name above, one can use the very same setup in components.xml:
<?xml version="1.0" encoding="UTF-8"?> <components xmlns="http://jboss.com/products/seam/components" xmlns:theme="http://jboss.com/products/seam/theme" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://jboss.com/products/seam/components http://jboss.com/products/seam/components-1.1.xsd http://jboss.com/products/seam/theme http://jboss.com/products/seam/theme-1.1.xsd"> <theme:theme-selector cookie-enabled="true"> <theme:available-themes> <value>default</value> <value>accessible</value> <value>printable</value> </theme:available-themes> </theme:theme-selector> </components>
...or, when one wants to use the additional setter for a different cookie name, then one cannot use the existing namespace, so:
<component name="org.jboss.seam.theme.themeSelector"> <property name="availableThemes"> <value>default</value> <value>accessible</value> <value>printable</value> </property> <property name="cookieEnabled">true</property> <property name="cookieName">skin</property> </component>
Now, the following works, still referring to the default #{themeSelector}:
<h:form> <h:selectOneMenu immediate="true" value="#{themeSelector.theme}" onchange="submit();" valueChangeListener="#{themeSelector.valueChanged}"> <f:selectItems value="#{themeSelector.themes}" /> </h:selectOneMenu> <h:selectOneMenu immediate="true" value="#{localeSelector.localeString}" onchange="submit();" valueChangeListener="#{localeSelector.select}"> <f:selectItems value="#{localeSelector.supportedLocales}" /> </h:selectOneMenu> </h:form>
Note that the immediate="true" are not actually required when these dropdowns are the only elements within the form. And note that any other form contents might be lost when the user selects another theme or language. See also: http://wiki.apache.org/myfaces/SubmitPageOnValueChange
In the pages, no changes are required:
<link href="#{theme.css}" rel="stylesheet" type="text/css" />
and
template="#{theme.template}"
Finally, when using both themes and localization then add the translations to, for example, messages_nl.properties:
org.jboss.seam.theme.default=Standaard org.jboss.seam.theme.accessible=Groot org.jboss.seam.theme.printable=Afdrukken
Enjoy,
Arjan.