[jboss-user] [JBoss Seam] - HOWTO: override ThemeSelector (valueChangeListener, cookie n

avbentem do-not-reply at jboss.com
Thu Mar 8 06:29:48 EST 2007


Though 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:

anonymous wrote : 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.

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4026205#4026205

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4026205



More information about the jboss-user mailing list