2

Primefaces 6.0. I understand that update attribute of p:remoteCommand should be used to specify clientIds of the components that should be updated by AJAX. I am trying to understand how PF works. In combination with DataTable it doesn't seem to work as expected. When I try to directly set update="form:dataTable:2:bColumn", it has no efect. However, doing this (commented out in the below code) RequestContext.getCurrentInstance().update("form:dataTable:2:bColumn"); will force PF to update the specified outputText.

Why is this happening? I will be happy for technical explanation - I am trying to find the answer by debugging PF Java/Javascript sources.

<h:form id="form">
    <p:remoteCommand name="remoteCall"
                     action="#{grid4.onEdit}"
                     update="form:dataTable:2:bColumn"
    />

    <p:dataTable id="dataTable"
                 var="gridItem"
                 value="#{grid4.gridItems}"
                 editable="true" editMode="cell"
    >

        <p:ajax event="cellEdit"
                oncomplete="remoteCall()">
        </p:ajax>

        <p:column headerText="A">
            <p:cellEditor>
                <f:facet name="output"><h:outputText value="#{gridItem.a}" /></f:facet>
                <f:facet name="input"><p:inputText value="#{gridItem.a}"/></f:facet>
            </p:cellEditor>
        </p:column>
        <p:column headerText="B">
            <h:outputText id="bColumn" value="#{gridItem.b}" />
        </p:column>
    </p:dataTable>

</h:form>

Bean

@ManagedBean
@ViewScoped
public class Grid4 {
    private List<GridItem> gridItems = new ArrayList<>();


    public Grid4() {
        gridItems.add(new GridItem("1", "a","b"));
        gridItems.add(new GridItem("2", "a","b"));
        gridItems.add(new GridItem("3", "a","b"));
    }

    public void onEdit() {
        System.out.println("onEdit()");
        gridItems.get(2).setB("CHANGED VALUE");
//        RequestContext.getCurrentInstance().update("form:dataTable:2:bColumn");
    }

    public List<GridItem> getGridItems() {
        return gridItems;
    }

    public void setGridItems(List<GridItem> gridItems) {
        this.gridItems = gridItems;
    }

}
Filip Nguyen
  • 1,029
  • 1
  • 7
  • 20

2 Answers2

3

basically jsf ids an client side ids are two different things (check this answer and this post for a better understanding).

When you use RequestContext.getCurrentInstance().update("form:dataTable:2:bColumn"); that method use the client id to find the components that have to be updated, but in the case of the update property of p:remoteCommand it is expecting a jsf id, not the generated client id, so that´s why your update doesn't work. However, primefaces support jquery selectors to update components, so you could use a client side id on an update property like this update="@(#yourElementId)"

Community
  • 1
  • 1
David Florez
  • 1,460
  • 2
  • 13
  • 26
0

Let me start by mentioning that this is not specific to the p:remoteCommand. The reason for the behaviour you notice is rather simple although not directly obvious maybe since it is unfortunately not in the PrimeFaces documentation.

The update attribute in:

<p:remoteCommand name="remoteCall"
                 action="#{grid4.onEdit}"
                 update="form:dataTable:2:bColumn"
/>

uses a relative path if it does not start with a : and since the p:remoteCommand is already in the naming container with id='form', the form in the update attribute is superfluous and even makes it not work (run your app in dev mode, add a messages tag and see the errors).

So

<p:remoteCommand name="remoteCall"
                 action="#{grid4.onEdit}"
                 update="dataTable:2:bColumn"
/>

Should work, as should

<p:remoteCommand name="remoteCall"
                 action="#{grid4.onEdit}"
                 update=":form:dataTable:2:bColumn"
/>

The

RequestContext.getCurrentInstance().update("form:dataTable:2:bColumn");

is always absolute, so the colon is not needed here and it will find the element starting from the root (form 'prefix' is needed then)

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
  • Solutions you provided don't work. After more debugging I found out that remoteCommand is being wrongly translated into HTML. In the generated HTML I can see remoteCall = function() {PrimeFaces.ab({s:"form:j_idt4",f:"form",u:"form:dataTable:bColumn",pa:arguments[0]});} . Note that row number is missing. After debugging the source code of PF, it looks like a bug. The code is generating this 'clientId' by looking up the component (output text field) first. But after it finds it, there is some side effect that nullifies the clientId field. – Filip Nguyen Feb 08 '17 at 18:30
  • 1
    That is a separte issue. The value of the update attribute in your question is wrong in the way I describe in my answer. – Kukeltje Feb 08 '17 at 19:04