Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Datatable: CommandButton in datatable-header action called twice #3472

Closed
floriandulzky opened this issue Mar 12, 2018 · 12 comments
Closed

Datatable: CommandButton in datatable-header action called twice #3472

floriandulzky opened this issue Mar 12, 2018 · 12 comments
Labels
🐞 defect Bug...Something isn't working Resolution: Wontfix Issue will not be fixed due to technical limitations

Comments

@floriandulzky
Copy link
Contributor

1) Environment

  • PrimeFaces version: 6.1/6.2/6.3-SNAPSHOT
  • Does it work on the newest released PrimeFaces version? no
  • Does it work on the newest sources in GitHub? (Build by source) no
  • Application server + version: wildfly 11 / jetty
  • Affected browsers: chrome / Firefox / IE

2) Expected behavior

Action of a button in an datatable header should be called once.

3) Actual behavior

Action of a button in an datatable header will be called twice.

4) Steps to reproduce

checkout https://github.com/floriandulzky/primefaces-test
mvn jetty:run
http://localhost:8080/primefaces-test/test2.xhtml
click on the button in the header - the action will be called twice.
other buttons (not in the header) - action will be called once (same action).

5) Sample

https://github.com/floriandulzky/primefaces-test

testcase implementend in:
http://localhost:8080/primefaces-test/test2.xhtml

@tandraschko tandraschko added the 🐞 defect Bug...Something isn't working label Mar 12, 2018
@cnsgithub
Copy link
Contributor

This is some weird behavior. However, I think it is not a PrimeFaces bug.

The stack is the same on both calls:

	at org.primefaces.test.DatatableTestManagedBean.testAction(DatatableTestManagedBean.java:46)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at javax.el.BeanELResolver.invokeMethod(BeanELResolver.java:740)
	at javax.el.BeanELResolver.invoke(BeanELResolver.java:470)
	at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:257)
	at com.sun.el.parser.AstValue.invoke(AstValue.java:232)
	at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:302)
	at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
	at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
	at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
	at javax.faces.component.UICommand.broadcast(UICommand.java:315)
	at javax.faces.component.UIData.broadcast(UIData.java:1108)
	at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
	at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)

Workaround: add process="@this" to p:commandButton.

@floriandulzky
Copy link
Contributor Author

floriandulzky commented Mar 12, 2018

But in the second datatable (without primefaces) everything works fine.

<h:dataTable id="testtable1" value="#{datatabletest.customers}" var="customer" style="height: 50%;">
     <h:column headerText="Firstname" filterBy="#{customer.firstname}">
          <h:outputText value="#{customer.firstname}" />
     </h:column>
     <h:column headerText="Lastname" filterBy="#{customer.lastname}">
          <h:outputText value="#{customer.lastname}" />
     </h:column>
     <h:column>
          <f:facet name="header">
               <h:commandButton action="#{datatabletest.testAction()}" value="testAction"/>
          </f:facet>
          <p:outputPanel rendered="#{not empty customer}" required="false">
               <h:outputText value="#{customer.gender}"/>
          </p:outputPanel>
     </h:column>
</h:dataTable>

@cnsgithub
Copy link
Contributor

Ok, I didn't see that second table. You're right.

@cnsgithub
Copy link
Contributor

I think the problem is somehow related to the fact that there are two CommandButton instances with the same clientId each firing an ActionEvent.

image

image

As the DataTableRenderer is really complex someone more experienced should have a look at it.

@melloware
Copy link
Member

@mertsincan usually fixes most of the Datatable issues as it is quite complex at this point.

@cnsgithub
Copy link
Contributor

In the meanwhile you could use the workaround proposed in #3472 (comment)

@floriandulzky
Copy link
Contributor Author

I updatetd the test project.
I have removed pagination and scrollable, so the header will not be copied. And I have the same behavior as before.

@Hamsterbau
Copy link

Hamsterbau commented Mar 21, 2018

Workaround is not working, because of the called PrimeFaces method with the ID, which is not unique at this time:

PrimeFaces.ab({s:j_idt4:testtable:j_idt8});

...

PrimeFaces.ab({s:j_idt4:testtable:j_idt8});

I'm having the same problem with a selectbox, where the call looks a little bit different, but has the same problem:

PrimeFaces.ab({s:this,e:"valueChange",p:"myView:events:j_idt585",u:"myForm"});

...

PrimeFaces.ab({s:this,e:"valueChange",p:"myView:events:j_idt585",u:"myForm"});

The problem is that the selectionbox at the bottom is useless, because the only the first selectionbox on top is working.

Will this be fixed soon?

PS: In case of the RowsPerPageDropdown, this input has two different IDs (one for the header, and another one for the footer).

@mertsincan
Copy link
Member

mertsincan commented May 22, 2018

Could you please try this issue after removing binding="#{datatabletest.dataTable}" attribute from p:dataTable or adding binding="#{datatabletest.htmlDataTable}" attribute to h:dataTable?

For second suggestion(binding="#{datatabletest.htmlDataTable}");

private HtmlDataTable htmlDataTable; /* getter; setter */

They have similar behavior.

@floriandulzky
Copy link
Contributor Author

Without binding everything works fine.
But in my real application I need the databing. Also I would like to use primefaces features like filter and so on. Because of this I can't switch to h:dataTable.

@mertsincan
Copy link
Member

For this issue, you can use RequestScoped instead of ViewScoped for DatatableTestManagedBean
OR
DataTable datatable = FacesContext.getCurrentInstance().getViewRoot().findComponent("TABLE_CLIENTID") instead of binding="#{datatabletest.dataTable}"

Also, please see; https://myfaces.apache.org/orchestra/myfaces-orchestra-core/component-bindings.html

@tandraschko
Copy link
Member

yep, viewscoped bean binding is broken.

@tandraschko tandraschko added the Resolution: Wontfix Issue will not be fixed due to technical limitations label May 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐞 defect Bug...Something isn't working Resolution: Wontfix Issue will not be fixed due to technical limitations
Projects
None yet
Development

No branches or pull requests

6 participants