0

I found this question is already asked several times in different forms, but I still need some help on this, since can't get this as in the examples.

I have a JSF 2 page with PrimeFaces, and it contains the following hidden button, which I need to call on pageUnLoad from javascript.

The JSF has:

// Supposed to be hidden eventually
<h:commandButton id="doStuff" action="#{myBean.callMethod()}" />

The javascript has:

var stuff = new Object();

$(window).bind('beforeunload', function() {
    stuff.doStuff();
});

stuff.doStuff = function() {
    // var hidden = $("#doStuff"); // Incorrect
    var hidden = document.getElementById("formId:doStuff"); // Correct
    if (hidden === undefined) {
            // Some logging
    } else {
        hidden.click();
    }
}

And the managedBean has:

@ManagedBean(name = "myBean")
@RequestScoped
public class MyBean {
    public void callMethod() {
        // Do stuff
    }
}

By debugging I can see that when manually clicking the button, it fires the event correctly. I am also able to verify that the JavaScript is called correctly, it "seems" to find the element, and performs the '.click()' for it, but I do not catch any event on the server side.

I seem to be doing it as it has been instructed in other similar questions, but I lack the final result.

Any help would be appreciated, thanks.

Ville Myrskyneva
  • 1,560
  • 3
  • 20
  • 35
  • 1
    jQuery can't call click functions that weren't defined by jQuery. You would need to send an ajax request to the server on click and then send the result of that back. Or you would need to pre populate that data into a JS variable, and serve the data from the variable on click after defining the click function with jQuery. – Ohgodwhy Jul 24 '13 at 12:55

2 Answers2

2

Hidden button can be clicked by using JavaScript like

document.getElementById('doStuff').click();

However, you should be careful about naming containers. Hidden button must be enclosed by a <h:form> tag and prependid attribute of it should be set false. Otherwise you can access the button with the id formId:doStuff.

See also

Naming Container in JSF2/PrimeFaces

Cannot click hidden button by JavaScript

Community
  • 1
  • 1
erencan
  • 3,725
  • 5
  • 32
  • 50
  • Some unpleasant fact I didn't know about JQuery. Got it working after educating my self with the provided links and doing it like you said. Thank you. – Ville Myrskyneva Jul 25 '13 at 05:12
  • Since I had alert following the click call (so that I was able to check it was really called), the event gets fired and caught on the server side. Also when changing the alert to console.log and tagging it with breakpoint, it also works (it gets stuck waiting with the breakpoint with FireFox FireBug). However, when I removed the alert / breakpoint it ceased working. Yet another lovely feature with javascript / DOM handling. Restoring either of those made it work again. This may have been the case with the other solution also (the other answer below). – Ville Myrskyneva Jul 25 '13 at 06:19
  • Just to double confirm this behavior. Adding a break point => works. Removing breakpoint => Does not work. – Ville Myrskyneva Jul 25 '13 at 06:20
  • I have never seen a situation like this. It should be work without breakpoints. However, there may be some exception before returning the action. – erencan Jul 25 '13 at 06:30
  • The moment I stop watching it, it breaks. The solution is correct, but I can't use it after finding out this unpleasant behavior. Also I found out that the whole 'onbeforeunload' event doesn't work with opera (my current version atleast) http://stackoverflow.com/questions/390260/onbeforeunload-in-opera – Ville Myrskyneva Jul 25 '13 at 06:56
  • Opera version: 12.16, Internet Explorer 9, FireFox 22.0 – Ville Myrskyneva Jul 25 '13 at 07:03
  • > there may be some exception before returning the action. - There is no exceptions in the log (since the serverside method is never called and when it is, it works correctly). However since the called method does not return anything, this may be worth checking if such behaviour is expected!? – Ville Myrskyneva Jul 25 '13 at 07:07
  • I have no idea about `onbeforeunload`. Sorry. – erencan Jul 25 '13 at 07:07
  • No problem. You have already been helpful. This is already another situation (atleast kind of). – Ville Myrskyneva Jul 25 '13 at 07:10
  • Exception stack trace may not be seen in the log since JSF exception handler wraps it. Check this. http://wmarkito.wordpress.com/2012/04/05/adding-global-exception-handling-using-jsf-2-x-exceptionhandler/ and also [FullAjaxExceptionHandler](http://showcase.omnifaces.org/exceptionhandlers/FullAjaxExceptionHandler) feature of OmniFaces. – erencan Jul 25 '13 at 07:15
1

There is a much simpler way of calling server-side methods from javascript. Define a p:remoteCommand and Primefaces will create a JavaScript-function which you can call from inside your JavaScript-functions.

Use the following for defining the remoteCommand:

<p:remoteCommand name="doStuff" action="#{myBean.callMethod()}"/>

And then to call the bean-method on beforeunload just use:

$(window).bind('beforeunload', doStuff);
user1983983
  • 4,793
  • 2
  • 15
  • 24
  • It's not guaranteed that this call ever successfully hits the server. But that's a different problem. – BalusC Jul 24 '13 at 14:18
  • I tried this briefly, but didn't get it working right away. I trust this is a working solution also, but as the 1st answer already worked I accepted it (and it was also more direct answer to my question). Just aquestion regarding to this. Should (or should it not) the binding be in the onReady function? $(document).ready(function() { $(window).bind('beforeunload', doStuff); }); – Ville Myrskyneva Jul 25 '13 at 05:18
  • I think it would be a good practice to add the eventlistener in `window.onload`. – user1983983 Jul 25 '13 at 08:12