Focus can not be set on a lot of PrimeFaces components

UI Components for JSF
Post Reply
User avatar
Oleg
Expert Member
Posts: 3805
Joined: 02 Oct 2009, 09:41
Location: Germany, Black Forest

28 Apr 2010, 10:21

PrimeFaces focus component is useless for some components like Calendar, Autocomplete, ... Input fields of such components have clientId with postfix, e.g. "calendarClientId_input". FocusRenderer is looking for clientId and try to set focus on HTML element with such Id, but it's mostly SPAN or DIV elements and not inputs.

Check: Try to set focus for (invalid) calendar. It never works.

I found a right solution (s. below example for encodeImplicitFocus in FocusRenderer). Important is to check whether the component satisfies INPUT selector. If yes - set the focus directly, if not - set the focus on the first focusable child.

Code: Select all

private static final String INPUT_SELECTOR =
    ":input:not(:button,:submit,:reset,:hidden,:disabled,[readonly='readonly'])";

protected void encodeImplicitFocus(FacesContext facesContext, Focus focus) throws IOException
{
   ResponseWriter writer = facesContext.getResponseWriter();

   if (isPostBack()) {
      String clientId = findFirstInvalidClientId(facesContext, focus);

      if (clientId != null) {
          String selector = ComponentUtils.escapeJQueryId(clientId);
	       writer.write("var invalidEl = jQuery(\"" + selector + "\");");
	       writer.write("if (invalidEl.is(\"" + INPUT_SELECTOR + "\")){invalidEl.focus();}");
	       writer.write("else {jQuery(\"" + selector + " " + INPUT_SELECTOR + ":first\").focus();}");
      } else {
         focusOnFirstFocusable(facesContext, focus, writer);
      }
   } else {
      focusOnFirstFocusable(facesContext, focus, writer);
   }
}

private void focusOnFirstFocusable(FacesContext facesContext, Focus focus, ResponseWriter writer) throws IOException
{
   String selector = INPUT_SELECTOR + ":first";

   if (focus.getContext() != null) {
      UIComponent context = focus.findComponent(focus.getContext());

      if (context == null) {
         throw new FacesException("Cannot find component " + focus.getContext() + " in view");
      } else {
	      selector = ComponentUtils.escapeJQueryId(context.getClientId(facesContext)) + " " + selector;
      }
   }

   writer.write("jQuery(document).ready(function(){jQuery(\"" + selector + "\").focus();});");
}
In addition you should introduce a new "forElement" attribute for explicit focus. You know what I mean :-)

I have created a issue http://code.google.com/p/primefaces/iss ... ail?id=781
PrimeFaces Cookbook (2. edition): http://ova2.github.io/primefaces-cookbook/ Learning Angular UI Development with PrimeNG: https://github.com/ova2/angular-develop ... th-primeng Blog: https://medium.com/@OlegVaraksin

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 48 guests