From ef56792ca01e59ca247a50671301fe2c043345fd Mon Sep 17 00:00:00 2001 From: Bernard Labno Date: Wed, 16 Mar 2011 10:56:30 +0000 Subject: [PATCH] Added timing and name attributes to focus component. --- src/main/config/component/focus.xml | 30 +++++++++++++++++++++++++----- src/main/java/org/richfaces/component/UIFocus.java | 17 +++++++++++++---- src/main/java/org/richfaces/renderkit/html/HtmlFocusRenderer.java | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/resources/org/richfaces/renderkit/html/scripts/focus.js | 40 ++++++++++++++++++++++++++++++++-------- src/main/templates/focus.jspx | 53 ----------------------------------------------------- 5 files changed, 199 insertions(+), 70 deletions(-) create mode 100644 src/main/java/org/richfaces/renderkit/html/HtmlFocusRenderer.java delete mode 100644 src/main/templates/focus.jspx diff --git a/src/main/config/component/focus.xml b/src/main/config/component/focus.xml index e2da31c..9c86f3b 100644 --- a/src/main/config/component/focus.xml +++ b/src/main/config/component/focus.xml @@ -1,5 +1,6 @@ - + org.richfaces.Focus @@ -12,9 +13,9 @@ attribute. ]]> - + org.richfaces.FocusRenderer - + org.richfaces.renderkit.html.HtmlFocusRenderer focus @@ -26,9 +27,9 @@ org.richfaces.taglib.HtmlFocusTagTest org.ajax4jsf.tests.AbstractJspTestCase - + - &ui_component_attributes; + &ui_component_attributes; for java.lang.String @@ -55,5 +56,24 @@ "" + + timing + java.lang.String + + Moment when focus should be put. The possible values are "onJScall" and "onload". + If "onJScall" is used then you must manually call Richfaces.FocusManager.focus(). + The default value is "onload". + + "onload" + + + name + java.lang.String + + Name of JavaScript function generated to trigger focus. This is required if "timing" attribute + is set to "onJScall". + + null + diff --git a/src/main/java/org/richfaces/component/UIFocus.java b/src/main/java/org/richfaces/component/UIFocus.java index 98ff150..7701941 100644 --- a/src/main/java/org/richfaces/component/UIFocus.java +++ b/src/main/java/org/richfaces/component/UIFocus.java @@ -1,18 +1,19 @@ package org.richfaces.component; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; import javax.faces.component.UIComponent; import javax.faces.component.UIComponentBase; import javax.faces.component.UIForm; import javax.faces.component.UIInput; import javax.faces.context.FacesContext; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; public abstract class UIFocus extends UIComponentBase { public static final String COMPONENT_TYPE = "org.richfaces.Focus"; public static final String COMPONENT_FAMILY = "org.richfaces.Focus"; + public static final String TIMING_ON_LOAD = "onload"; public Integer getDefaultPriority() { UIComponent parentForm = getParent(); @@ -20,7 +21,7 @@ public abstract class UIFocus extends UIComponentBase { parentForm = parentForm.getParent(); } if (parentForm != null) { - return getUIInputChildrenCount((UIForm) parentForm, getForComponentId()); + return getUIInputChildrenCount(parentForm, getForComponentId()); } else { return Integer.MAX_VALUE; } @@ -74,6 +75,14 @@ public abstract class UIFocus extends UIComponentBase { public abstract void setPriority(Integer value); + public abstract String getTiming(); + + public abstract String getName(); + + public abstract void setName(String name); + + public abstract void setTiming(String timing); + private UIComponent getFirstInput(UIComponent parent, Set allowedClientIds) { UIComponent input = null; FacesContext facesContext = getFacesContext(); diff --git a/src/main/java/org/richfaces/renderkit/html/HtmlFocusRenderer.java b/src/main/java/org/richfaces/renderkit/html/HtmlFocusRenderer.java new file mode 100644 index 0000000..bc63b0a --- /dev/null +++ b/src/main/java/org/richfaces/renderkit/html/HtmlFocusRenderer.java @@ -0,0 +1,129 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright , Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.richfaces.renderkit.html; + +import org.ajax4jsf.javascript.JSFunction; +import org.ajax4jsf.javascript.JSFunctionDefinition; +import org.ajax4jsf.renderkit.HeaderResourcesRendererBase; +import org.ajax4jsf.renderkit.RendererUtils.HTML; +import org.ajax4jsf.resource.InternetResource; +import org.richfaces.component.UIFocus; + +import javax.faces.FacesException; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.context.ResponseWriter; +import java.io.IOException; + +public class HtmlFocusRenderer extends HeaderResourcesRendererBase { +// ------------------------------ FIELDS ------------------------------ + + private final InternetResource[] scripts = { + getResource("/org/ajax4jsf/javascript/scripts/prototype.js"), + getResource("/org/richfaces/renderkit/html/scripts/focus.js"), + }; + private final InternetResource[] styles = {}; + +// --------------------- GETTER / SETTER METHODS --------------------- + + @Override + protected InternetResource[] getScripts() { + return scripts; + } + + @Override + protected InternetResource[] getStyles() { + return styles; + } + + @Override + protected void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent component) + throws IOException { + if (!(component instanceof UIFocus)) { + return; + } + UIFocus uiFocus = (UIFocus) component; + final String clientId = getUtils().clientId(context, component); + checkValidity(clientId, uiFocus.getName(), uiFocus.getTiming()); + Integer priority = uiFocus.getPriority(); + if (priority == null) { + priority = uiFocus.getDefaultPriority(); + } + + String sid = uiFocus.getForComponentId(); + String target; + if (sid != null && !"".equals(sid)) { + try { + UIComponent forcomp = getUtils().findComponentFor(component, sid); + if (forcomp != null) { + target = forcomp.getClientId(context); + } else { + target = sid; + } + } catch (IllegalArgumentException e) { + target = sid; + } + String suffix = uiFocus.getSuffix(); + if (suffix != null && !"".equals(suffix)) { + target += suffix; + } + } else { + target = component.getParent().getClientId(context); + } + + + writer.startElement(HTML.SCRIPT_ELEM, null); + writer.writeAttribute(HTML.TYPE_ATTR, "text/javascript", "type"); + writer.writeAttribute(HTML.id_ATTRIBUTE, clientId, HTML.id_ATTRIBUTE); + if (UIFocus.TIMING_ON_LOAD.equals(uiFocus.getTiming())) { + writer.write(new JSFunction("Richfaces.FocusManager.setFocus", target, priority).toScript()); + writer.write(";"); + } else { + writer.write(new JSFunction("Richfaces.FocusManager.setFocus", target, priority, clientId, + uiFocus.getTiming()).toScript()); + writer.write(";"); + } + if (uiFocus.getName() != null && !uiFocus.getName().trim().equals("")) { + final JSFunctionDefinition definition = new JSFunctionDefinition().addToBody(new JSFunction("Richfaces.FocusManager.focusStored", clientId)); + definition.setName(uiFocus.getName()); + writer.write(definition.toScript()); + writer.write(";"); + } + writer.endElement(HTML.SCRIPT_ELEM); + } + + private void checkValidity(String clientId, String name, String timing) { + if ((name == null || "".equals(name.trim())) && "onJScall".equals(timing)) { + throw new FacesException( + "The name attribute of the focus component (id='" + clientId + "') must be specified when timing attribute equals to 'onJScall'"); + } + if (name != null && !"".equals(name.trim()) && !"onJScall".equals(timing)) { + throw new FacesException( + "The timing attribute of the focus component (id='" + clientId + "') must be set to 'onJScall' when name attribute is specified"); + } + } + + protected Class getComponentClass() { + return UIFocus.class; + } +} diff --git a/src/main/resources/org/richfaces/renderkit/html/scripts/focus.js b/src/main/resources/org/richfaces/renderkit/html/scripts/focus.js index 4b94291..53c1f6e 100644 --- a/src/main/resources/org/richfaces/renderkit/html/scripts/focus.js +++ b/src/main/resources/org/richfaces/renderkit/html/scripts/focus.js @@ -5,13 +5,20 @@ Richfaces.FocusManager = (function() { var m_focus; var m_priority = 999999; var m_domLoaded = false; + var m_timing = false; + var m_focusStore = {}; + /** Constants */ + var TIMING_ON_JS_CALL = "onJScall"; + var TIMING_ON_LOAD = "onload"; - var focus = function() { - if (m_focus == null) { - return; - } + var focus = function(element) { try { - var element = $(m_focus); + if (element == null) { + if (m_focus == null) { + return; + } + element = $(m_focus); + } if (element != null) { element.focus(); element.select(element); @@ -22,22 +29,38 @@ Richfaces.FocusManager = (function() { }; document.observe('dom:loaded', function() { - focus(); + if (m_timing == TIMING_ON_LOAD) { + focus(null); + } m_domLoaded = true; }); return { + focus: focus, + focusStored: function(focusComponentId) { + var element = $(m_focusStore[focusComponentId]); + if (element != null) { + focus(element); + } + }, getFocus : function() { return m_focus; }, - setFocus : function(id, priority) { + setFocus : function(id, priority, focusComponentId, timing) { if (priority == null) { priority = 99999; } + if (timing != TIMING_ON_JS_CALL) { + timing = TIMING_ON_LOAD; + } + if (focusComponentId != null) { + m_focusStore[focusComponentId] = id; + } if (m_focus == null || priority < m_priority) { m_focus = id; m_priority = priority == null ? 0 : priority; - if (m_domLoaded) { + m_timing = timing; + if (m_domLoaded && timing == TIMING_ON_LOAD) { focus(); } } @@ -45,6 +68,7 @@ Richfaces.FocusManager = (function() { clearFocus : function() { m_focus = null; m_priority = 999999; + m_timing = null; } }; })(); diff --git a/src/main/templates/focus.jspx b/src/main/templates/focus.jspx deleted file mode 100644 index dd6e379..0000000 --- a/src/main/templates/focus.jspx +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - new org.ajax4jsf.javascript.PrototypeScript(),/org/richfaces/renderkit/html/scripts/focus.js - - - - - - - \ No newline at end of file -- libgit2 0.24.0