Commit ef56792ca01e59ca247a50671301fe2c043345fd
1 parent
5422bcfa
Added timing and name attributes to focus component.
Showing
5 changed files
with
199 additions
and
70 deletions
| 1 | 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 | 4 | <components> | 
| 4 | 5 | <component> | 
| 5 | 6 | <name>org.richfaces.Focus</name> | 
| ... | ... | @@ -12,9 +13,9 @@ | 
| 12 | 13 | attribute. | 
| 13 | 14 | ]]> | 
| 14 | 15 | </description> | 
| 15 | - <renderer generate="true" override="true"> | |
| 16 | + <renderer generate="false" override="false"> | |
| 16 | 17 | <name>org.richfaces.FocusRenderer</name> | 
| 17 | - <template>focus.jspx</template> | |
| 18 | + <classname>org.richfaces.renderkit.html.HtmlFocusRenderer</classname> | |
| 18 | 19 | </renderer> | 
| 19 | 20 | <tag> | 
| 20 | 21 | <name>focus</name> | 
| ... | ... | @@ -26,9 +27,9 @@ | 
| 26 | 27 | <classname>org.richfaces.taglib.HtmlFocusTagTest</classname> | 
| 27 | 28 | <superclassname>org.ajax4jsf.tests.AbstractJspTestCase</superclassname> | 
| 28 | 29 | </test> | 
| 29 | - | |
| 30 | + | |
| 30 | 31 | </tag> | 
| 31 | - &ui_component_attributes; | |
| 32 | + &ui_component_attributes; | |
| 32 | 33 | <property> | 
| 33 | 34 | <name>for</name> | 
| 34 | 35 | <classname>java.lang.String</classname> | 
| ... | ... | @@ -55,5 +56,24 @@ | 
| 55 | 56 | </description> | 
| 56 | 57 | <defaultvalue>""</defaultvalue> | 
| 57 | 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 | 78 | </component> | 
| 59 | 79 | </components> | ... | ... | 
| 1 | 1 | package org.richfaces.component; | 
| 2 | 2 | |
| 3 | -import java.util.HashSet; | |
| 4 | -import java.util.Iterator; | |
| 5 | -import java.util.Set; | |
| 6 | 3 | import javax.faces.component.UIComponent; | 
| 7 | 4 | import javax.faces.component.UIComponentBase; | 
| 8 | 5 | import javax.faces.component.UIForm; | 
| 9 | 6 | import javax.faces.component.UIInput; | 
| 10 | 7 | import javax.faces.context.FacesContext; | 
| 8 | +import java.util.HashSet; | |
| 9 | +import java.util.Iterator; | |
| 10 | +import java.util.Set; | |
| 11 | 11 | |
| 12 | 12 | public abstract class UIFocus extends UIComponentBase { | 
| 13 | 13 | |
| 14 | 14 | public static final String COMPONENT_TYPE = "org.richfaces.Focus"; | 
| 15 | 15 | public static final String COMPONENT_FAMILY = "org.richfaces.Focus"; | 
| 16 | + public static final String TIMING_ON_LOAD = "onload"; | |
| 16 | 17 | |
| 17 | 18 | public Integer getDefaultPriority() { | 
| 18 | 19 | UIComponent parentForm = getParent(); | 
| ... | ... | @@ -20,7 +21,7 @@ public abstract class UIFocus extends UIComponentBase { | 
| 20 | 21 | parentForm = parentForm.getParent(); | 
| 21 | 22 | } | 
| 22 | 23 | if (parentForm != null) { | 
| 23 | - return getUIInputChildrenCount((UIForm) parentForm, getForComponentId()); | |
| 24 | + return getUIInputChildrenCount(parentForm, getForComponentId()); | |
| 24 | 25 | } else { | 
| 25 | 26 | return Integer.MAX_VALUE; | 
| 26 | 27 | } | 
| ... | ... | @@ -74,6 +75,14 @@ public abstract class UIFocus extends UIComponentBase { | 
| 74 | 75 | |
| 75 | 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 | 86 | private UIComponent getFirstInput(UIComponent parent, Set<String> allowedClientIds) { | 
| 78 | 87 | UIComponent input = null; | 
| 79 | 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 | 5 | var m_focus; | 
| 6 | 6 | var m_priority = 999999; | 
| 7 | 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 | 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 | 22 | if (element != null) { | 
| 16 | 23 | element.focus(); | 
| 17 | 24 | element.select(element); | 
| ... | ... | @@ -22,22 +29,38 @@ Richfaces.FocusManager = (function() { | 
| 22 | 29 | }; | 
| 23 | 30 | |
| 24 | 31 | document.observe('dom:loaded', function() { | 
| 25 | - focus(); | |
| 32 | + if (m_timing == TIMING_ON_LOAD) { | |
| 33 | + focus(null); | |
| 34 | + } | |
| 26 | 35 | m_domLoaded = true; | 
| 27 | 36 | }); | 
| 28 | 37 | |
| 29 | 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 | 46 | getFocus : function() { | 
| 31 | 47 | return m_focus; | 
| 32 | 48 | }, | 
| 33 | - setFocus : function(id, priority) { | |
| 49 | + setFocus : function(id, priority, focusComponentId, timing) { | |
| 34 | 50 | if (priority == null) { | 
| 35 | 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 | 59 | if (m_focus == null || priority < m_priority) { | 
| 38 | 60 | m_focus = id; | 
| 39 | 61 | m_priority = priority == null ? 0 : priority; | 
| 40 | - if (m_domLoaded) { | |
| 62 | + m_timing = timing; | |
| 63 | + if (m_domLoaded && timing == TIMING_ON_LOAD) { | |
| 41 | 64 | focus(); | 
| 42 | 65 | } | 
| 43 | 66 | } | 
| ... | ... | @@ -45,6 +68,7 @@ Richfaces.FocusManager = (function() { | 
| 45 | 68 | clearFocus : function() { | 
| 46 | 69 | m_focus = null; | 
| 47 | 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> | |
| \ No newline at end of file | 
Please
register
or
login
to post a comment