6

Since I'm working with TinyMCE (please don't go into "Primefaces has an editor" or anything similar) I need to execute a small piece of Javascript before and after every Ajax-call. I'd prefer not to edit every Ajax-call for this since there are a lot (and doing so will be bad practice for any future maintenance).

What would be the most elegant solution to execute Javascript pre- and post- any Ajax-call on the page?

Note: I'm using a custom composite for the TinyMCE-textarea. Any events too this object would also suffice. Though keep in mind that the actual Ajax-trigger might be invoked by a totally different object (though could nevertheless rerender the composite).

Menno
  • 12,175
  • 14
  • 56
  • 88

2 Answers2

8

Use the jsf.ajax.addOnEvent handler.

jsf.ajax.addOnEvent(function(data) {
    switch(data.status) {
        case "begin":
            // This is invoked right before ajax request is sent.
            break;

        case "complete":
            // This is invoked right after ajax response is returned.
            break;

        case "success":
            // This is invoked right after successful processing of ajax response and update of HTML DOM.
            // In case you're interested in error handling, use jsf.ajax.addOnError handler.
            break;
    }
});

Just put it in a JS file which is included by <h:outputScript target="head"> in the <h:body> of the desired pages. This will ensure that it's loaded after JSF's own jsf.js containing the jsf namespace.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I ran into an issue using `jsf.ajax.addOnEvent` which I'm not able to solve, can you take a look at it (update on question)? – Menno May 09 '13 at 20:00
  • Apparently you're not using `` to fire the ajax call. – BalusC May 09 '13 at 20:01
  • Ok, seems I misinterpreted this function. Thought it would be executed on `actionListeners` too. Will change my code accordingly, thanks again. – Menno May 09 '13 at 20:03
  • This is not related to whether you use action listeners or not. Just nest a `` in the command component. – BalusC May 09 '13 at 20:03
  • I'm quite surprised though that you're explicitly asking how to listen on an ajax request, while you're not firing an ajax request at all. – BalusC May 09 '13 at 20:06
  • Ah.. Let's just say it's been a long day. While testing I've removed my `f:ajax` and replaced them with `actionListener`s. Removed my `actionListener`s and replaced them with `f:ajax` once again. Ofcourse your solution is working as planned now! – Menno May 09 '13 at 20:18
  • There is something I don't quite understand. As far as I know, ajax requests are made by `` components whether they have an `` nested or not. But the `addOnEvent` handler only works for the ones that explicitly include the `` tag? Is there a way to add the event for every ajax call, independently of the `` tag? Thank you very much. – gmanjon Jul 22 '21 at 10:32
  • @gmanjon: There are no other ways than `jsf.ajax` API to create ajax requests in standard JSF. So this answer is fine. Perhaps you had PrimeFaces in mind? It indeed doesn't use standard `jsf.ajax` API, instead it uses jQuery. In this case, head to https://stackoverflow.com/q/27443142 – BalusC Jul 22 '21 at 10:35
  • You're right (as expected xD). All the ones that were not being intercepted were PrimeFaces components. It only doesn't work for `` after refreshes, which are done via ajax. But I will add a comment in the referenced staoverflow answer to ask this. Thank you very much. – gmanjon Jul 22 '21 at 12:36
0

There is an onevent attribute of JSF's <f:ajax> tag, that's used to perform AJAX tasks within a JSF application. Basically it specifies a JavaScript function that's called thrice: before AJAX call is sent, after AJAX response is received and after HTML DOM is updated. Exactly for this purpose PrimeFaces has split those callbacks into onstart, onsuccess, oncomplete and onerror respectively.

Not to be repetitive, you can find usage example in the answer to How to re-execute javascript function after form reRender?.

Community
  • 1
  • 1
skuntsel
  • 11,624
  • 11
  • 44
  • 67
  • Yes I know, though this would mean that I need to edit every `Ajax`-call on my page. As I stated in my question, I'm searching for a way to avoid this. E.g.: an `f:event` that is triggered upon every `Ajax-call` on the page. – Menno May 09 '13 at 14:17
  • In this case you could investigate jsf.js and build up several JS helper functions to send ajax requests not via tags, but via JavaScript. – skuntsel May 09 '13 at 14:23
  • Hmm will consider it, there's no default `JSF`-way so to speak? – Menno May 09 '13 at 14:30
  • No way that I know of. But it's definitely worth investigating the programmatic JS approach for your reason. – skuntsel May 09 '13 at 14:33