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