You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by "Chad Lyon (JIRA)" <de...@myfaces.apache.org> on 2006/04/10 19:46:59 UTC

[jira] Updated: (MYFACES-1277) Auto-Focus functionality similar to Auto-Scroll. [PATCH]

     [ http://issues.apache.org/jira/browse/MYFACES-1277?page=all ]

Chad Lyon updated MYFACES-1277:
-------------------------------

    Status: Patch Available  (was: Open)

> Auto-Focus functionality similar to Auto-Scroll. [PATCH]
> --------------------------------------------------------
>
>          Key: MYFACES-1277
>          URL: http://issues.apache.org/jira/browse/MYFACES-1277
>      Project: MyFaces Core
>         Type: New Feature

>   Components: General
>     Reporter: Chad Lyon
>  Attachments: Myfaces_392980_AutoFocus.patch
>
> I have created the attached patch from revision 392980 to add the ability for the page to automatically return focus to the control (link, or button) that submitted the page.  This functionality mimics the auto-scroll functionality and is configurable VIA a similar context parameter in the deployment descriptor (org.apache.myfaces.AUTO_FOCUS).
> ---Begin Patch---
> Index: shared/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
> ===================================================================
> --- shared/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java	(revision 392980)
> +++ shared/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java	(working copy)
> @@ -56,16 +56,20 @@
>      private static final String  INIT_PARAM_AUTO_SCROLL = "org.apache.myfaces.AUTO_SCROLL";
>      private static final boolean INIT_PARAM_AUTO_SCROLL_DEFAULT = false;
>  
> +    private static final String  INIT_PARAM_AUTO_FOCUS = "org.apache.myfaces.AUTO_FOCUS";
> +    private static final boolean INIT_PARAM_AUTO_FOCUS_DEFAULT = false;
> +
>      private static final String INIT_PARAM_ADD_RESOURCE_CLASS = "org.apache.myfaces.ADD_RESOURCE_CLASS";
>      private static final String INIT_PARAM_ADD_RESOURCE_CLASS_DEFAULT = "org.apache.myfaces.renderkit.html.util.DefaultAddResource";
>  
>      private static final String  INIT_CHECK_EXTENSIONS_FILTER = "org.apache.myfaces.CHECK_EXTENSIONS_FILTER";
>      private static final boolean INIT_CHECK_EXTENSIONS_FILTER_DEFAULT = true;
> -    
> +
>      private boolean _prettyHtml;
>      private boolean _detectJavascript;
>      private boolean _allowJavascript;
>      private boolean _autoScroll;
> +    private boolean _autoFocus;
>      private String _addResourceClass;
>      private boolean _checkExtensionsFilter;
>  
> @@ -86,14 +90,16 @@
>                                                                    INIT_PARAM_DETECT_JAVASCRIPT_DEFAULT));
>          myfacesConfig.setAutoScroll(getBooleanInitParameter(extCtx, INIT_PARAM_AUTO_SCROLL,
>                                                              INIT_PARAM_AUTO_SCROLL_DEFAULT));
> +        myfacesConfig.setAutoFocus(getBooleanInitParameter(extCtx, INIT_PARAM_AUTO_FOCUS,
> +                INIT_PARAM_AUTO_FOCUS_DEFAULT));
>          myfacesConfig.setAddResourceClass(getStringInitParameter(extCtx, INIT_PARAM_ADD_RESOURCE_CLASS,
>                                                                   INIT_PARAM_ADD_RESOURCE_CLASS_DEFAULT));
>          myfacesConfig.setAddResourceClass(getStringInitParameter(extCtx, INIT_PARAM_ADD_RESOURCE_CLASS,
>                  INIT_PARAM_ADD_RESOURCE_CLASS_DEFAULT));
> -        
> +
>          myfacesConfig.setCheckExtensionsFilter(getBooleanInitParameter(extCtx, INIT_CHECK_EXTENSIONS_FILTER,
>          		INIT_CHECK_EXTENSIONS_FILTER_DEFAULT));
> -                
> +
>          return myfacesConfig;
>      }
>  
> @@ -183,6 +189,16 @@
>          _autoScroll = autoScroll;
>      }
>  
> +    public boolean isAutoFocus()
> +    {
> +        return _autoFocus;
> +    }
> +
> +    private void setAutoFocus(boolean autoFocus)
> +    {
> +        _autoFocus = autoFocus;
> +    }
> +
>      private void setAddResourceClass(String addResourceClass)
>      {
>          _addResourceClass = addResourceClass;
> @@ -211,7 +227,7 @@
>      }
>  
>      /**
> -     * Should the environment be checked so that the ExtensionsFilter will work properly. 
> +     * Should the environment be checked so that the ExtensionsFilter will work properly.
>       */
>  	public boolean isCheckExtensionsFilter()
>  	{
> Index: shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HTML.java
> ===================================================================
> --- shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HTML.java	(revision 392980)
> +++ shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HTML.java	(working copy)
> @@ -91,7 +91,7 @@
>      String STYLE_ATTR = "style";
>      String TITLE_ATTR = "title";
>      String STYLE_CLASS_ATTR = "styleClass"; //"class" cannot be used as property name
> -     
> +
>      String[] UNIVERSAL_ATTRIBUTES_WITHOUT_STYLE =
>      {
>          DIR_ATTR,
> Index: shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java
> ===================================================================
> --- shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java	(revision 392980)
> +++ shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java	(working copy)
> @@ -174,7 +174,7 @@
>      	}
>      	String formName = formInfo.getFormName();
>      	UIForm nestingForm = formInfo.getForm();
> -    	
> +
>          StringBuffer onClick = new StringBuffer();
>          String commandOnClick = (String)uiComponent.getAttributes().get(HTML.ONCLICK_ATTR);
>  
> @@ -192,6 +192,11 @@
>              org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils.appendAutoScrollAssignment(onClick, formName);
>          }
>  
> +        if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isAutoFocus())
> +        {
> +            org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils.appendAutoFocusAssignment(onClick, formName);
> +        }
> +
>          //add hidden field for the case there is no commandLink in the form
>          String hiddenFieldName = HtmlRendererUtils.getHiddenCommandLinkFieldName(formName);
>          addHiddenCommandParameter(facesContext, nestingForm, hiddenFieldName);
> Index: shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlFormRendererBase.java
> ===================================================================
> --- shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlFormRendererBase.java	(revision 392980)
> +++ shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlFormRendererBase.java	(working copy)
> @@ -89,7 +89,12 @@
>          {
>              org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils.renderAutoScrollHiddenInput(facesContext,writer);
>          }
> -        
> +
> +        if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isAutoFocus())
> +        {
> +            org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils.renderAutoFocusHiddenInput(facesContext,writer);
> +        }
> +
>          if(!facesContext.getApplication().getStateManager().isSavingStateInClient(facesContext))
>          {
>              writer.startElement(HTML.INPUT_ELEM, component);
> Index: shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java
> ===================================================================
> --- shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java	(revision 392980)
> +++ shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java	(working copy)
> @@ -238,6 +238,11 @@
>              org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils.appendAutoScrollAssignment(onClick, formName);
>          }
>  
> +        if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isAutoFocus())
> +        {
> +            org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils.appendAutoFocusAssignment(onClick, formName);
> +        }
> +
>          //add id parameter for decode
>          String hiddenFieldName = HtmlRendererUtils.getHiddenCommandLinkFieldName(formName);
>          onClick.append(jsForm);
> @@ -298,7 +303,7 @@
>      {
>      	return _ComponentUtils.findNestingForm(uiComponent, facesContext);
>      }
> -    
> +
>  	protected void addHiddenCommandParameter(FacesContext facesContext, UIForm nestingForm, String hiddenFieldName)
>  	{
>  		if (nestingForm != null)
> Index: shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/JavascriptUtils.java
> ===================================================================
> --- shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/JavascriptUtils.java	(revision 392980)
> +++ shared/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/JavascriptUtils.java	(working copy)
> @@ -47,6 +47,8 @@
>      private static final String AUTO_SCROLL_PARAM = "autoScroll";
>      private static final String AUTO_SCROLL_FUNCTION = "getScrolling()";
>  
> +    private static final String AUTO_FOCUS_PARAM = "autoFocus";
> +
>      private static final String OLD_VIEW_ID = JavascriptUtils.class + ".OLD_VIEW_ID";
>  
>  
> @@ -257,7 +259,7 @@
>      {
>      	session.setAttribute(JAVASCRIPT_DETECTED, Boolean.valueOf(value));
>      }
> -    
> +
>      public static boolean isJavascriptDetected(ExternalContext externalContext)
>      {
>          //TODO/FIXME (manolito): This info should be better stored in the viewroot component and not in the session
> @@ -278,6 +280,17 @@
>      }
>  
>      /**
> +     * Adds the hidden form input value assignment that is necessary for the autofocus
> +     * feature to an html link or button onclick attribute.
> +     */
> +    public static void appendAutoFocusAssignment(StringBuffer onClickValue, String formName)
> +    {
> +        onClickValue.append("document.forms['").append(formName).append("']");
> +        onClickValue.append(".elements['").append(AUTO_FOCUS_PARAM).append("']");
> +        onClickValue.append(".value=this.id;");
> +    }
> +
> +    /**
>       * Renders the hidden form input that is necessary for the autoscroll feature.
>       */
>      public static void renderAutoScrollHiddenInput(FacesContext facesContext, ResponseWriter writer) throws IOException
> @@ -291,6 +304,19 @@
>      }
>  
>      /**
> +     * Renders the hidden form input that is necessary for the autofocus feature.
> +     */
> +    public static void renderAutoFocusHiddenInput(FacesContext facesContext, ResponseWriter writer) throws IOException
> +    {
> +        org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils.writePrettyLineSeparator(facesContext);
> +        writer.startElement(org.apache.myfaces.shared.renderkit.html.HTML.INPUT_ELEM, null);
> +        writer.writeAttribute(org.apache.myfaces.shared.renderkit.html.HTML.TYPE_ATTR, "hidden", null);
> +        writer.writeAttribute(org.apache.myfaces.shared.renderkit.html.HTML.NAME_ATTR, AUTO_FOCUS_PARAM, null);
> +        writer.endElement(org.apache.myfaces.shared.renderkit.html.HTML.INPUT_ELEM);
> +        org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils.writePrettyLineSeparator(facesContext);
> +    }
> +
> +    /**
>       * Renders the autoscroll javascript function.
>       */
>      public static void renderAutoScrollFunction(FacesContext facesContext,
> @@ -318,6 +344,7 @@
>                      "    }\n" +
>                      "    return x + \",\" + y;\n" +
>                       "}\n");
> +
>          ExternalContext externalContext = facesContext.getExternalContext();
>          String oldViewId = getOldViewId(externalContext);
>          if (oldViewId != null && oldViewId.equals(facesContext.getViewRoot().getViewId()))
> @@ -342,12 +369,21 @@
>                  }
>                  script.append("window.scrollTo(").append(x).append(",").append(y).append(");\n");
>              }
> +
> +            // now focus the control that had focus before.
> +            String focus = (String)externalContext.getRequestParameterMap().get(AUTO_FOCUS_PARAM);
> +            if (focus != null && focus.length() > 0)
> +            {
> +                script.append("\nif(document.getElementById('" + focus + "') != null) {\n" +
> +                				   "document.getElementById('" + focus + "').focus();\n" +
> +                				   "}\n");
> +            }
>          }
>  
>          writer.writeText(script.toString(),null);
>  
>          writer.endElement(org.apache.myfaces.shared.renderkit.html.HTML.SCRIPT_ELEM);
> -        HtmlRendererUtils.writePrettyLineSeparator(facesContext);        
> +        HtmlRendererUtils.writePrettyLineSeparator(facesContext);
>      }
> ---End Patch---
> Additionally, if anyone would like their page to return focus and scroll to other controls (inputText, selectOneMenu, etc) on value change then add the following javascript to your page:
> function setScrolling(component) {
> 	if(component.form.elements['autoScroll'] != null)
> 	{
> 		component.form.elements['autoScroll'].value=getScrolling();
> 	}
> 	if(component.form.elements['autoFocus'] != null)
> 	{
> 		component.form.elements['autoFocus'].value=component.id;
> 	}
> }
> And to your controls onchange attributes:
> onchange="setScrolling(this);submit()"
> For example:
> <h:selectOneMenu id="state" immediate="true"
> 	onchange="setScrolling(this);submit()"
> 	value="#{someBean.state}"
> 	valueChangeListener="#{someBean.stateChangeListener}">
> 	<f:selectItems value="#{someBean.stateOptions}" /> </h:selectOneMenu>

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira