Using 8.5.3 UP1. I’m having an issue with an SSJS script library that I am using for “hide/whens” or more exactly in xpages “show/ifs”. In any case the global variables seem to take the value of the last time I saved the script library. They don’t seem to compute based on the documents current value. Is this a known thing (obviously not known to me.). Here is a sample page and script library to demonstrate the issue:
Example XPage:
<xp:this.resources>
<xp:script src="/ssjsVisTest.jss" clientSide="false"></xp:script>
</xp:this.resources>
<xp:inputText id="inputText1" value="#{document1.StatusTX}"></xp:inputText>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:button value="Save" id="SaveBtn">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:saveDocument var="document1"></xp:saveDocument>
</xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:label id="label1" value="Status is Draft"
rendered="#{javascript:statusVisibleDraft()}">
</xp:label>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:label id="label2" value="Status is Pending"
rendered="#{javascript:statusVisiblePending()}">
</xp:label>
<xp:br></xp:br>
<xp:br></xp:br>
</xp:view>
Sample SSJS script library:
var status = document1.getItemValueString('StatusTX');
function statusVisibleDraft() {
x = (status == "Draft") ? 1 : 0;
if(x > 0) {
return true;
} else {
return false;
}
}
function statusVisiblePending() {
x = (status == "Pending") ? 1 : 0;
if(x > 0) {
return true;
} else {
return false;
}
}
Any ideas? Thanks
Variables in script libraries are transient in nature. Depending on system load the libraries might get unloaded between calls. The right place for global variables are the scopes (this is what they are made for). In your example it seems the view scope would be appropriate. Also Sven is right about computation. Furthermore it is good practise not to have side dependencies. If you add another data source with a different name you can’t reuse your ssjs lib. You would hand over the data source as parameter e.g. in beforeRenderResult:
setstatusDraftVisible(document1,’Status’,’draft’)
Inside such a function you check if the field (2nd param) exists and has the value of the 3rd param and then set:
viewScope.statusDraftVisible=true; // or false
Then you have rendered=”#{JavaScript:viewscope.statusDraftVisible}”
When your application is more complex and you have a lot of these checks, you might consider a viewScope ‘backing bean’ aka managed bean. This could reduce rendered to
rendered=”#{beanName.statusDraftVisible}”
Which is faster.