10

Is there a way to call a method upon leaving a page with JSF?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Landister
  • 2,194
  • 7
  • 38
  • 56
  • Incidentally, this is mentioned in the JSF 2.2 JSR: *"Event system enhancements. For example, the ability to install a listener for page navigation events. This would enable the familiar dialog, "You have unsaved changes in this page, are you sure you want to discard them?"* – Arjan Tijms Apr 03 '12 at 08:13
  • Possibly the spec intends a server side navigation here, but that would be limiting since the user needs to use postbacks to navigate to a new page then. – Arjan Tijms Apr 03 '12 at 15:47

4 Answers4

7

Not when using native JSF or PrimeFaces. Your best bet would be to hook on session expiration instead.

import jakarta.inject.Named;
import jakarta.enterprise.context.SessionScoped;

@Named
@SessionScoped
public class Bean implements Serializable {

    @PreDestroy
    public void destroy() {
        // Your code here.
    }
}

If you happen to use the JSF utility library OmniFaces, then you can use its @ViewScoped. This will call the @PreDestroy when leaving the page referencing the view scoped bean.

import jakarta.inject.Named;
import org.omnifaces.cdi.ViewScoped;

@Named
@ViewScoped
public class Bean implements Serializable {

    @PreDestroy
    public void destroy() {
        // Your code here.
    }
}

Under the covers, it works by triggering a navigator.sendBeacon() during the window beforeunload or pagehide event with a fallback to synchronous XHR (which is deprecated in modern browsers supporting navigator.sendBeacon()).

See also:

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
3

If you use omnifaces @ViewScoped annotation in the backing bean the bean object is destroyed when you leave the view; so you can call a function when this happens using the @PreDestroy annotation in it.

Note: You must use omnifaces @ViewScoped annotation; with standard JSF @ViewScoped annotation the object isn't destroyed just by leaving the view, so pay attention to the import!

Source: http://showcase.omnifaces.org/cdi/ViewScoped

Community
  • 1
  • 1
2

Your problem Solution :- it work with java script

    <head>
<title>onunload test</title>
<script type="text/javascript">
window.onunload = unloadPage;

function unloadPage()
{
 alert("unload event detected!");
}
</script>
</head>

Also Some link for more details:- Link

AirSon
  • 31
  • 1
  • 2
    The OP want to call a JSF backing bean method, not to show a simple alert. – BalusC Apr 04 '12 at 11:12
  • 3
    maybe you can programmatically click a hidden commandButton in the unload event to call a method in backing bean – damian Oct 14 '12 at 13:05
  • @BalusC I don't see OP has written he want to call baking bean method, he want simply to call method, or can't write... – Web Devie Dec 04 '13 at 08:25
0

You can call a JSF managed bean method when you are closing the page or navigating to another page by using a <a4j:jsFunction/> and calling it at 'onunload' event of the page body as below.

<body onunload="leavingPage()">

<a4j:jsFunction name="leavingPage" action="#{myBean.myMethod}"/>
prageeth
  • 7,159
  • 7
  • 44
  • 72
  • 1
    Have you ever tried it yourself? It won't work. At least, not in normal webbrowsers. – BalusC Apr 03 '12 at 11:17
  • 1
    I dont know what are the "normal webbrowsers". But I have tried this before I put it here. Now again I tried it in Chrome, FF and IE. Have YOU tried this before commenting? – prageeth Apr 03 '12 at 11:49
  • 5
    Then you had the luck to be inside a race condition everytime where ajax request has won from the browser close event. This is however **not** guaranteed to be successful everytime. For sure not in production where the server usually runs at a physically different machine and the network latency is thus higher. – BalusC Apr 03 '12 at 12:16