Tips for referencing elements in XPages JavaScript

I managed to hit a bit of a wall with my IdeaJam on XPages development this week. Up until now I haven’t really needed to write any client side JavaScript which is impressive in itself compared to how much client side scripts we have in IdeaJam classic. But I have reached that point where I want to add some interactivity without round-tripping to the server.

In classic Domino it’s very easy to write script that refers to specific elements of the HTML because you get to control the IDs of those elements. But with XPages it is not possible to predict what the name of an element will be when it reaches the browser. So you are provided with a couple of functions to help you out. When you’re writing client side Javascript in an XPage client side event (like clicking a button) it’s very easy, the syntax you use to reference an element is “#{id:myElement}” in place of the id. So for example you could use:

dojo.byId(“#{id:myDiv}”).style.display = “none”;

But the thing that I didn’t know about until John Mackey gave me some help was that there is a second way of getting the ID of an element. My specific problem was that I wanted to have a script run when the page finishes loading and that script needed to go and work on several different elements. It’s easy enough to make a script run “onload”. You can actually write JavaScript directly into the source XML of the XPage, so I have added, at the top of my XPage something like this:

<script language=”Javascript”>
XSP.addOnLoad(function () {
initLocal();
}
);
</script>

This will tell Dojo to call the function “initLocal()” when the page has finished loading, no problem there. But my initLocal function needs to reference an element on the page and I can’t use the “#{id:myElement}” format as that only gets evaluated in events that are provided for you by the XPage, enter the “getClientId()” function. You can add a computed field to the XPage that has JavaScript embedded within it in the following format:

var out=”<script language=\”Javascript\”>\n”;
out += “var myElementId = \”” + getClientId(“myElement”) + “\”;\n”;
out += “function initLocal(){\n”;
out += “myFunction(myElementId);\n”;
out += “}\n”;
out += “</script>”;
out

And by the time it makes it out the the browser it has been translated into:

<script language=”Javascript”>
var myElementId = “view:_id1:_id2:content:_id4:myElement”;
function initLocal(){
myFunction(myElementId);
}
</script>

So in the initLocal function I call another function which is held in a Client Side JavaScript library and I pass in the element ID so that the function can reference the element on the page with proper separation between UI and business logic. So it’s all a bit round the houses but this way of doing things does work well and hopefully you won’t need to go through the pain that I have in working this stuff out.

Finally a big thanks to John Mackey for his help, this is when the Lotus community really proves it’s worth

Join the Conversation

11 Comments

  1. Great article Matt! The getClientId() function should remind all of us that while there are so many click-and-run RAD features available with XPages, there are so many capabilities built into the technology that will allow us to even further extend it’s application.

    Like

  2. That is very, very kewl. And this post will help many others who delve into the world of xpages for development.Thanks for posting!–Rock

    Like

  3. I’m trying to figure out how to get a value of a repeat control in client sidedocument.getDocumentById(‘#{id:view:_id1:repeat1:0:inputText1}’).value it doesnt workany suggestions?

    Like

  4. Hi Nina,Looks like you’re trying to use the wrong code. In client side code you can’t use getDocumentById (which wouldn’t run against a document object anyway), instead you’ll need to use something like:dojo.byId(“#{id:inputText1}”).valueBut you’ll need to make sure that that client side script is inside the repeat control as well, otherwise it won’t know how to refer to the correct instance of the input field.Matt

    Like

  5. Hi MathThank you for you responseYes It’s my faultI meantdocument.getElementById(‘#{id:view:_id1:repeat1:0:inputText1}’).value I have a button(button1) and a inputText1(inputText1), both inside of a repeat control(repeat1)I need to show a message when clicked the button this message should include the value of inputText1(each value is different per row) and I dont know how to refer this valueI used this code in client side in click event of button1 var index=”#{colindex}”;/* colindex is the index of the collection of the repeat control */var valor=document.getElementById(‘#{id:view:_id1:repeat1:”+ index +”:inputText1}’).value but not luckThank youNina

    Like

  6. Because the ‘password’ item type is not available as an xpage element (correct me if Im wrong), I have been trying to get my HTML password field value back onto the server side. And failing miserably. I thought I might be able to getClientID to create a hidden item that contains the name of a bound field that I could populate in the clientside before submitting the document.

    This seems clumsy have you any better ideas?

    Thanks

    ewan

    Like

  7. How to access / getting the date in Client side in XPAGES. Hope you could reply here

    Like

  8. Thanks for the article, it’s definitely helped me. The only problem I’m having is with the output from the computed field.

    When the tag chevrons (is that the name for these: <>?) are rendered to the browsers source, they actually get rendered as meaning the code doesn’t understand it’s Javascript initially. Any ideas how I can get it render to the source as actual chevrons <>?

    I’ve tried using \ to escape it but that hasn’t worked 😦

    Using 8.5 server, tried also on 8.5 FP1 client (local http), same results in Firefox 3, IE 7, IE 6 (I know groan), chrome and Safari.

    Thanks!

    Like

  9. Absolutely typical!

    No sooner than I post do I find the answer after messing around for a while longer. If anyone else gets this issue, toggling ‘escape’ in the all properties for the computed field to false will sort this out 🙂

    Like

Leave a comment