luni, 20 aprilie 2015

[OmniFaces utilities (2.0)] Get the render IDs from the RichFaces PartialViewContext implementation (until RichFaces 4.5)


[OmniFaces utilities] The getRichFacesRenderIds() method returns the render IDs from the RichFaces PartialViewContext implementation. RichFaces PartialViewContext implementation does not have the getRenderIds() method properly implemented. So a hack wherin the exact name of the private field needs to be known has to be used to properly extract it from the RichFaces PartialViewContext implementation.

Method:
Usage:

If you read the documentation for PartialViewContext#getRenderIds() and you didn't understand exactly what it does, then here it is a quick overview. When we submit a form via an AJAX request (managed by JSF via PartialViewContext), the value of the render attribute it one of the reserved values (e.g. @form) and/or a list of clientIds separated by space. Practically, the value of the render attribute is available in the request parameters map under the javax.faces.partial.render parameter (or, PartialViewContext#PARTIAL_RENDER_PARAM_NAME), as in figure below:

<h:form id="loginFormId">             
 E-mail: <h:inputText id="emailId" value="#{loginBean.email}"/>               
 Info: <h:inputSecret id="passwordId" value="#{loginBean.password}"/>                                         
 <h:commandButton id="submitId" value="Login" action="#{loginBean.loginAction()}">       
  <f:ajax execute="@form" render="emailId passwordId"/>
 </h:commandButton>   
</h:form>
The loginFormId:emailId and loginFormId:passwordId are returned by the PartialViewContext#getRenderIds() in a Collection of Strings (see Ajax#getContext()):  

import org.omnifaces.util.Ajax;
import java.util.Collection;
...
PartialViewContext pvContext= Ajax.getContext();
// e.g. [loginFormId:emailId, loginFormId:passwordId]
Collection<String> renderIds = pvContext.getExecuteIds();

If you are curious to see how this method is implemented, then check below the Mojarra 2.2.9 implementation (the relevant code was highlighted):

// Mojarra 2.2.9 - PartialViewContextImpl
@Override
public Collection<String> getRenderIds() {
  assertNotReleased();
  if (renderIds != null) {
      return renderIds;
  }
  renderIds = populatePhaseClientIds(PARTIAL_RENDER_PARAM_NAME);
  return renderIds;
}

private List<String> populatePhaseClientIds(String parameterName) {

 Map<String,String> requestParamMap =
                    ctx.getExternalContext().getRequestParameterMap();
 String param = requestParamMap.get(parameterName);
 if (param == null) {
     return new ArrayList<String>();
 } else {
     Map<String, Object> appMap =
     FacesContext.getCurrentInstance().getExternalContext().getApplicationMap();
     String[] pcs = Util.split(appMap, param, "[ \t]+");
     return ((pcs != null && pcs.length != 0)
              ? new ArrayList<String>(Arrays.asList(pcs))
              : new ArrayList<String>());
 }
}

Now, in RichFaces (until version 4.5) this method is not properly implemented. So, OmniFaces comes with Hacks#getRichFacesRenderIds() which fixes the problems. This method can be invoked as below:

import org.omnifaces.util.Hacks;
import java.util.Collection;
...
Collection<String> renderIds = Hacks.getRichFacesRenderIds();

Niciun comentariu:

Trimiteți un comentariu