Client side Javascript frequently makes use of IDs that have been assigned to controls in order to encode client side logic. Take the simple case where you have a combo box above an edit box. When some values in the combo box are selected, the edit box should be visible, and when others are selected, it should be invisible.
This would appear easy do to by some simple client side Javascript attached to the onChange event on the combo box:
var ourValue = document.getElementById("comboBox").value;
var visibility;
if (ourValue == 'Other')
visibility = 'visible';
else
visibility = 'hidden';
document.getElementById("editBox").style.visibility=visibility;
However, this doesn't work. The reason why is that "comboBox" and "editBox" are the IDs we've assigned the controls in Domino Designer. When they are rendered to HTML they take on different values:
Client side:
The "view:_id1:" prefix assigned to the ID of the controls is what XPages do to make sure that the IDs used for each control are unique. If you remember, a control is in an XPage or Custom Control, which can be included in another XPage. Domino Designer can ensure the IDs as you type them are unique to the XPage or Custom Control you create, but since it cannot predict what you will include in what, at runtime these unique identifiers need to be added. Similarly a control can be included within a repeat control. This means the control will appear several times in the final UI. Since you can only specify the ID once, we also need this prefixing to ensure it is unique at run time.
There is a Javascript function getClientId() which will prefix an ID with the correct value to make it into a client ID. However, this function can only be called from Server Side Javascript. To use it from Client Side Javascript we need to use the feature of XPages which allows you to insert Server Side Javascript into arbitrary places on your XPage. This is signaled by surrounding the Server Side Javascript with #{javascript: ... } notation. When the page is rendered, it is first examined for these script inclusions. If they are found, they are executed and their output is rendered into the output HTML. To work correctly, the above script can be changed to the following:
var comboID = '#{javascript:getClientId("comboBox")}';
var editID = '#{javascript:getClientId("editBox")}';
var ourValue = document.getElementById(comboID).value;
var visibility;
if (ourValue == 'Other')
visibility = 'visible';
else
visibility = 'hidden';
document.getElementById(editID).style.visibility=visibility;
The IDs are evaluated on the server and inserted into the client side Javascript. When the script reaches the client it looks like this:
var comboID = 'view:_id1:comboBox';
var editID = 'view:_id1:editBox';
var ourValue = document.getElementById(comboID).value;
var visibility;
if (ourValue == 'Other')
visibility = 'visible';
else
visibility = 'hidden';
document.getElementById(editID).style.visibility=visibility;
And this runs the way we expect it.
Although useful to illustrate the power of embedding Server Side JavaScript into Client Side Javascript, this is an even simpler method that can be used for this specific use case. There is another insertion #{id:
ident} specifically for getting the client IDs of controls. You could change the first two lines of our code above to:
var comboID = '#{id
:comboBox}';
var editID = '#{id
:editBox}';
for the most optimal solution of this case.
[Note: in this particular use case we wish the edit box to start off invisible. We cannot uncheck the "visible" status in the designer. This actually indicates the edit box is not to be
rendered. If it is not rendered, it is not present at all, so we cannot later make it visible. So what we want to do is give it a custom status of "visibility: hidden". Then it will work as expected.]
This technique can be used in all circumstances where we need to use Client Side Javascript code that manipulates controls based on their actual ID values.
For a wider discussion of making things selectively visible and a comparison between the client approach and the server approach see the article "
Selective Visibility on XPages".