4

I am using JSF to build a site. I have included jQuery Gritter (Growl) notification on my home page. Is it possible to call a managed bean method inside the before_close: of $.gritter.add function?

The code that I want to use is as follows:

<h:body>
    <c:forEach items="#{notificationBean.growlNotificationList}" var="p">
        <script>
        /* <![CDATA[ */
        $.gritter.add({
            // (string | mandatory) the heading of the notification
            title: 'Notification',
            // (string | mandatory) the text inside the notification
            text: 'Comment on your staus',
            // (bool | optional) if you want it to fade out on its own or just sit there
            sticky: true, 
            // (int | optional) the time you want it to be alive for before fading out (milliseconds)
            time: 8000,
            // (string | optional) the class name you want to apply directly to the notification for custom styling
            class_name: 'gritter-light',
            // (function | optional) function called before it closes
            before_close: function(e, manual_close){
                '#{notificationBean.set0ToGrowlToShow(p.notificationID)}'
            }
        });
        /* ]]> */
        </script>
    </c:forEach>
</h:body>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555

2 Answers2

5

Your current attempt merely interprets the given EL expression as a value expression and just prints its result immediately during producing the HTML output with the JS code embedded. It's like as if you're using <h:outputText>. This is indeed not going to work.

The functional requirement is however understood. The standard JSF API does not offer a ready-to-use solution for this. If you want to stick to standard JSF API, your best bet is to create a hidden form with a hidden command link which you trigger using JavaScript.

Basically,

<h:form id="form" style="display:none">
    <h:inputHidden id="id" value="#{notificationBean.notificationID}" />
    <h:commandLink id="command" action="#{notificationBean.set0ToGrowlToShow}">
        <f:ajax execute="@form" />
    </h:commandLink>
</h:form>

with

$("[id='form:id']").val(#{p.notificationID});    
$("[id='form:command']").click();

However, this is pretty clumsy. Consider looking for a 3rd party JSF component or even utility library to achieve the requirement anyway. The JSF utility library OmniFaces has the <o:commandScript> component for this. See also its showcase page.

<h:form>
    <o:commandScript name="set0ToGrowlToShow" action="#{notificationBean.set0ToGrowlToShow}" />
</h:form>

with

set0ToGrowlToShow(#{p.notificationID});

(please note that this is set as HTTP request parameter, not as action method argument)

The JSF component library PrimeFaces has the <p:remoteCommand> for this which is much similar to <o:commandScript>. See also its showcase page. Even more, PrimeFaces has a ready-to-use <p:growl> component which does essentially the same as your jQuery plugin! See also its showcase page. Instead of your whole jQuery thing you can just do:

<p:growl globalOnly="true" autoUpdate="true" />

and feed it with messages by

facesContext.addMessage(null, message);

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Where will I paste the following code ``. Will I place it outside the –  Mar 27 '13 at 20:13
  • 2
    Yes. Are you familiar with basic HTML? Just do rightclick and *view source* in browser. You just have to make sure that the JSF-produced HTML code is [valid](http://validator.w3.org). – BalusC Mar 27 '13 at 20:14
  • getting `Component ID foo has already been found in the view.` in the exception –  Mar 27 '13 at 20:21
  • 2
    That's a different problem unrelated to the concrete question. The answer is basically already in the exception message itself: just don't use the same ID on multiple components. – BalusC Mar 27 '13 at 20:24
  • Is it because the form with id = foo is generated multiple times inside the forEach?. Is there any work around? –  Mar 27 '13 at 20:40
  • 2
    As said, this is going to be very clumsy. You could add another loop which prints the form with a dynamic ID. You could use a single form with an additional `` whose value you manipulate with jQuery. I've edited the answer with the latter approach. – BalusC Mar 27 '13 at 20:56
0

You need to understand that you need to call a java method that runs in the server and you CANNOT call it directly.

In your case, I would recommend to use AJAX or have the value read on load of the page and use it (if feasible for you)

Check how you can use AJAX with Jquery

hop
  • 2,518
  • 11
  • 40
  • 56
  • OP is aware of this, that's why the question is how to call the managed bean method inside the JavaScript method. By the way, JSF 2 already supports ajax interaction, and there are third party libraries like PrimeFaces and RichFaces that ease ajax and JSF interaction. – Luiggi Mendoza Mar 27 '13 at 20:06