jsfprimefacesdatatableremotecommand

p:remoteCommand inside iterating component like p:dataTable only works for last row


i was trying to print the value entered in the inputText but it only shows 0 except for the last row it shows the right value! here's a minimal code (i didn't include all the fields and the getters/setters)

@ManagedBean(name="medicament")
@ViewScoped
public class MedicamentBean {
  private List<Medicament> medicaments;
  private String libelle;
  private int qte_vente;

  public void test() {
    System.out.println(this.qte_vente);
}
}

html:

<h:form>
<p:dataTable value ="#{medicament.medicaments}" var ="m">
   <p:column headerText="libelle">      
      <h:outputText value = "#{m.libelle}"/>
   </p:column>
<p:column headerText="qte">
    <h:inputText value ="#{medicament.qte_vente}" onkeyup="myCommand();"/>
    <p:remoteCommand name="myCommand" actionListener="#{medicament.test()}"  style="display: none;" 
 />
   </p:column>

</p:dataTable>
</h:form>

Solution

  • Open the webpage in webbrowser. Rightclick and choose View Page Source. Look carefully at the generated HTML output which you see there. When you have 10 table rows in e.g. p:datatable, it should look something like this

    <table>
        <tr><td><script>function myCommand() { /* ... */ }</script></td></tr>
        <tr><td><script>function myCommand() { /* ... */ }</script></td></tr>
        <tr><td><script>function myCommand() { /* ... */ }</script></td></tr>
        <tr><td><script>function myCommand() { /* ... */ }</script></td></tr>
        <tr><td><script>function myCommand() { /* ... */ }</script></td></tr>
        <tr><td><script>function myCommand() { /* ... */ }</script></td></tr>
        <tr><td><script>function myCommand() { /* ... */ }</script></td></tr>
        <tr><td><script>function myCommand() { /* ... */ }</script></td></tr>
        <tr><td><script>function myCommand() { /* ... */ }</script></td></tr>
        <tr><td><script>function myCommand() { /* ... */ }</script></td></tr>
    </table>
    

    (When you use a different iterating component like a p:datagrid or even something like a ui:repeat it looks different but the generic 'repeating' is the same)

    Guess which one gets invoked when you execute myCommand() in JavaScript ...

    Right, that just doesn't work.

    It would have worked with only one <p:remoteCommand> outside the <p:dataTable> to which you pass a parameter, which is a generic solution for all sorts of iterating components.

    But in your case you are in fact overcomplicating things. Just use <p:ajax> instead.

    <h:inputText ...>
        <p:ajax event="keyup" listener="#{medicament.test()}" />
    </h:inputText>
    

    That's all.