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
- focus.jspx
+ 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 extends UIComponent> 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