There have been a few posts recently about triggering client-side javascript from server-side javascript, integrating output from the server-side javascript. Here’s one way of doing it. It may not be best practice, and I’m sure there are other methods – with XPages I’ve come to learn that there are always at least two ways of doing the same thing.

One caveat with this method before we get started: it will only work from 8.5.1 onwards. That’s because we’re triggering client-side javascript from the onComplete event, and that only became available from 8.5.1.

You can see it in action here. Take a look at the source HTML and you’ll see the database creation date and replica ID are not to be found. Look closer and you’ll see a client-side javascript alert in XSP.attachPartial which refers to an empty input element and an empty span element. Click the button and you’ll get an alert box with this message:

“Database was created on 21/04/2010 10:15:37 PM. Database replica ID is 8025770C0073083D”

Take a look at the source HTML again, and you’ll see the input and span are now populated.

So how does it work?

There is nothing unusual with the input. It’s a Hidden Input control with value=”” (so doesn’t display, but is available to client-side javascript) – you could also use a normal xp:inputText with style=”display:none”.

And the span is a Computed Field control – xp:text bound to a viewScope variable called SSJS_Return. That has style=”display:none” so it’s visible to the client-side javascript but not visible.

Both these controls are within a repeat panel called “refreshPanel”. That’s very important, and you’ll see why shortly.

The button uses server-side javascript to set a value in the xp:inputHidden and set the viewScope variable. It then does a partial refresh of refreshPanel. That means the source HTML for that panel is refreshed and the values become available for client-side javascript. Put the xpInputHidden and xp:text outside the panel you’re refreshing and it won’t work.

But the alert happens when you click the button. After the server-side javascript has run. How do we do that?

That’s where the onComplete event comes in. You need to look at the All Properties panel to find it, along with the onStart and onError events. These are all client-side javascript functions, and here’s the beauty. It means after the server-side javascript has triggered, we can run some client-side javascript code. We use dojo.byId() to get the field and the span, and alert the user with the values.

It’s a simple technique, but one which could have extended applications for alerting the user as we’re doing here. Made simpler, we could just populate the viewScope variable, and set dojo.byId().style.visibility=”visible” to display the message in its xp:text. Or, extending it further, we could populate content in and showing a dijit.Dialog.

Here’s the code of my XPage:

  1. <xp:button value=“Trigger Refresh” id=“button1”>
  2.         <xp:eventHandler event=“onclick” submit=“true”
  3.             refreshMode=“partial” refreshId=“refreshPanel”>
  4.             <xp:this.action><![CDATA[#{javascript:getComponent(“inputSSJS”).setValue(@Text(database.getCreated()))
  5. viewScope.SSJS_Return = database.getReplicaID()}]]></xp:this.action>
  6.             <xp:this.onComplete><![CDATA[alert(“Database was created on ” + dojo.byId(“#{id:inputSSJS}”).value + “. Database replica ID is ” + dojo.byId(“#{id:textSSJS}”).innerHTML)]]></xp:this.onComplete>
  7.         </xp:eventHandler></xp:button>
  8.     <xp:panel id=“refreshPanel”>
  9.         <xp:inputHidden id=“inputSSJS” value=“”></xp:inputHidden>
  10.         <xp:text id=“textSSJS” value=“#{viewScope.SSJS_Return}” style=“display:none”></xp:text>
  11.     </xp:panel>

6 thoughts on “XPages: Calling Client-Side Javascript from Server-Side Javascript”

  1. It took some searching but finally found your post. It is really helpful and and cleans up some SSJS processing that happens during my XPage. This was exactly what I was looking for this morning 🙂
    Thanks,
    Glenn

  2. With the latest version of Domino there are more flexible ways of triggering CSJS from SSJS. view.postScript (there are plenty of blogs about it) allows you to pass CSJS as a string from SSJS, and it runs at the end of the partial refresh.

    So you could use:
    getComponent(“inputSSJS”).setValue(@Text(database.getCreated()));
    var alertStm=Database was created on ” + @Text(database.getCreated()) + “. Database replica ID is ” + database.getReplicaID() + “;
    view.postScript(“alert(‘” + alertStm + “‘)”);

    The key is remembering that view.postScript takes a string which is then parsed as CSJS.

  3. Thank you very much for the post. Very informative!

    view.postScript is really amazing (must have put more attention on ‘What’s new’ section of 8.5.3 release note – it was there).

  4. Hello there! Do you use Twitter? I’d like to follow you if
    that would be ok. I’m undoubtedly enjoying your blog and look forward to
    new updates.

  5. Pingback: Send a serverside redirect to a new window – LinQed | Mark Leusink

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.