Commit ef56792ca01e59ca247a50671301fe2c043345fd
1 parent
5422bcfa
Added timing and name attributes to focus component.
Showing
5 changed files
with
199 additions
and
70 deletions
| 1 | <?xml version="1.0" encoding="UTF-8"?> | 1 | <?xml version="1.0" encoding="UTF-8"?> | 
| 2 | -<!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN" "http://labs.jboss.com/jbossrichfaces/component-config.dtd" > | 2 | +<!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN" | 
| 3 | + "http://labs.jboss.com/jbossrichfaces/component-config.dtd" > | ||
| 3 | <components> | 4 | <components> | 
| 4 | <component> | 5 | <component> | 
| 5 | <name>org.richfaces.Focus</name> | 6 | <name>org.richfaces.Focus</name> | 
| @@ -12,9 +13,9 @@ | @@ -12,9 +13,9 @@ | ||
| 12 | attribute. | 13 | attribute. | 
| 13 | ]]> | 14 | ]]> | 
| 14 | </description> | 15 | </description> | 
| 15 | - <renderer generate="true" override="true"> | 16 | + <renderer generate="false" override="false"> | 
| 16 | <name>org.richfaces.FocusRenderer</name> | 17 | <name>org.richfaces.FocusRenderer</name> | 
| 17 | - <template>focus.jspx</template> | 18 | + <classname>org.richfaces.renderkit.html.HtmlFocusRenderer</classname> | 
| 18 | </renderer> | 19 | </renderer> | 
| 19 | <tag> | 20 | <tag> | 
| 20 | <name>focus</name> | 21 | <name>focus</name> | 
| @@ -26,9 +27,9 @@ | @@ -26,9 +27,9 @@ | ||
| 26 | <classname>org.richfaces.taglib.HtmlFocusTagTest</classname> | 27 | <classname>org.richfaces.taglib.HtmlFocusTagTest</classname> | 
| 27 | <superclassname>org.ajax4jsf.tests.AbstractJspTestCase</superclassname> | 28 | <superclassname>org.ajax4jsf.tests.AbstractJspTestCase</superclassname> | 
| 28 | </test> | 29 | </test> | 
| 29 | - | 30 | + | 
| 30 | </tag> | 31 | </tag> | 
| 31 | - &ui_component_attributes; | 32 | + &ui_component_attributes; | 
| 32 | <property> | 33 | <property> | 
| 33 | <name>for</name> | 34 | <name>for</name> | 
| 34 | <classname>java.lang.String</classname> | 35 | <classname>java.lang.String</classname> | 
| @@ -55,5 +56,24 @@ | @@ -55,5 +56,24 @@ | ||
| 55 | </description> | 56 | </description> | 
| 56 | <defaultvalue>""</defaultvalue> | 57 | <defaultvalue>""</defaultvalue> | 
| 57 | </property> | 58 | </property> | 
| 59 | + <property> | ||
| 60 | + <name>timing</name> | ||
| 61 | + <classname>java.lang.String</classname> | ||
| 62 | + <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". | ||
| 66 | + </description> | ||
| 67 | + <defaultvalue>"onload"</defaultvalue> | ||
| 68 | + </property> | ||
| 69 | + <property> | ||
| 70 | + <name>name</name> | ||
| 71 | + <classname>java.lang.String</classname> | ||
| 72 | + <description> | ||
| 73 | + Name of JavaScript function generated to trigger focus. This is required if "timing" attribute | ||
| 74 | + is set to "onJScall". | ||
| 75 | + </description> | ||
| 76 | + <defaultvalue>null</defaultvalue> | ||
| 77 | + </property> | ||
| 58 | </component> | 78 | </component> | 
| 59 | </components> | 79 | </components> | 
| 1 | package org.richfaces.component; | 1 | package org.richfaces.component; | 
| 2 | 2 | ||
| 3 | -import java.util.HashSet; | ||
| 4 | -import java.util.Iterator; | ||
| 5 | -import java.util.Set; | ||
| 6 | import javax.faces.component.UIComponent; | 3 | import javax.faces.component.UIComponent; | 
| 7 | import javax.faces.component.UIComponentBase; | 4 | import javax.faces.component.UIComponentBase; | 
| 8 | import javax.faces.component.UIForm; | 5 | import javax.faces.component.UIForm; | 
| 9 | import javax.faces.component.UIInput; | 6 | import javax.faces.component.UIInput; | 
| 10 | import javax.faces.context.FacesContext; | 7 | import javax.faces.context.FacesContext; | 
| 8 | +import java.util.HashSet; | ||
| 9 | +import java.util.Iterator; | ||
| 10 | +import java.util.Set; | ||
| 11 | 11 | ||
| 12 | public abstract class UIFocus extends UIComponentBase { | 12 | public abstract class UIFocus extends UIComponentBase { | 
| 13 | 13 | ||
| 14 | public static final String COMPONENT_TYPE = "org.richfaces.Focus"; | 14 | public static final String COMPONENT_TYPE = "org.richfaces.Focus"; | 
| 15 | public static final String COMPONENT_FAMILY = "org.richfaces.Focus"; | 15 | public static final String COMPONENT_FAMILY = "org.richfaces.Focus"; | 
| 16 | + public static final String TIMING_ON_LOAD = "onload"; | ||
| 16 | 17 | ||
| 17 | public Integer getDefaultPriority() { | 18 | public Integer getDefaultPriority() { | 
| 18 | UIComponent parentForm = getParent(); | 19 | UIComponent parentForm = getParent(); | 
| @@ -20,7 +21,7 @@ public abstract class UIFocus extends UIComponentBase { | @@ -20,7 +21,7 @@ public abstract class UIFocus extends UIComponentBase { | ||
| 20 | parentForm = parentForm.getParent(); | 21 | parentForm = parentForm.getParent(); | 
| 21 | } | 22 | } | 
| 22 | if (parentForm != null) { | 23 | if (parentForm != null) { | 
| 23 | - return getUIInputChildrenCount((UIForm) parentForm, getForComponentId()); | 24 | + return getUIInputChildrenCount(parentForm, getForComponentId()); | 
| 24 | } else { | 25 | } else { | 
| 25 | return Integer.MAX_VALUE; | 26 | return Integer.MAX_VALUE; | 
| 26 | } | 27 | } | 
| @@ -74,6 +75,14 @@ public abstract class UIFocus extends UIComponentBase { | @@ -74,6 +75,14 @@ public abstract class UIFocus extends UIComponentBase { | ||
| 74 | 75 | ||
| 75 | public abstract void setPriority(Integer value); | 76 | public abstract void setPriority(Integer value); | 
| 76 | 77 | ||
| 78 | + public abstract String getTiming(); | ||
| 79 | + | ||
| 80 | + public abstract String getName(); | ||
| 81 | + | ||
| 82 | + public abstract void setName(String name); | ||
| 83 | + | ||
| 84 | + public abstract void setTiming(String timing); | ||
| 85 | + | ||
| 77 | private UIComponent getFirstInput(UIComponent parent, Set<String> allowedClientIds) { | 86 | private UIComponent getFirstInput(UIComponent parent, Set<String> allowedClientIds) { | 
| 78 | UIComponent input = null; | 87 | UIComponent input = null; | 
| 79 | FacesContext facesContext = getFacesContext(); | 88 | FacesContext facesContext = getFacesContext(); | 
| 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.javascript.JSFunction; | ||
| 26 | +import org.ajax4jsf.javascript.JSFunctionDefinition; | ||
| 27 | +import org.ajax4jsf.renderkit.HeaderResourcesRendererBase; | ||
| 28 | +import org.ajax4jsf.renderkit.RendererUtils.HTML; | ||
| 29 | +import org.ajax4jsf.resource.InternetResource; | ||
| 30 | +import org.richfaces.component.UIFocus; | ||
| 31 | + | ||
| 32 | +import javax.faces.FacesException; | ||
| 33 | +import javax.faces.component.UIComponent; | ||
| 34 | +import javax.faces.context.FacesContext; | ||
| 35 | +import javax.faces.context.ResponseWriter; | ||
| 36 | +import java.io.IOException; | ||
| 37 | + | ||
| 38 | +public class HtmlFocusRenderer extends HeaderResourcesRendererBase { | ||
| 39 | +// ------------------------------ FIELDS ------------------------------ | ||
| 40 | + | ||
| 41 | + private final InternetResource[] scripts = { | ||
| 42 | + getResource("/org/ajax4jsf/javascript/scripts/prototype.js"), | ||
| 43 | + getResource("/org/richfaces/renderkit/html/scripts/focus.js"), | ||
| 44 | + }; | ||
| 45 | + private final InternetResource[] styles = {}; | ||
| 46 | + | ||
| 47 | +// --------------------- GETTER / SETTER METHODS --------------------- | ||
| 48 | + | ||
| 49 | + @Override | ||
| 50 | + protected InternetResource[] getScripts() { | ||
| 51 | + return scripts; | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + @Override | ||
| 55 | + protected InternetResource[] getStyles() { | ||
| 56 | + return styles; | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + @Override | ||
| 60 | + protected void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent component) | ||
| 61 | + throws IOException { | ||
| 62 | + if (!(component instanceof UIFocus)) { | ||
| 63 | + return; | ||
| 64 | + } | ||
| 65 | + UIFocus uiFocus = (UIFocus) component; | ||
| 66 | + final String clientId = getUtils().clientId(context, component); | ||
| 67 | + checkValidity(clientId, uiFocus.getName(), uiFocus.getTiming()); | ||
| 68 | + Integer priority = uiFocus.getPriority(); | ||
| 69 | + if (priority == null) { | ||
| 70 | + priority = uiFocus.getDefaultPriority(); | ||
| 71 | + } | ||
| 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); | ||
| 80 | + } else { | ||
| 81 | + target = sid; | ||
| 82 | + } | ||
| 83 | + } catch (IllegalArgumentException e) { | ||
| 84 | + target = sid; | ||
| 85 | + } | ||
| 86 | + String suffix = uiFocus.getSuffix(); | ||
| 87 | + if (suffix != null && !"".equals(suffix)) { | ||
| 88 | + target += suffix; | ||
| 89 | + } | ||
| 90 | + } else { | ||
| 91 | + target = component.getParent().getClientId(context); | ||
| 92 | + } | ||
| 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); | ||
| 98 | + if (UIFocus.TIMING_ON_LOAD.equals(uiFocus.getTiming())) { | ||
| 99 | + writer.write(new JSFunction("Richfaces.FocusManager.setFocus", target, priority).toScript()); | ||
| 100 | + writer.write(";"); | ||
| 101 | + } else { | ||
| 102 | + writer.write(new JSFunction("Richfaces.FocusManager.setFocus", target, priority, clientId, | ||
| 103 | + uiFocus.getTiming()).toScript()); | ||
| 104 | + writer.write(";"); | ||
| 105 | + } | ||
| 106 | + if (uiFocus.getName() != null && !uiFocus.getName().trim().equals("")) { | ||
| 107 | + final JSFunctionDefinition definition = new JSFunctionDefinition().addToBody(new JSFunction("Richfaces.FocusManager.focusStored", clientId)); | ||
| 108 | + definition.setName(uiFocus.getName()); | ||
| 109 | + writer.write(definition.toScript()); | ||
| 110 | + writer.write(";"); | ||
| 111 | + } | ||
| 112 | + writer.endElement(HTML.SCRIPT_ELEM); | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + private void checkValidity(String clientId, String name, String timing) { | ||
| 116 | + if ((name == null || "".equals(name.trim())) && "onJScall".equals(timing)) { | ||
| 117 | + throw new FacesException( | ||
| 118 | + "The name attribute of the focus component (id='" + clientId + "') must be specified when timing attribute equals to 'onJScall'"); | ||
| 119 | + } | ||
| 120 | + if (name != null && !"".equals(name.trim()) && !"onJScall".equals(timing)) { | ||
| 121 | + throw new FacesException( | ||
| 122 | + "The timing attribute of the focus component (id='" + clientId + "') must be set to 'onJScall' when name attribute is specified"); | ||
| 123 | + } | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + protected Class<? extends UIComponent> getComponentClass() { | ||
| 127 | + return UIFocus.class; | ||
| 128 | + } | ||
| 129 | +} | 
| @@ -5,13 +5,20 @@ Richfaces.FocusManager = (function() { | @@ -5,13 +5,20 @@ Richfaces.FocusManager = (function() { | ||
| 5 | var m_focus; | 5 | var m_focus; | 
| 6 | var m_priority = 999999; | 6 | var m_priority = 999999; | 
| 7 | var m_domLoaded = false; | 7 | var m_domLoaded = false; | 
| 8 | + var m_timing = false; | ||
| 9 | + var m_focusStore = {}; | ||
| 10 | + /** Constants */ | ||
| 11 | + var TIMING_ON_JS_CALL = "onJScall"; | ||
| 12 | + var TIMING_ON_LOAD = "onload"; | ||
| 8 | 13 | ||
| 9 | - var focus = function() { | ||
| 10 | - if (m_focus == null) { | ||
| 11 | - return; | ||
| 12 | - } | 14 | + var focus = function(element) { | 
| 13 | try { | 15 | try { | 
| 14 | - var element = $(m_focus); | 16 | + if (element == null) { | 
| 17 | + if (m_focus == null) { | ||
| 18 | + return; | ||
| 19 | + } | ||
| 20 | + element = $(m_focus); | ||
| 21 | + } | ||
| 15 | if (element != null) { | 22 | if (element != null) { | 
| 16 | element.focus(); | 23 | element.focus(); | 
| 17 | element.select(element); | 24 | element.select(element); | 
| @@ -22,22 +29,38 @@ Richfaces.FocusManager = (function() { | @@ -22,22 +29,38 @@ Richfaces.FocusManager = (function() { | ||
| 22 | }; | 29 | }; | 
| 23 | 30 | ||
| 24 | document.observe('dom:loaded', function() { | 31 | document.observe('dom:loaded', function() { | 
| 25 | - focus(); | 32 | + if (m_timing == TIMING_ON_LOAD) { | 
| 33 | + focus(null); | ||
| 34 | + } | ||
| 26 | m_domLoaded = true; | 35 | m_domLoaded = true; | 
| 27 | }); | 36 | }); | 
| 28 | 37 | ||
| 29 | return { | 38 | return { | 
| 39 | + focus: focus, | ||
| 40 | + focusStored: function(focusComponentId) { | ||
| 41 | + var element = $(m_focusStore[focusComponentId]); | ||
| 42 | + if (element != null) { | ||
| 43 | + focus(element); | ||
| 44 | + } | ||
| 45 | + }, | ||
| 30 | getFocus : function() { | 46 | getFocus : function() { | 
| 31 | return m_focus; | 47 | return m_focus; | 
| 32 | }, | 48 | }, | 
| 33 | - setFocus : function(id, priority) { | 49 | + setFocus : function(id, priority, focusComponentId, timing) { | 
| 34 | if (priority == null) { | 50 | if (priority == null) { | 
| 35 | priority = 99999; | 51 | priority = 99999; | 
| 36 | } | 52 | } | 
| 53 | + if (timing != TIMING_ON_JS_CALL) { | ||
| 54 | + timing = TIMING_ON_LOAD; | ||
| 55 | + } | ||
| 56 | + if (focusComponentId != null) { | ||
| 57 | + m_focusStore[focusComponentId] = id; | ||
| 58 | + } | ||
| 37 | if (m_focus == null || priority < m_priority) { | 59 | if (m_focus == null || priority < m_priority) { | 
| 38 | m_focus = id; | 60 | m_focus = id; | 
| 39 | m_priority = priority == null ? 0 : priority; | 61 | m_priority = priority == null ? 0 : priority; | 
| 40 | - if (m_domLoaded) { | 62 | + m_timing = timing; | 
| 63 | + if (m_domLoaded && timing == TIMING_ON_LOAD) { | ||
| 41 | focus(); | 64 | focus(); | 
| 42 | } | 65 | } | 
| 43 | } | 66 | } | 
| @@ -45,6 +68,7 @@ Richfaces.FocusManager = (function() { | @@ -45,6 +68,7 @@ Richfaces.FocusManager = (function() { | ||
| 45 | clearFocus : function() { | 68 | clearFocus : function() { | 
| 46 | m_focus = null; | 69 | m_focus = null; | 
| 47 | m_priority = 999999; | 70 | m_priority = 999999; | 
| 71 | + m_timing = null; | ||
| 48 | } | 72 | } | 
| 49 | }; | 73 | }; | 
| 50 | })(); | 74 | })(); | 
src/main/templates/focus.jspx
deleted
100644 → 0
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | -<f:root | ||
| 3 | - xmlns:f="http://jsf.exadel.com/template" | ||
| 4 | - xmlns:vcp=" http://jsf.exadel.com/vcp" | ||
| 5 | - xmlns:ui=" http://jsf.exadel.com/ui" | ||
| 6 | - xmlns:x=" http://jsf.exadel.com/vcp" | ||
| 7 | - xmlns:u="http://jsf.exadel.com/util" | ||
| 8 | - xmlns:h="http://jsf.exadel.com/header" | ||
| 9 | - component="org.richfaces.component.UIFocus" | ||
| 10 | - baseclass="org.ajax4jsf.renderkit.HeaderResourcesRendererBase" | ||
| 11 | - class="org.richfaces.renderkit.html.FocusRenderer"> | ||
| 12 | - | ||
| 13 | - <f:clientid var="clientId"/> | ||
| 14 | - <c:set var="for" value="#{component.forComponentId}"/> | ||
| 15 | - <c:set var="priority" value="#{component.attributes['priority']}"/> | ||
| 16 | - <h:scripts>new org.ajax4jsf.javascript.PrototypeScript(),/org/richfaces/renderkit/html/scripts/focus.js</h:scripts> | ||
| 17 | - | ||
| 18 | - <jsp:scriptlet> | ||
| 19 | -<![CDATA[ | ||
| 20 | - Integer priority = (Integer)variables.getVariable("priority"); | ||
| 21 | - if(priority == null) { | ||
| 22 | - priority = component.getDefaultPriority(); | ||
| 23 | - } | ||
| 24 | - | ||
| 25 | - variables.setVariable("priority",priority); | ||
| 26 | - String sid = (String) variables.getVariable("for"); | ||
| 27 | - String target; | ||
| 28 | - if (sid != null && ! "".equals(sid)) { | ||
| 29 | - try { | ||
| 30 | - UIComponent forcomp = getUtils().findComponentFor((UIComponent)component,sid); | ||
| 31 | - if (forcomp != null) { | ||
| 32 | - target = forcomp.getClientId(context); | ||
| 33 | - } else { | ||
| 34 | - target = sid; | ||
| 35 | - } | ||
| 36 | - }catch(IllegalArgumentException e) { | ||
| 37 | - target = sid; | ||
| 38 | - } | ||
| 39 | - String suffix = component.getSuffix(); | ||
| 40 | - if(suffix != null && !"".equals(suffix)) { | ||
| 41 | - target += suffix; | ||
| 42 | - } | ||
| 43 | - } else { | ||
| 44 | - target = component.getParent().getClientId(context); | ||
| 45 | - } | ||
| 46 | - variables.setVariable("for",target); | ||
| 47 | -]]> | ||
| 48 | - </jsp:scriptlet> | ||
| 49 | - | ||
| 50 | - <script type="text/javascript"> | ||
| 51 | - Richfaces.FocusManager.setFocus("#{for}",#{priority}); | ||
| 52 | - </script> | ||
| 53 | -</f:root> | 
Please
register
or
login
to post a comment