0

working with a Primefaces data table and dialog. Each record in data table has a link as such:

     <p:commandLink value="#{item.pk}" update=":itemUpdateForm:display"
                    onclick="PF('itemUpdateDialog').show();" title="Edit">
            <f:setPropertyActionListener value="#{item}"
                        target="#{itemController.selecteditem}" />
     </p:commandLink>

The link opens a primefaces dialog successfully the first time but after I submit the form in this popup dialog, which updates that recordset, the links in the datatable will no longer open the dialog again unless I hit refresh on the browser.

Here is the update button in the p:dialog:

<f:facet name="footer">
    <p:commandButton value="Update" update=":ItemListForm:dataTable, :growl"
        oncomplete=" handleSubmitRequest(xhr, status, args, 'itemDlg','itemUpdateForm');"
        actionListener="#{itemController.doUpdateItem()}" />
    <p:commandButton type="reset" value="Reset"></p:commandButton>
</f:facet>

And scopes/pertinent code:

itemController

@ManagedBean
@ViewScoped
public class ItemController implements Serializable {

@PostConstruct
public void init() {
    items= itemListProducer.getItems();
}

public void doUpdateItem() {
    itemRepository.update(selectedItem);
    itemEventSrc.fire(selectedItem);
    items = itemListProducer.getitems();
    Messages.addAjaxMessage("Update Operation Was Successful!");
}

List Producer

@ApplicationScoped
public class ItemListProducer implements Serializable {

Edit per comment here is DataTable and the Primefaces update dialog

<h:form id="ItemListForm">
    <p:dataTable id="dataTable" var="item"
        value="#{itemController.items}"
        paginator="true" rows="10"
        selection="#{itemController.selectedItems}" rowKey="#{item.oc_id}"
        paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
        lazy="false" rowsPerPageTemplate="10,15,50">

   <f:facet name="header"> 
       Items (#{itemController.items.size()}) 
   </f:facet>

   <p:column selectionMode="multiple" style="width:18px"/>

   <p:column filterBy="#{item.oc_id}" sortBy="#{item.oc_id}">
      <f:facet name="header"><h:outputText value="OC #" /></f:facet>

      <p:commandLink value="#{item.pk}" update=":itemUpdateForm:display" onclick="PF('itemUpdateDialog').show();" title="Edit">
      <f:setPropertyActionListener value="#{item}" target="#{itemController.selecteditem}" />
      </p:commandLink>
   </p:column>

   more p:columns

   <f:facet name="footer">
      <p:commandButton value="New item" onclick="PF('dlg1').show();" title="Creates new Item" />

      <p:commandButton value="Delete Selected Items" 
         actionListener="#{itemController.doDeleteItems}"
         update="@form, :growl">
        <p:confirm header="Confirmation" message="Are you sure you want to remove the selected Items?" />
      </p:commandButton>
  </f:facet>

</p:dataTable>
    <p:confirmDialog global="true">
        <p:commandButton value="Yes" type="button"
            styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
        <p:commandButton value="No" type="button"
            styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
    </p:confirmDialog>

</h:form>

... and dialog

<p:dialog header="Item Update Form" widgetVar="itemUpdateDialog" resizable="false" id="itemDlg">
   <h:form id="itemUpdateForm">
      <p:panel>
         <p:panelGrid id="display" columns="3" cellpadding="4"
                    style="margin:0 auto;">

                    <h:outputText value="Title :"></h:outputText>
                    <p:inputText id="title" value="#{itemController.selectedItem.title}"
                        required="true"
                        requiredMessage="Please Enter Title!" />
                    <p:message for="title" />
    other inputs

                    <f:facet name="footer">
                        <p:commandButton value="Update" update=":ItemListForm:dataTable, :growl"
                            oncomplete=" handleSubmitRequest(xhr, status, args, 'itemDlg','itemUpdateForm');"
                            actionListener="#{itemController.doUpdateItem()}" />
                        <p:commandButton type="reset" value="Reset"></p:commandButton>
                    </f:facet>
         </p:panelGrid>
      </p:panel>
   </h:form>
</p:dialog>

EDIT 2 Thanks to help from Michele's Answer, I determined the issue was related to how I was closing the dialog by its id and not by its widgetVar. I was originally passing in just the id which was used with jQuery effect 'shake', and then closing that object. By adding the widgetVar and using Michele's var d = (typeof dialogWv === "string") ? PF(dialogWv) : dialogWv; I no longer have my issue.

This ultimately works for me:

<p:dialog header="Update Form" widgetVar="itemUpdateDialogWv"
    resizable="false" id="itemUpdateDialogId">
      <h:form id="itemUpdateForm">
          <p:panel>
  ------content-------
                <f:facet name="footer">
                    <p:commandButton value="Update" update=":ItemListForm:dataTable, :growl"
                        oncomplete=" handleSubmitRequest(xhr, status, args, 'itemUpdateDialogWv','itemUpdateForm', 'itemUpdateDialogId');"
                        actionListener="#{itemController.doUpdateItem()}" />
                    <p:commandButton type="reset" value="Reset"></p:commandButton>
                </f:facet>
            </p:panelGrid>
            </p:panel>

      </h:form>
</p:dialog>


function handleSubmitRequest(xhr, status, args, dialogWv, formName, dialogNameId) {  
        dialog = jQuery('#'+dialogNameId);
        var d = (typeof dialogWv === "string") ? PF(dialogWv) : dialogWv;
    if(args.validationFailed) {  
        dialog.effect("shake", { times:5 }, 1000);  
    } else {
        clearForm(formName);
        d.hide();
    }  
}
function clearForm(formName){
    jQuery('#'+formName).each(function(){
        this.reset();
});
}
jeff
  • 3,618
  • 9
  • 48
  • 101
  • `update=":ItemListForm:dataTable, :growl"` should be `update=":ItemListForm:dataTable :growl"`, without `,`. Also look for javascript errors. – Michele Mariotti Dec 17 '14 at 09:47
  • @MicheleMariotti that isn't a error. Read more about [on this post](http://stackoverflow.com/questions/4474789/jsfprimefaces-ajax-update-of-several-elements-by-ids). About javascript errors i'm agree with you. – giaffa86 Dec 17 '14 at 13:08
  • could you post `itemUpdateDialog` full code, and all code if possible.I wanna see the structure in which you have included the dialog and datatable. – Kishor Prakash Dec 17 '14 at 13:25
  • @KishorP, added more (hopefully not too much) code – jeff Dec 17 '14 at 16:10
  • @MicheleMariotti th issue is not that my datatable is not being updated. After I click the submit button on the dialog, the dialog hides as expect, the datatable reflects the values changed in the popup dialog as expect, but the commandLinks in the datatable fail to reopen the dialog unless I hit refresh on the browser first. – jeff Dec 17 '14 at 19:08
  • Try appending the `p:dialog` to body using `appendTo="@(body)"`. – Kishor Prakash Dec 18 '14 at 05:40
  • @jeff I understood the datatable is being rendered, but maybe its commandButtons are not rendered correctly. No js errors on commandButton click? Is request fired? Can you post request params for the not working click? – Michele Mariotti Dec 18 '14 at 07:57

1 Answers1

1

Too long for a comment...

You can try:

<p:commandLink value="#{item.pk}" process="@this" update=":itemUpdateForm" 
    oncomplete="PF('itemUpdateDialog').show();" title="Edit">

    <f:setPropertyActionListener value="#{item}" target="#{itemController.selecteditem}" />
</p:commandLink>
  • specify process="@this": otherwise it defaults to @all and will include the dialog too
  • use oncomplete instead of onclick

and

<p:commandButton value="Update" process="@form" update="@form, :ItemListForm, :growl"
    oncomplete="handleSubmitRequest(xhr, status, args, 'itemDlg','itemUpdateForm');"
    actionListener="#{itemController.doUpdateItem}" />
  • specify process="@form": the same as before
  • add @form to update: generally is a good practice to update the dialog form tho show validation errors and to close dialog only if not validation failed (I don't know how handleSubmitRequest works, maybe it does exactly this)

However:

  • No js errors on commandButton click?
  • Is request fired?
  • If yes, can you post request params for the not working click?

P.S.

handleSubmitRequest(xhr, status, args, 'itemDlg','itemUpdateForm'); has argument itemDlg. Is it correct?

for completeness here is my hideDialog

function hideDialog(dialog, args, status, xhr)
{
    var d = (typeof dialog === "string") ? PF(dialog) : dialog;

    if(!args.validationFailed)
    {
        d.hide();
    }
}

which is invoked:

<p:commandButton value="Update" process="@form" update="@form :ItemListForm :growl"
    oncomplete="hideDialog('itemUpdateDialog', args)"
    actionListener="#{itemController.doUpdateItem}" />
Michele Mariotti
  • 7,372
  • 5
  • 41
  • 73