Commit 9b1f71c86041ddf3454d3f02abc553d1dd1adf6f
1 parent
ef56792c
Added FocusModifier to modify client id for components.
Showing
6 changed files
with
176 additions
and
40 deletions
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | -<!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN" | |
| 1 | +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN" | |
| 3 | 2 | "http://labs.jboss.com/jbossrichfaces/component-config.dtd" > | 
| 4 | 3 | <components> | 
| 5 | 4 | <component> | 
| ... | ... | @@ -28,8 +27,7 @@ | 
| 28 | 27 | <superclassname>org.ajax4jsf.tests.AbstractJspTestCase</superclassname> | 
| 29 | 28 | </test> | 
| 30 | 29 | |
| 31 | - </tag> | |
| 32 | - &ui_component_attributes; | |
| 30 | + </tag> &ui_component_attributes; | |
| 33 | 31 | <property> | 
| 34 | 32 | <name>for</name> | 
| 35 | 33 | <classname>java.lang.String</classname> | 
| ... | ... | @@ -42,17 +40,23 @@ | 
| 42 | 40 | <name>priority</name> | 
| 43 | 41 | <classname>java.lang.Integer</classname> | 
| 44 | 42 | <description> | 
| 45 | - If there are more components requesting focus, | |
| 46 | - then component with lowest priority will be focused. | |
| 43 | + If there are more components requesting focus, then component with lowest priority will be focused. | |
| 47 | 44 | </description> | 
| 48 | 45 | </property> | 
| 49 | 46 | <property> | 
| 47 | + <name>targetClientId</name> | |
| 48 | + <classname>java.lang.String</classname> | |
| 49 | + <description> | |
| 50 | + If some other element then the one matching clintId of target component should be focused and it cannot be achieved with suffix, use this | |
| 51 | + attribute. | |
| 52 | + </description> | |
| 53 | + <defaultvalue>""</defaultvalue> | |
| 54 | + </property> | |
| 55 | + <property> | |
| 50 | 56 | <name>suffix</name> | 
| 51 | 57 | <classname>java.lang.String</classname> | 
| 52 | 58 | <description> | 
| 53 | - Suffix added to clientId. Useful for focusing radio elements. | |
| 54 | - Example : suffix=":0" puts focus on first radio if target is | |
| 55 | - radio. | |
| 59 | + Suffix added to clientId. Useful for focusing radio elements. Example : suffix=":0" puts focus on first radio if target is radio. | |
| 56 | 60 | </description> | 
| 57 | 61 | <defaultvalue>""</defaultvalue> | 
| 58 | 62 | </property> | 
| ... | ... | @@ -60,9 +64,8 @@ | 
| 60 | 64 | <name>timing</name> | 
| 61 | 65 | <classname>java.lang.String</classname> | 
| 62 | 66 | <description> | 
| 63 | - Moment when focus should be put. The possible values are "onJScall" and "onload". | |
| 64 | - If "onJScall" is used then you must manually call Richfaces.FocusManager.focus(). | |
| 65 | - The default value is "onload". | |
| 67 | + Moment when focus should be put. The possible values are "onJScall" and "onload". If "onJScall" is used then you must manually call | |
| 68 | + Richfaces.FocusManager.focus(). The default value is "onload". | |
| 66 | 69 | </description> | 
| 67 | 70 | <defaultvalue>"onload"</defaultvalue> | 
| 68 | 71 | </property> | 
| ... | ... | @@ -70,8 +73,7 @@ | 
| 70 | 73 | <name>name</name> | 
| 71 | 74 | <classname>java.lang.String</classname> | 
| 72 | 75 | <description> | 
| 73 | - Name of JavaScript function generated to trigger focus. This is required if "timing" attribute | |
| 74 | - is set to "onJScall". | |
| 76 | + Name of JavaScript function generated to trigger focus. This is required if "timing" attribute is set to "onJScall". | |
| 75 | 77 | </description> | 
| 76 | 78 | <defaultvalue>null</defaultvalue> | 
| 77 | 79 | </property> | ... | ... | 
src/main/config/component/focusModifier.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN" | |
| 2 | + "http://labs.jboss.com/jbossrichfaces/component-config.dtd" > | |
| 3 | +<components> | |
| 4 | + <component> | |
| 5 | + <name>org.richfaces.FocusModifier</name> | |
| 6 | + <family>org.richfaces.FocusModifier</family> | |
| 7 | + <classname>org.richfaces.component.html.HtmlFocusModifier</classname> | |
| 8 | + <superclass>org.richfaces.component.UIFocusModifier</superclass> | |
| 9 | + <description> | |
| 10 | + <![CDATA[ | |
| 11 | + Provides info for focus component used to modify clientId to focus. | |
| 12 | + ]]> | |
| 13 | + </description> | |
| 14 | + <renderer generate="false" override="false"> | |
| 15 | + <name>org.richfaces.FocusModifierRenderer</name> | |
| 16 | + <classname>org.richfaces.renderkit.html.HtmlFocusModifierRenderer</classname> | |
| 17 | + </renderer> | |
| 18 | + <tag> | |
| 19 | + <name>focusModifier</name> | |
| 20 | + <classname>org.richfaces.taglib.FocusModifierTag</classname> | |
| 21 | + <superclass> | |
| 22 | + org.ajax4jsf.webapp.taglib.HtmlComponentTagBase | |
| 23 | + </superclass> | |
| 24 | + <test> | |
| 25 | + <classname>org.richfaces.taglib.HtmlFocusModifierTagTest</classname> | |
| 26 | + <superclassname>org.ajax4jsf.tests.AbstractJspTestCase</superclassname> | |
| 27 | + </test> | |
| 28 | + </tag> &ui_component_attributes; | |
| 29 | + <property> | |
| 30 | + <name>targetClientId</name> | |
| 31 | + <classname>java.lang.String</classname> | |
| 32 | + <description> | |
| 33 | + If some other element then the one matching clintId of target component should be focused and it cannot be achieved with suffix, use this | |
| 34 | + attribute. | |
| 35 | + </description> | |
| 36 | + <defaultvalue>""</defaultvalue> | |
| 37 | + </property> | |
| 38 | + <property> | |
| 39 | + <name>suffix</name> | |
| 40 | + <classname>java.lang.String</classname> | |
| 41 | + <description> | |
| 42 | + Suffix added to clientId. Useful for focusing radio elements. Example : suffix=":0" puts focu on first radio if target is radio. | |
| 43 | + </description> | |
| 44 | + <defaultvalue>""</defaultvalue> | |
| 45 | + </property> | |
| 46 | + </component> | |
| 47 | +</components> | ... | ... | 
| ... | ... | @@ -12,22 +12,26 @@ import java.util.Set; | 
| 12 | 12 | public abstract class UIFocus extends UIComponentBase { | 
| 13 | 13 | |
| 14 | 14 | public static final String COMPONENT_TYPE = "org.richfaces.Focus"; | 
| 15 | + | |
| 15 | 16 | public static final String COMPONENT_FAMILY = "org.richfaces.Focus"; | 
| 17 | + | |
| 16 | 18 | public static final String TIMING_ON_LOAD = "onload"; | 
| 17 | 19 | |
| 20 | + public static final String FOCUS_MODIFIER_FACET_NAME = "focusModifier"; | |
| 21 | + | |
| 18 | 22 | public Integer getDefaultPriority() { | 
| 19 | 23 | UIComponent parentForm = getParent(); | 
| 20 | 24 | while (parentForm != null && !(parentForm instanceof UIForm)) { | 
| 21 | 25 | parentForm = parentForm.getParent(); | 
| 22 | 26 | } | 
| 23 | 27 | if (parentForm != null) { | 
| 24 | - return getUIInputChildrenCount(parentForm, getForComponentId()); | |
| 28 | + return getUIInputChildrenCount(parentForm, getTargetComponentId()); | |
| 25 | 29 | } else { | 
| 26 | 30 | return Integer.MAX_VALUE; | 
| 27 | 31 | } | 
| 28 | 32 | } | 
| 29 | 33 | |
| 30 | - public String getForComponentId() { | |
| 34 | + public String getTargetComponentId() { | |
| 31 | 35 | String aFor = getFor(); | 
| 32 | 36 | |
| 33 | 37 | if (aFor != null && !"".equals(aFor)) { | 
| ... | ... | @@ -67,6 +71,10 @@ public abstract class UIFocus extends UIComponentBase { | 
| 67 | 71 | |
| 68 | 72 | public abstract void setFor(String value); | 
| 69 | 73 | |
| 74 | + public abstract String getTargetClientId(); | |
| 75 | + | |
| 76 | + public abstract void setTargetClientId(String targetClientId); | |
| 77 | + | |
| 70 | 78 | public abstract String getSuffix(); | 
| 71 | 79 | |
| 72 | 80 | public abstract void setSuffix(String value); | ... | ... | 
| 1 | +package org.richfaces.component; | |
| 2 | + | |
| 3 | +import javax.faces.component.UIComponentBase; | |
| 4 | + | |
| 5 | +public abstract class UIFocusModifier extends UIComponentBase { | |
| 6 | +// ------------------------------ FIELDS ------------------------------ | |
| 7 | + | |
| 8 | + public static final String COMPONENT_FAMILY = "org.richfaces.Focus"; | |
| 9 | + | |
| 10 | + public static final String COMPONENT_TYPE = "org.richfaces.FocusModifier"; | |
| 11 | + | |
| 12 | +// -------------------------- OTHER METHODS -------------------------- | |
| 13 | + | |
| 14 | + public abstract String getTargetClientId(); | |
| 15 | + | |
| 16 | + public abstract String getSuffix(); | |
| 17 | + | |
| 18 | + public abstract void setTargetClientId(String focusClientId); | |
| 19 | + | |
| 20 | + public abstract void setSuffix(String value); | |
| 21 | +} | ... | ... | 
| 1 | +/* | |
| 2 | + * JBoss, Home of Professional Open Source | |
| 3 | + * Copyright , Red Hat, Inc. and individual contributors | |
| 4 | + * by the @authors tag. See the copyright.txt in the distribution for a | |
| 5 | + * full listing of individual contributors. | |
| 6 | + * | |
| 7 | + * This is free software; you can redistribute it and/or modify it | |
| 8 | + * under the terms of the GNU Lesser General Public License as | |
| 9 | + * published by the Free Software Foundation; either version 2.1 of | |
| 10 | + * the License, or (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This software is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 | + * Lesser General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU Lesser General Public | |
| 18 | + * License along with this software; if not, write to the Free | |
| 19 | + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | |
| 20 | + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | |
| 21 | + */ | |
| 22 | + | |
| 23 | +package org.richfaces.renderkit.html; | |
| 24 | + | |
| 25 | +import org.ajax4jsf.renderkit.RendererBase; | |
| 26 | +import org.richfaces.component.UIFocusModifier; | |
| 27 | + | |
| 28 | +import javax.faces.component.UIComponent; | |
| 29 | + | |
| 30 | +public class HtmlFocusModifierRenderer extends RendererBase { | |
| 31 | + | |
| 32 | + protected Class<? extends UIComponent> getComponentClass() { | |
| 33 | + return UIFocusModifier.class; | |
| 34 | + } | |
| 35 | +} | ... | ... | 
| ... | ... | @@ -25,9 +25,10 @@ package org.richfaces.renderkit.html; | 
| 25 | 25 | import org.ajax4jsf.javascript.JSFunction; | 
| 26 | 26 | import org.ajax4jsf.javascript.JSFunctionDefinition; | 
| 27 | 27 | import org.ajax4jsf.renderkit.HeaderResourcesRendererBase; | 
| 28 | -import org.ajax4jsf.renderkit.RendererUtils.HTML; | |
| 28 | +import org.ajax4jsf.renderkit.RendererUtils; | |
| 29 | 29 | import org.ajax4jsf.resource.InternetResource; | 
| 30 | 30 | import org.richfaces.component.UIFocus; | 
| 31 | +import org.richfaces.component.UIFocusModifier; | |
| 31 | 32 | |
| 32 | 33 | import javax.faces.FacesException; | 
| 33 | 34 | import javax.faces.component.UIComponent; | 
| ... | ... | @@ -42,6 +43,7 @@ public class HtmlFocusRenderer extends HeaderResourcesRendererBase { | 
| 42 | 43 | getResource("/org/ajax4jsf/javascript/scripts/prototype.js"), | 
| 43 | 44 | getResource("/org/richfaces/renderkit/html/scripts/focus.js"), | 
| 44 | 45 | }; | 
| 46 | + | |
| 45 | 47 | private final InternetResource[] styles = {}; | 
| 46 | 48 | |
| 47 | 49 | // --------------------- GETTER / SETTER METHODS --------------------- | 
| ... | ... | @@ -69,37 +71,42 @@ public class HtmlFocusRenderer extends HeaderResourcesRendererBase { | 
| 69 | 71 | if (priority == null) { | 
| 70 | 72 | priority = uiFocus.getDefaultPriority(); | 
| 71 | 73 | } | 
| 72 | - | |
| 73 | - String sid = uiFocus.getForComponentId(); | |
| 74 | - String target; | |
| 75 | - if (sid != null && !"".equals(sid)) { | |
| 76 | - try { | |
| 77 | - UIComponent forcomp = getUtils().findComponentFor(component, sid); | |
| 78 | - if (forcomp != null) { | |
| 79 | - target = forcomp.getClientId(context); | |
| 74 | + String targetClientId = uiFocus.getTargetClientId(); | |
| 75 | + if (targetClientId == null || "".equals(targetClientId)) { | |
| 76 | + String targetComponentId = uiFocus.getTargetComponentId(); | |
| 77 | + String suffix = uiFocus.getSuffix(); | |
| 78 | + if (targetComponentId == null || "".equals(targetComponentId)) { | |
| 79 | + return; | |
| 80 | + } | |
| 81 | + UIComponent forcomp = getUtils().findComponentFor(component, targetComponentId); | |
| 82 | + if (forcomp == null) { | |
| 83 | + throw new FacesException("No component with id=" + targetComponentId + " found!"); | |
| 84 | + } | |
| 85 | + targetClientId = forcomp.getClientId(context); | |
| 86 | + UIFocusModifier modifier = findModifier(forcomp); | |
| 87 | + if (modifier != null) { | |
| 88 | + final String modifiedTargetClientId = modifier.getTargetClientId(); | |
| 89 | + if (modifiedTargetClientId != null && !modifiedTargetClientId.equals("")) { | |
| 90 | + targetClientId = modifiedTargetClientId; | |
| 80 | 91 | } else { | 
| 81 | - target = sid; | |
| 92 | + suffix = modifier.getSuffix(); | |
| 82 | 93 | } | 
| 83 | - } catch (IllegalArgumentException e) { | |
| 84 | - target = sid; | |
| 85 | 94 | } | 
| 86 | - String suffix = uiFocus.getSuffix(); | |
| 87 | 95 | if (suffix != null && !"".equals(suffix)) { | 
| 88 | - target += suffix; | |
| 96 | + targetClientId += suffix; | |
| 89 | 97 | } | 
| 90 | - } else { | |
| 91 | - target = component.getParent().getClientId(context); | |
| 92 | 98 | } | 
| 93 | - | |
| 94 | - | |
| 95 | - writer.startElement(HTML.SCRIPT_ELEM, null); | |
| 96 | - writer.writeAttribute(HTML.TYPE_ATTR, "text/javascript", "type"); | |
| 97 | - writer.writeAttribute(HTML.id_ATTRIBUTE, clientId, HTML.id_ATTRIBUTE); | |
| 99 | + if (targetClientId == null || targetClientId.equals("")) { | |
| 100 | + return; | |
| 101 | + } | |
| 102 | + writer.startElement(RendererUtils.HTML.SCRIPT_ELEM, null); | |
| 103 | + writer.writeAttribute(RendererUtils.HTML.TYPE_ATTR, "text/javascript", "type"); | |
| 104 | + writer.writeAttribute(RendererUtils.HTML.id_ATTRIBUTE, clientId, RendererUtils.HTML.id_ATTRIBUTE); | |
| 98 | 105 | if (UIFocus.TIMING_ON_LOAD.equals(uiFocus.getTiming())) { | 
| 99 | - writer.write(new JSFunction("Richfaces.FocusManager.setFocus", target, priority).toScript()); | |
| 106 | + writer.write(new JSFunction("Richfaces.FocusManager.setFocus", targetClientId, priority).toScript()); | |
| 100 | 107 | writer.write(";"); | 
| 101 | 108 | } else { | 
| 102 | - writer.write(new JSFunction("Richfaces.FocusManager.setFocus", target, priority, clientId, | |
| 109 | + writer.write(new JSFunction("Richfaces.FocusManager.setFocus", targetClientId, priority, clientId, | |
| 103 | 110 | uiFocus.getTiming()).toScript()); | 
| 104 | 111 | writer.write(";"); | 
| 105 | 112 | } | 
| ... | ... | @@ -109,7 +116,7 @@ public class HtmlFocusRenderer extends HeaderResourcesRendererBase { | 
| 109 | 116 | writer.write(definition.toScript()); | 
| 110 | 117 | writer.write(";"); | 
| 111 | 118 | } | 
| 112 | - writer.endElement(HTML.SCRIPT_ELEM); | |
| 119 | + writer.endElement(RendererUtils.HTML.SCRIPT_ELEM); | |
| 113 | 120 | } | 
| 114 | 121 | |
| 115 | 122 | private void checkValidity(String clientId, String name, String timing) { | 
| ... | ... | @@ -126,4 +133,20 @@ public class HtmlFocusRenderer extends HeaderResourcesRendererBase { | 
| 126 | 133 | protected Class<? extends UIComponent> getComponentClass() { | 
| 127 | 134 | return UIFocus.class; | 
| 128 | 135 | } | 
| 136 | + | |
| 137 | + private UIFocusModifier findModifier(UIComponent component) { | |
| 138 | + if (component instanceof UIFocusModifier) { | |
| 139 | + return (UIFocusModifier) component; | |
| 140 | + } | |
| 141 | + UIFocusModifier modifier = (UIFocusModifier) component.getFacet(UIFocus.FOCUS_MODIFIER_FACET_NAME); | |
| 142 | + if (modifier == null) { | |
| 143 | + for (UIComponent child : component.getChildren()) { | |
| 144 | + modifier = findModifier(child); | |
| 145 | + if (modifier != null) { | |
| 146 | + break; | |
| 147 | + } | |
| 148 | + } | |
| 149 | + } | |
| 150 | + return modifier; | |
| 151 | + } | |
| 129 | 152 | } | ... | ... | 
Please
register
or
login
to post a comment