1

In my view I have a disabled p:inputText showing some adress information. The value of the p:inputText is set by the dialogReturn listener onAdresseDialogReturn(). Besides this inputText I have several other input fields (p:selectOneMenu, p:inputText).

Whenever I change some values of the other input components and try to leave the page, I get a warning dialog from the detectUnsavedChanges JavaScript.

My problem now is, that I want this warning message also, when the dialogReturn listener changes the value of the inputText field - but this does not happen!

So my question is, how can I achieve this?

Here the p:inputText with a p:commandButton using the primefaces dialog framework:

<ui:composition>

    <ui:define name="head">
        <h:outputScript name="js/detectUnsavedChanges.js"/>
    </ui:define>

    <ui:define name="content">
        <h:form id="form">
            <p:panelGrid>
                <p:row>
                    <p:column>
                        <p:commandButton id="save" value="Save" ajax="false" action="#{bean.save}"/>
                    </p:columns>
                </p:row>
            </p:panelGrid>

            <p:panelGrid>
                <p:row>
                    <p:column>
                        <p:inputText id="adresse" disabled="true" size="50"
                                     value="#{bean.adresse}"/>
                        <p:commandButton id="adresseAuswahl" 
                                         title="Adresse bearbeiten"
                                         process="@this"
                                         actionListener="#{bean.showAdresseDialog}">
                            <p:ajax event="dialogReturn" update="adresse"
                                    listener="#{bean.onAdresseDialogReturn}"/>
                        </p:commandButton>  
                    </p:columns>
                </p:row>
            </p:panelGrid>
        </h:form>
    </ui:define>
</ui:composition>

Here the dialogReturn listener in my bean:

public void onAdresseDialogReturn(SelectEvent e) {
    final Adresse adresse = (Adresse) e.getObject();
    boolean changedAdresse = Optional.ofNullable(adresse).isPresent() 
            && !getAdresse().equals(adresse);
    if (changedBauvorhabenAdresse) {
        // Adresse has been changed
        setAdresse(adresse);
    }
}

Here the JavaScript code as mentioned by BalusC from How to detect unsaved data in form when user leaves the page?:

$(function() {
    // Set the unload message whenever any input element get changed.
    $(':input').on('change', function() {
        setConfirmUnload(true);
    });

    // Turn off the unload message whenever a form get submitted properly.
    $('form').on('submit', function() {
        setConfirmUnload(false);
    });
});

function setConfirmUnload(on) {
    var message = "You have unsaved data. Are you sure to leave the page?";
    window.onbeforeunload = (on) ? function() { return message; } : null;
}

My Environment: Primefaces 6.0 on Wildfly-10.0.0.Final

Any hints welcome - Thank you!

Community
  • 1
  • 1
raho
  • 129
  • 4
  • 18

1 Answers1

0

Try adding an oncomplete attribute to your p:ajax inside the commandButton. I don't actually know if you can put a p:ajax component inside the p:commandButton however in the oncomplete attribute you should call setConfirmUnload(true) like this:

                   <p:commandButton id="adresseAuswahl" 
                                     title="Adresse bearbeiten"
                                     process="@this"
                                     actionListener="#{bean.showAdresseDialog}">
                        <p:ajax event="dialogReturn" update="adresse"
                                listener="#{bean.onAdresseDialogReturn}" oncomplete="setConfirmUnload(true)"/>
                    </p:commandButton>
500 Server error
  • 644
  • 13
  • 28
  • The `p:commandButton` is already ajaxified by default as mentioned in the PrimeFaces showcase and documentation – Kukeltje Jan 30 '17 at 17:32
  • I thought so. I'd use the `p:ajax` component inside the `dialog` component listening to the **close** event. Like this: ` ` – 500 Server error Jan 30 '17 at 17:48
  • But now the confirm dialog appears always - even if `changedBauvorhabenAdresse` is false in my `onAdresseDialogReturn()` listener. I tried `oncomplete="setConfirmUnload(#{bean.changedBauvorhabenAdresse})"` but the getter of `changedBauvorhabenAdresse` is called only once during page creation and not when the ajax event occurs! How can I solve this? – raho Jan 31 '17 at 06:29
  • yes it's called only once when JSF is creating your HTML page and evaulating client-side attributes of the components used. – 500 Server error Jan 31 '17 at 10:23
  • It should be reevaluated on every update of the `p:commandButton` component though. – 500 Server error Jan 31 '17 at 11:26
  • changing `update="adresse adresseAuswahl"` in my ajax event tag does not re-evaluate the `p:commandButton` and therefore does not show the confirm dialog on page change?! – raho Feb 02 '17 at 06:24
  • @raho When is it that you want to call your javascript method? – 500 Server error Feb 02 '17 at 11:54
  • the javascript method should be called after the dialogReturn listener and should use as parameter a value which is set be the listener – raho Feb 04 '17 at 17:44
  • Try debugging and see if it actually calls the method `isChangedBauvorhabenAdress‌​e` in your bean. – 500 Server error Feb 05 '17 at 22:10
  • 1
    adding the id of the button to ajax update (`update="adresse adresseAuswahl"`) re-evaluates `changedBauvorhabenAdresse` and die confirm dialog appears as expected - thank you! – raho Feb 13 '17 at 07:04