Toggle p:fieldset from another button - jsf

I want to expand/collapse a fieldset from buttons that are outside and inside of the fieldset, The problem is that not always the effect is the desired one. Some times the fieldset expands and collapses in a blink of an eye, sometimes it remains always open. However if a click in another button wich is not related with the fieldset, it seems that "reset" the state, and buttons starts to work fine for a while, till , for example, when the form validation fails.
Here is the whole XHTML.
I suspect this is because any AJAX issue
Thanks very much in advance
<p:fieldset id="fs_new_po"
widgetVar="fs_new_po"
legend="#{msg['btn_add_po.manage_po']}"
toggleable="true"
toggleSpeed="500"
collapsed="true">
....
<p:column>
<p:commandButton process="#this"
update=":mng_po:fs_new_po :mng_po:msgs"
value="#{msg['btnCancel']}"
onclick="PF('fs_new_po').toggle();"
actionListener="#{managePO.btnCancelClick}"/>
</p:column>
</p:row>
</p:panelGrid>
</p:fieldset>
...
<p:commandButton process="#this"
update=":mng_po:fs_new_po"
oncomplete="PF('fs_new_po').toggle();"
icon="ui-icon-pencil"
title="edit"
action="#{managePO.btnEditClick}">
<f:setPropertyActionListener value="#{po}" target="#{managePO.selectedPo}"/>
</p:commandButton>

Following the suggestion of Tiny, I update onclick event just the content of the fieldset that could be change.
<p:fieldset id="fs_new_po"
widgetVar="fs_new_po"
legend="#{msg['btn_add_po.manage_po']}"
toggleable="true"
toggleSpeed="500"
collapsed="true">
//ADDED A CONTENT INSIDE THE FIELDSET TO BE UPDATED
<p:panelGrid id="fs_cntnt">
....
<p:column>
//UPDATE JUST THE CONTENT OF THE FIELDSET
<p:commandButton process="#this" update=":mng_po:fs_cntnt :mng_po:msgs" value="# {msg['btnCancel']}" onclick="PF('fs_new_po').toggle();" actionListener="#{managePO.btnCancelClick}" />
</p:column>
</p:row>
</p:panelGrid>
</p:fieldset>
...
//UPDATE JUST THE CONTENT OF THE FIELDSET
<p:commandButton process="#this" update=":mng_po:fs_cntnt" oncomplete="PF('fs_new_po').toggle();" icon="ui-icon-pencil" title="edit" action="#{managePO.btnEditClick}" >
<f:setPropertyActionListener value="#{po}" target="#{managePO.selectedPo}" />
</p:commandButton>
Thank you Tiny!

Related

p:dataGrid content disappears after ajax update

I got a little problem with p:ajax update here. After closing p:panel or checking checkbox or adding answer i'm ajax-updating ans-data-grid as you can see in the code. But it works only for add answer button. When i close panel or click checkbox content of p:datagrid dissapears. It's still there but it is not visible and whole datagrid is 0px high. So my question is, Is there a difference between update from p:commandButton and p:ajax, and if yes how can i update this datagrid properly?
<p:panel id="edit_ans_panel" styleClass="edit-ans-panel" visible="#{editorBean.question.qtype != 2}">
<p:dataGrid rowIndexVar="rowIndex" var="answer" value="#{editorBean.question.answers}" columns="1" id="ans_data_grid">
<p:panel header="Answer" styleClass="QApanel" closable="#{editorBean.closableAns}" toggleable="true">
<p:ajax event="close" update="ans_data_grid" listener="#{editorBean.onAnswerRemoved(answer)}" />
<p:panelGrid columnClasses="anscol1,anscol2,anscol3" columns="3" layout="grid" styleClass="QAgrid">
<p:inputTextarea placeholder="enclose LaTeX expression in $ to be processed" id="editor_input_#{answer.id_answer}" styleClass="editor-input" minQueryLength="2" value="#{answer.text}" />
<h:outputText id="editor_output_#{answer.id_answer}" styleClass="editor-output" value="#{answer.text}"/>
<p:column>
<p:panel id="edit_ans_corr_chkbx" styleClass="edit-ans-corr-chkbx" visible="#{editorBean.question.qtype != 3}">
<h:outputText value="Correct: " />
<p:selectBooleanCheckbox id="is_true_#{answer.id_answer}" value="#{answer.is_true}" >
<p:ajax update="ans_data_grid" listener="#{editorBean.ansChecked(answer)}" />
</p:selectBooleanCheckbox>
</p:panel>
</p:column>
</p:panelGrid>
</p:panel>
</p:dataGrid>
<p:commandButton id="add_ans_btn" value="Add Answer" styleClass="add-ans-btn" action="#{editorBean.addAnswer()}" update="ans_data_grid"/>
</p:panel>
\edit
For some reason p:panel with .QApanel class gets .ui-helper-hidden class after update where is display:none.

Primefaces datatable update datatable

I have a problem with primefaces datatables. I have one datatable with some entries and a column with a button inside. If the button is pressed a popup is opened with another datatable. The entries in the second datatable are depending on the row in which the button is pressed.
<!-- first datatable -->
<h:form id="list">
<p:dataTable id="list1" var="item" value="#{bean1.itemlist}"
rowKey="#{item.id}" selection="#{bean1.selectedItem}"
selectionMode="single">
<p:column headerText="ID">
<h:outputText value="#{item.id}" />
</p:column>
...
<p:column headerText="Edit Entries">
<p:commandButton value="Edit Entries"
actionListener="#{bean2.updateEntries(item)}" ajax="true"
oncomplete="PF('edit_entries').show()" />
</p:column>
</p:dataTable>
<!-- Second datatable in the popup -->
<p:dialog header="Edit Entries" widgetVar="edit_entries" modal="true"
resizable="false">
<p:dataTable id="list2" var="entry"
value="#{bean2.entriesList}" rowKey="#{entry.id}"
selection="#{bean2.selectedEntry}" selectionMode="single">
<p:column headerText="Entry Number">
<h:outputText value="#{entry.number}" />
</p:column>
</p:dataTable>
<f:facet name="footer">
<p:commandButton value="Save" oncomplete="PF('edit_entries').hide()" />
</f:facet>
</p:dialog>
</form>
Bean2
public void updateEntries(Item selectedItem) {
this.entriesList = this.entriesQuery.getAllEntriesByItemID(selectedItem.getId());//db query could take some time
System.out.println("entrieslist size: " + this.entriesList.size()); //prints the correct size
}
The problem is that there are no entries listed in the popup datatable although there are some in the list after the db query.
Any ideas how to fix this bug?
Thanks in advance!
UPDATE 1:
<!-- first datatable -->
<h:form id="list">
<p:dataTable id="list1" var="item" value="#{bean1.itemlist}"
rowKey="#{item.id}" selection="#{bean1.selectedItem}"
selectionMode="single">
<p:column headerText="ID">
<h:outputText value="#{item.id}" />
</p:column>
...
<p:column headerText="Edit Entries">
<p:commandButton value="Edit Entries" update=":dialogUpdateEntries"
actionListener="#{bean2.updateEntries(item)}" ajax="true"
oncomplete="PF('edit_entries').show()" />
</p:column>
</p:dataTable>
</h:form>
<!-- Second datatable in the popup -->
<p:dialog header="Edit Enries" id="dialogUpdateEntries" widgetVar="edit_entries" modal="true"
resizable="false">
<h:form id="formEntriesList">
<p:dataTable id="list2" var="entry"
value="#{bean2.entriesList}" rowKey="#{entry.id}"
selection="#{bean2.selectedEntry}" selectionMode="single">
<p:column headerText="Entry Number">
<h:outputText value="#{entry.number}" />
</p:column>
</p:dataTable>
<f:facet name="footer">
<p:commandButton value="Save" oncomplete="PF('edit_entries').hide()" />
</f:facet>
</form>
</p:dialog>
You're indeed not updating the data table in the dialog. JSF doesn't automatically update the view on change of the model, you have to explicitly tell the view to do so. You can use the ajax action component's update attribute for this. This takes a JSF client ID which can be found by rules as outlined in this related answer: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar".
Given the markup as shown in the question, that'll be
<p:commandButton ... update=":list:list2" />
However, there's another potential problem. You're using <p:dialog modal="true"> inside a form instead of giving the dialog its own form. This way the dialog may not be available in the HTML DOM tree as JavaScript (the one responsible for dealing with ajax stuff) would expect to find it. Giving the dialog its own form should fix this matter. It'll also fix the potential future problems with invoking actions from inside the dialog as handled in this related question: <p:commandbutton> action doesn't work inside <p:dialog>.
<h:form id="viewForm">
...
<p:commandButton ... update=":editDialog" />
...
</h:form>
<p:dialog id="editDialog" modal="true">
<h:form id="editForm">
...
</h:form>
</p:dialog>
Try adding update="list2" to Edit Entries command button (even update="#widgetVar(edit_entries)" should work).
If, because of page layout and structure, you can't target the second datatable using above suggestions, then add styleClass="tList2" to second table, and update it with update="#(.tList2)" on edit button.

Update p:commandButton in p:column on complete of actionListener

I am trying to do a deactivation method, which will show the status ("DEACTIVATED","ACTIVATED") of the account on the commandbutton, and when i clicked on the commandButton, it will either activate or deactivate the account based on the current status. Once I confirm, the commandButton will be immediately updated to its current status.
I have the following code and I would like to update my commandButton after completion of my actionlistener in "confirmDeactivateDialog" or "confirmActivateDialog". I tried using update="a,b" at those two confirmDialog tag but it doesn't work. Any suggestions?
<p:column headerText="Status" style="text-align: center">
<p:commandButton id='a' rendered="#{bean.isActivated(account_status)==true}" oncomplete="PF('deactivateDialog').show();" value="Activated">
<f:setPropertyActionListener value="#{searchEmployeeResultList}" target="#{bean.selectedEmployee}"/>
</p:commandButton>
<p:confirmDialog id="confirmDeactivateDialog" header="Confirm Deactivation" widgetVar="deactivateDialog">
<p:commandButton id="Deactivate" value="Ok" oncomplete="PF('deactivateDialog').hide();" actionListener="#{AccountManagedBean.deactivate}"/>
</p:confirmDialog>
<p:commandButton id="b" rendered="#{bean.isActivated(account_status)==false}" oncomplete="PF('activateDialog').show();" value="Deactivate">
<f:setPropertyActionListener value="#{searchEmployeeResultList}" target="#{bean.selectedEmployee}"/>
</p:commandButton>
<p:confirmDialog id="confirmActivateDialog" header="Confirm Activation" widgetVar="activateDialog">
<p:commandButton id="Activate" value="Ok" oncomplete="PF('activateDialog').hide();" actionListener="#{AccountManagedBean.activate}"/>
</p:confirmDialog>
</p:column>
try
update="a b"
with no comma between them

Open <p:dialog> from bean by RequestContext#execute()

I have this form with a panel grid and a dialog:
<h:form id="regiForm">
<p:panelGrid>
<p:row style="height:30%">
<p:column>
<h:outputText/>
</p:column>
<p:column>
<p:commandButton style="width:350px" type="submit" actionListener="#
{regiBean.showDialog}" id="ajax" value="#{msg['regi_button']}" update="regiForm" process="#this"/>
</p:column>
<p:column>
</p:column>
</p:row>
</p:panelGrid>
<p:dialog id="dialog" header="#{msg['regi_dialog_header']}" widgetVar="myDialog" position="center center" >
<h:outputText value="#{msg['regi_dialog']}" />
</p:dialog>
</h:form>
I would like to open the dialog from inside the action listener:
public void showDialog() {
RequestContext.getCurrentInstance().execute("dialog.show()");
RequestContext.getCurrentInstance().execute("myDialog.show()");
}
However, the dialog is not shown. How is this caused and how can I solve it?
I'm using JSF 2.1 and PrimeFaces 3.5.
The first statement with the command
RequestContext.getCurrentInstance().execute("dialog.show()");
won't work because dialog refers to the XHTML ID of the p:dialog component. This will cause an javascript error. And that could be the reason why the second command
RequestContext.getCurrentInstance().execute("myDialog.show()");
won't get executed.
Also I would add ; to the end of each Javascript command (but this is just my personal style)

f:setPropertyActionListener not invoked

I am trying to move a p:dialog out of a h:form, because I have read that this is the preferred way (however I'd like to understand the reason, because my p:dialog inside a form works well in my application).
The only difficulty is that the dialog title needs to be updated dynamically. The dialog is shown when a button in a p:dataTable is clicked.
Here is my old xhtml (before the changes), that's working fine:
<p:dataTable var="event" value="#{eventBean.lazyModel}" selection="#{eventBean.selectedEvent}" />
...
<p:column headerText="#{msgs.Persons}">
<p:commandButton value="#{msgs.ViewPersons}" update=":viewPersonsForm" oncomplete="viewPersonsDlg.show()">
<f:setPropertyActionListener value="#{event}" target="#{eventBean.selectedEvent}" />
</p:commandButton>
</p:column>
</p:dataTable>
<h:form id="viewPersonsForm">
<p:dialog modal="true" widgetVar="viewPersonsDlg" dynamic="true" header="#{eventBean.selectedEvent.name}" >
...
</p:dialog>
</h:form>
And here is the new xhtml, with eventBean#setSelectedEvent() that is not invoked.
<p:dataTable var="event" value="#{eventBean.lazyModel}" selection="#{eventBean.selectedEvent}" />
...
<p:column headerText="#{msgs.Persons}">
<p:commandButton value="#{msgs.ViewPersons}" update=":viewPersonsDlgId" oncomplete="jQuery('#viewPersonsDlgId .ui-dialog-title').text('#{eventBean.selectedEvent.name}');viewPersonsDlg.show()">
<f:setPropertyActionListener value="#{event}" target="#{eventBean.selectedEvent}" />
</p:commandButton>
</p:column>
</p:dataTable>
<p:dialog modal="true" id="viewPersonsDlgId" widgetVar="viewPersonsDlg" dynamic="true" >
...
</p:dialog>
So, again, why in the second scenario eventBean#setSelectedEvent() is not invoked? And, if possible, why the first scenario is not optimal?
It is not restricted to use p:dialog inside a h:form since it can work in some cases, but most of the time you will find yourself struggling with some unexpected behaviour with that, here are some explanations :
Why not to place p:dialog inside h:form 1
Why not to place p:dialog inside h:form 2
The problem in your case is that jQuery method in oncomplete is called before the value is set with f:setPropertyActionListener. To avoid this use the same solution as you used in your first case. So :
<p:dataTable var="event" value="#{eventBean.lazyModel}" selection="#{eventBean.selectedEvent}" />
...
<p:column headerText="#{msgs.Persons}">
<p:commandButton value="#{msgs.ViewPersons}" update=":viewPersonsDlgId" oncomplete="viewPersonsDlg.show()">
<f:setPropertyActionListener value="#{event}" target="#{eventBean.selectedEvent}" />
</p:commandButton>
</p:column>
</p:dataTable>
<p:dialog modal="true" id="viewPersonsDlgId" widgetVar="viewPersonsDlg" dynamic="true" header="#{eventBean.selectedEvent.name}" >
...
</p:dialog>
No need to use jQuery here.
I had the same problem (pf 3.5):
<p:tabView id="cashFlowTabContainer" style="width:100%" activeIndex="0"
widgetVar="cashFlowTabContainerVar">
<p:tab title="#{labels['cashflow_incoming']}">
<p:outputPanel id="incomingPanel">
<p:dataTable value="#{cashFlowController.incomingCashFlows}"
var="cashFlow">
<p:column headerText="#{labels.cashflow_actions}">
<p:commandButton value="Edit"
action="# {cashFlowController.editIncoming}" update="#form" oncomplete="editInputVar.show();">
<f:setPropertyActionListener value="#{cashFlow}"
target="#{cashFlowController.selectedIncoming}" />
</p:commandButton>
</p:column>
and this was my dialog:
<p:dialog id="editInput" header="Dynamic Dialog"
widgetVar="editInputVar" resizable="false" draggable="false"
modal="true">
<p:panel>
<h:panelGrid columns="2" cellpadding="5">
...
<h:outputText value="#{labels.cashflow_description}:" />
<h:inputText
value="#{cashFlowController.selectedIncoming.description}" />
So... This way the setter was NEVER called. Then I noticed that if I emptied the dialog the setter was called.
So I solved it by putting a "rendered" statement on the panel:
<p:dialog id="editInput" header="Dynamic Dialog"
widgetVar="editInputVar" resizable="false" draggable="false"
modal="true">
<p:panel **rendered="#{cashFlowController.selectedIncoming != null}"**>
<h:panelGrid columns="2" cellpadding="5">
I guess there's a null pointer that is not logged anywhere... anyway this way it works :)

Resources