0
votes

I'm a beginner in Oracle ADF Faces, before that. I have known Primefaces, I usually use @process and @update in commandLink and commandButton to process or update specify the place. ADF faces have made me confused cause when I created a commandLink (or link) it's will be processed all components inside the form

Here's an illustration Img Look at the picture. When I click " button ", it will process all form, but I just want to process " table " only and update "child_form_02". How can I do it in ADF Faces?

Thank in advance.

2
I'm not sure about it. Does Oracle support it by another way, not use f:ajax? Like the way Primefaces didTea
f:ajax is general JSF and can be used with any component frameworkJasper de Vries
I see, I will try itTea
I don't think use f:ajax is a way, 'cause my button inside so many components, about 15 components, I don't want to write too many id inside f:ajax ?Tea

2 Answers

0
votes

You can split your form into 2 subforms (af:subform) Please see an example below: http://www.oracle.com/technetwork/developer-tools/adf/learnmore/40-ppr-subform-169182.pdf

0
votes

As explained in the answer on Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes, you should use:

<h:commandButton ...>
  <f:ajax execute="childForm2:clientId1 childForm2:clientId2 ..."/>
</h:commandButton>

As you already mentioned, this might result in a painfully long and unmaintainable string. In PrimeFaces you could use @(...) to jQuery the inputs you want to process. In plain JSF there is no such thing.

What you could do is create a method in a utility bean which gets you all input clientIds within a specific component. The OmniFaces Components utility class comes in handy here:

public String inputClientIds(String clientId)
{
  UIComponent component = Components.findComponent(clientId);
  List<String> clientIds = new ArrayList<>();
  for (UIInput input : Components.findComponentsInChildren(component, UIInput.class)) {
    clientIds.add(input.getClientId());
  }
  return String.join(" ", clientIds);
}

Now you can use it in your XHTML like:

<h:commandButton ...>
  <f:ajax execute="#{ajaxBean.inputClientIds('childForm2')}"/>
</h:commandButton>

If you are looking for a pure JSF / non-OmniFaces solution, things will get a bit more verbose:

public String inputClientIds(String clientId)
{
  UIComponent component = FacesContext.getCurrentInstance().getViewRoot().findComponent(clientId);
  List<String> clientIds = new ArrayList<>();
  for (UIInput input : findChildsOfType(component, UIInput.class)) {
    clientIds.add(input.getClientId());
  }
  return String.join(" ", clientIds);
}


public static <C extends UIComponent> List<C>
findChildsOfType(UIComponent component,
                 Class<C> type)
{
  List<C> result = new ArrayList<>();
  findChildsOfType(component, type, result);
  return result;
}


private static <C extends UIComponent> void
findChildsOfType(UIComponent component,
                 Class<C> type,
                 List<C> result)
{
  for (UIComponent child : component.getChildren()) {
    if (type.isInstance(child)) {
      result.add(type.cast(child));
    }
    findChildsOfType(child, type, result);
  }
}

You might consider creating a class with some utility methods.