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

Mike Kienenberger commented on MYFACES-1277:
--------------------------------------------

Sorry.   I knew your name was Chad, but my fingers sometimes don't type what my 
mind tells them to :)


> 2. It has to do with UIComponent.clientId not neccissarily corresponding to 
> the generated HTML id of the control on the form.

I assume you mean inside a UIData control.   I can't remember if all of these 
bugs have been fixed yet, but I'm pretty sure that Martin has also addressed 
this with the UIComponentPerspective.executeOn().   JSF should allow you to get 
from an html id to a component: that's the entire purpose of clientId -- it's 
supposed to be the client's representation of the component. 

> 3. In order to dynamically focus a page with multiple buttons or links the 
> user is burdoned with writing server-side backing code to handle the focus 
> logic. 

I don't understand this statement.


I agree that what you're proposing and have implemented is better.

What I'd like to see is a way for it to work with a focus component instead of 
forcing the end-user to write javascript on their page.   There shouldn't be 
any reason why a component cannot generate the same javascript that you would 
need the end-user to write by hand.  If necessary, redesign the focus component 
from scratch if need be (it's in the sandbox, after all).

Just a suggestion, obviously, but the people most interested in using your code 
are already using the focus component.   Anyone else who's doing focusing 
without this component have already written their own javascript.

> 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

Reply via email to