问题
I need to execute a call using Ajax, but first, I also have to make a validation on my backing bean's method. Based on a boolean returned by this method, the ajax call will be executed (returned true) or not (returned false, for example).
To be more specific and to give a touchable example, I am trying to open a dialog after I click on a button.
This is my .xhtml code:
<h:form id="tableVendasNaoPagas">
<p:dataTable value="#{relatorioVendaMB.vendasNaoPagas}" var="venda" rowKey="#{venda.codigo}" emptyMessage="Nenhuma venda encontrada" selection="#{relatorioVendaMB.vendasAPagar}">
<f:facet name="header">Tabela de Venda</f:facet>
<p:column selectionMode="multiple" style="width:16px;text-align:center"/>
<p:column headerText="Código" sortBy="#{venda.codigo}">
<h:outputText value="#{venda.codigo}"/>
</p:column>
<!--Other columns-->
<f:facet name="footer">
<p:commandButton id="btnAbreDialogEfetuarPagamento" value="Efetuar Pagamento" process="@form" update=":formConfirmarPagamento, :formAux:growlglobal, @this" oncomplete="if (#{relatorioVendaMB.abreDialogEfetuaPag()}) { PF('dialogConfirmarPagamento').show() }"/>
</f:facet>
</p:dataTable>
</h:form>
.
.
.
<h:form id="formConfirmarPagamento">
<p:dialog id="dialogConfirmarPagamento" ...>
</h:form>
.java:
public boolean abreDialogEfetuaPag () {
if (vendasAPagar == null || vendasAPagar.isEmpty()){
MensagensUtil.mensagemAviso("Atenção", "selecione ao menos uma venda");
return false;
} else {
return true;
}
}
The dialog should be displayed only if at least one item from the table has been selected (the list vendasAPagar is not empty).
The call to the method on the backing bean isn't required, but it would be convenient, because I could add a message to a <p:growl> and give a feedback to the user (Like here: MensagensUtil.mensagemAviso("Atenção", "selecione ao menos uma venda");)
I've tried many different approaches, but they didn't work either:
<p:commandButton id="btnAbreDialogEfetuarPagamento" value="Efetuar Pagamento">
<p:ajax process="@form" update=":formConfirmarPagamento, :formAux:growlglobal" disabled="#{!relatorioVendaMB.abreDialogEfetuaPag()}" oncomplete="PF('dialogConfirmarPagamento').show()"/>
</p:commandButton>
<p:commandButton id="btnAbreDialogEfetuarPagamento" value="Efetuar Pagamento" process="@form" update=":formConfirmarPagamento, :formAux:growlglobal, @this" oncomplete="#{not empty relatorioVendaMB.abreDialogEfetuaPag()} ? PF('dialogConfirmarPagamento').show() : return false"/>
...And many others. In some, the dialog would always be shown and the method would not be executed, in others the method would be executed but the dialog would never be shown...
Could someone give me a hint, a solution and, if possible, explain how Ajax works in this type of situation. Thanks in advance.
回答1:
Here is what we do...
First don't use a boolean use AJAX and JSF to your advantage instead.
In your JAVA code you can mark validationFailed if you do not want to show the dialog.
public void abreDialogEfetuaPag () {
if (vendasAPagar == null || vendasAPagar.isEmpty()){
MensagensUtil.mensagemAviso("Atenção", "selecione ao menos uma venda");
FacesContext.getCurrentInstance().validationFailed();
}
}
Have your button only show the dialog if validation did not fail. PrimeFaces hands back the value of that validationFailed flag in the "args" of every AJAX request.
<p:commandButton oncomplete="if (!args.validationFailed) PF('dialogConfirmarPagamento').show();" />
回答2:
You can enable the button already with the selection. The button now is only a click button without bean connection.
<p:datatable....
<p:ajax event="rowSelect" partialSubmit="true" process="@this" update="btnAbreDialogEfetuarPagamento" />
<p:commandButton id="btnAbreDialogEfetuarPagamento" rendered="#{relatorioVendaMB.abreDialogEfetuaPag()}" value="Efetuar Pagamento" type="button" onclick="PF('dialogConfirmarPagamento').show() }"/>
来源:https://stackoverflow.com/questions/51392946/how-to-execute-or-not-an-ajax-call-based-on-a-condition