diff --git b/pom.xml a/pom.xml
new file mode 100644
index 0000000..d8e0ad9
--- /dev/null
+++ a/pom.xml
@@ -0,0 +1,44 @@
+
+
+ ui
+ org.richfaces.sandbox
+ 3.3.3.Final
+
+ 4.0.0
+ org.richfaces.sandbox.ui
+ focus
+ focus
+ 3.3.3.Final
+
+
+
+ org.richfaces.cdk
+ maven-cdk-plugin
+ 3.3.3.Final
+
+
+ generate-sources
+
+ generate
+
+
+
+
+
+ org.richfaces
+
+ focus
+
+
+
+
+
+
+
+
+ org.richfaces.framework
+ richfaces-impl
+ 3.3.3.Final
+
+
+
diff --git b/src/main/config/component/focus.xml a/src/main/config/component/focus.xml
new file mode 100644
index 0000000..e2da31c
--- /dev/null
+++ a/src/main/config/component/focus.xml
@@ -0,0 +1,59 @@
+
+
+
+
+ org.richfaces.Focus
+ org.richfaces.Focus
+ org.richfaces.component.html.HtmlFocus
+ org.richfaces.component.UIFocus
+
+
+
+
+ org.richfaces.FocusRenderer
+ focus.jspx
+
+
+ focus
+ org.richfaces.taglib.FocusTag
+
+ org.ajax4jsf.webapp.taglib.HtmlComponentTagBase
+
+
+ org.richfaces.taglib.HtmlFocusTagTest
+ org.ajax4jsf.tests.AbstractJspTestCase
+
+
+
+ &ui_component_attributes;
+
+ for
+ java.lang.String
+
+ Id of component that should be focused
+
+ ""
+
+
+ priority
+ java.lang.Integer
+
+ If there are more components requesting focus,
+ then component with lowest priority will be focused.
+
+
+
+ suffix
+ java.lang.String
+
+ Suffix added to clientId. Useful for focusing radio elements.
+ Example : suffix=":0" puts focus on first radio if target is
+ radio.
+
+ ""
+
+
+
diff --git b/src/main/java/org/richfaces/component/UIFocus.java a/src/main/java/org/richfaces/component/UIFocus.java
new file mode 100644
index 0000000..98ff150
--- /dev/null
+++ a/src/main/java/org/richfaces/component/UIFocus.java
@@ -0,0 +1,104 @@
+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;
+
+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 Integer getDefaultPriority() {
+ UIComponent parentForm = getParent();
+ while (parentForm != null && !(parentForm instanceof UIForm)) {
+ parentForm = parentForm.getParent();
+ }
+ if (parentForm != null) {
+ return getUIInputChildrenCount((UIForm) parentForm, getForComponentId());
+ } else {
+ return Integer.MAX_VALUE;
+ }
+ }
+
+ public String getForComponentId() {
+ String aFor = getFor();
+
+ if (aFor != null && !"".equals(aFor)) {
+ return aFor;
+ } else {
+ if (!(getParent() instanceof UIInput)) {
+ Set allowedClientIds = new HashSet();
+ Iterator clientIdsWithMessages = getFacesContext().getClientIdsWithMessages();
+ while (clientIdsWithMessages.hasNext()) {
+ allowedClientIds.add(clientIdsWithMessages.next());
+ }
+ UIComponent component = getFirstInput(getParentForm(this), allowedClientIds);
+ return component == null ? null : component.getId();
+ } else {
+ return getParent().getId();
+ }
+ }
+ }
+
+ private int getUIInputChildrenCount(UIComponent component, String breakOnId) {
+ int inputComponentsCount = 0;
+ for (UIComponent child : component.getChildren()) {
+ if (child.getId().equals(breakOnId)) {
+ break;
+ }
+ if (child instanceof UIInput) {
+ inputComponentsCount++;
+ } else {
+ int uIInputChildrenCount = getUIInputChildrenCount(child, breakOnId);
+ inputComponentsCount += uIInputChildrenCount;
+ }
+ }
+ return inputComponentsCount;
+ }
+
+ public abstract String getFor();
+
+ public abstract void setFor(String value);
+
+ public abstract String getSuffix();
+
+ public abstract void setSuffix(String value);
+
+ public abstract Integer getPriority();
+
+ public abstract void setPriority(Integer value);
+
+ private UIComponent getFirstInput(UIComponent parent, Set allowedClientIds) {
+ UIComponent input = null;
+ FacesContext facesContext = getFacesContext();
+ for (UIComponent child : parent.getChildren()) {
+ if (child instanceof UIInput && (allowedClientIds.size() == 0 || allowedClientIds.contains(child.getClientId(facesContext)))) {
+ return child;
+ } else {
+ input = getFirstInput(child, allowedClientIds);
+ if (input != null) {
+ break;
+ }
+ }
+ }
+ return input;
+ }
+
+ private UIForm getParentForm(UIComponent component) {
+ UIComponent parent = component.getParent();
+ if (parent == null) {
+ return null;
+ }
+ if (parent instanceof UIForm) {
+ return (UIForm) parent;
+ } else {
+ return getParentForm(parent);
+ }
+ }
+}
diff --git b/src/main/resources/org/richfaces/renderkit/html/scripts/focus.js a/src/main/resources/org/richfaces/renderkit/html/scripts/focus.js
new file mode 100644
index 0000000..4cce423
--- /dev/null
+++ a/src/main/resources/org/richfaces/renderkit/html/scripts/focus.js
@@ -0,0 +1,40 @@
+if (!window.Richfaces) window.Richfaces = {};
+
+Richfaces.FocusManager = (function(){
+
+ var m_focus;
+ var m_priority = 999999;
+ var eventAttached = false;
+
+ var attachEvent = function() {
+ if(!eventAttached) {
+ document.observe('dom:loaded',function(){
+ var element = $(m_focus);
+ element.focus();
+ element.select(element);
+ Richfaces.FocusManager.clearFocus();
+ });
+ }
+ eventAttached = true;
+ };
+
+ return {
+ getFocus : function() {
+ return m_focus;
+ },
+ setFocus : function(id,priority) {
+ if(priority == null) {
+ priority = 99999;
+ }
+ if(m_focus == null || priority < m_priority) {
+ m_focus = id;
+ m_priority = priority == null ? 0 : priority;
+ attachEvent();
+ }
+ },
+ clearFocus : function() {
+ m_focus = null;
+ m_priority = 999999;
+ }
+ };
+ })();
diff --git b/src/main/templates/focus.jspx a/src/main/templates/focus.jspx
new file mode 100644
index 0000000..2f8bc25
--- /dev/null
+++ a/src/main/templates/focus.jspx
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+ new org.ajax4jsf.javascript.PrototypeScript(),/org/richfaces/renderkit/html/scripts/focus.js
+
+
+
+
+
+
+