0

I am working on a large, worldwide application, which includes access from areas of low bandwidth. As such, I want to use a minimum of SSJS or partial refreshes for all the complex hide/when calculations. Here is what I have so far for a simple "hide/when":

  1. A Yes/No radio button, with CSJS to show a panel ("Yes") or hide the panel ("No").
  2. The panel has a formTable inside it, and the values are shown or hidden, as per #1.
  3. In the XPage's onClientLoad, the following code is run:

    // "getRadioValue" is a simple script to return the value of a radio button
    var v_value = getRadioValue("#{id:radioButton}");
    v_div = '#{javascript:getClientId("radioButtonPanel")}';
    // show or hide div simply use dojo to change the display of the panel
    if (v_value == 'Yes') {
         showDiv(v_div);
    } else {
         hideDiv(v_div);
    };
    

For a new document, the onClientLoad script will hide the "radioButtonPanel" successfully. Changing the radio button to "Yes" will show the radioButtonPanel, just as clicking "No" will hide it. It works great! :-)

Once the document is saved and reopened in read mode, though, the onClientLoad CSJS event should read the saved value in the document, and decide to show the panel or not. When the document is opened in edit mode, the onClientLoad fires, reads the radioButton value and successfully shows or hides the panel.

This is what I've tried so far, to get it to work in read mode:

  1. In CSJS, using "#{javascript:currentDocument.getItemValueString('radioButton'}" to get the value,
  2. Doing some calculations in the "rendered" or "visible" properties, but that's SSJS and, if hidden, prevents any of the "show/hideDiv" CSJS visibility style changes.
  3. Adding an old fashioned "div" to compute the style (which is what I used to do before XPages), but since I can't do pass-thru html any more, I can't seem to get a CSJS calculation for the style. Ideally, I can do something like this:

    <div id="radioButtonPanel" style="<ComputedValue>">
    

    Where the ComputedValue would read the back end value of the document, and decide to add nothing or "display:none".

Note that I don't want to use viewScopes, since this long form would need many of them for all the other hide/when's.

Is there any way to make this 100% CSJS? I feel like I'm very close, but I wonder if there's something I'm just missing in this whole process.

1
  • You mention you can't do pass-thru... why not? Commented Mar 25, 2013 at 23:48

1 Answer 1

8

First, rather than computing style, I'd recommend computing the CSS class instead -- just define a class called hidden that applies the display:none; rule. Then toggling visibility becomes as simple as a call to dojo.addClass or dojo.removeClass.

Second, I see that you're using the #{id:component} syntax to get the client ID of the radio button but using SSJS to get the client ID of the panel. Use the id: syntax for both; this is still just a server-side optimization, but if there are many instances of these calculations, it adds up. Similarly, replace #{javascript:currentDocument.getItemValueString('radioButton'} with #{currentDocument.radioButton}. Both will return the same value, but the latter will be faster.

Finally, any attribute of a pass-thru tag (any component with no namespace, like xp: or xc:) can still be computed, but you'll need to populate the expression by hand, since the editor doesn't know which attributes for valid for these tags, and therefore doesn't provide a graphical expression editor. So if the ideal way to evaluate the initial display is by wrapping the content in a div, the result might look something like this:

<div class="#{javascript:return (currentDocument.getValue('radioButton') == 'Yes' ? 'visible' : 'hidden');}">
<xp:panel>
...
</xp:panel>
</div>
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! Works like a charm! I have many more "hide/when's" to go, but I can take it from here.
For the benefit of other people, what happens if there are multiple conditions? Basically, they still work, but there is a small change needed for some characters. Take the following as an example: <div class="#{javascript:return (currentDocument.getValue('radioButton') == 'Yes' && currentDocument.getValue('radioButton2') == 'Yes' ? 'visible' : 'hidden');}"> <xp:panel> ... </xp:panel> </div> The "&&" will give you the error "the entity name must immediately follow the '&' in the entity reference". So, instead of using "&&", replace them with "&amp;&amp;", and it will work.
Good point. You'd also need to encode <> (i.e. "someValue &lt; anotherValue"). When using the visual editor, it automatically wraps the expression in a CDATA if it detects characters that would otherwise need to be escaped or encoded, but when hand-editing passthru attributes, it's faster to just escape or encode these characters ourselves.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.