Updating Multiple Elements on ComboBox change
When a combo box changes, you can trigger the onChange event to run server-side JavaScript and refresh one element of the page. It looks like this in your source:<xp:comboBox id="comboBox1" value="#{document.ComboBox}" defaultValue="One">
<xp:selectItem itemLabel="One"></xp:selectItem>
<xp:selectItem itemLabel="Two"></xp:selectItem>
<xp:selectItem itemLabel="Three"></xp:selectItem>
<xp:eventHandler event="onchange" submit="true" refreshMode="partial" refreshId="dependencyOne" disableValidators="true">
</xp:eventHandler>
</xp:comboBox>
When the combo box value is changed, everything within the "dependencyOne" panel (or table, or whatever has that ID) will be refreshed. If you have a bunch of dependent fields, put them all in a panel and refresh the panel. Easy.
But I ran into a case where two things at different ends of the XPage needed to be refreshed - one at the top and the other at the bottom. Putting EVERYTHING into a panel didn't really make sense. So I had to find another way. After doing some 'net searches, I found a very elegant solution.
Let's say I have another panel called "dependencyTwo" way down at the bottom of the XPage and I want that to be refreshed as well as "dependencyOne" when the radio button changes. The way the combo box is currently coded, only "dependencyOne" will be refreshed. To make both of them be refreshed, we change from server-side JavaScript to client-side JavaScript in the onChange event and use a built-in object called XSP with a method of partialRefreshPost. This method takes either one or two parameters. The first parameter is the ID of the object to be refreshed. This means that instead of the above XPages source for the combo box, I could write this code and achieve the exact same result, only with client-side JavaScript:
<xp:comboBox id="comboBox1" value="#{document.ComboBox}" defaultValue="One">
<xp:selectItem itemLabel="One"></xp:selectItem>
<xp:selectItem itemLabel="Two"></xp:selectItem>
<xp:selectItem itemLabel="Three"></xp:selectItem>
<xp:eventHandler event="onchange" submit="false">
<xp:this.script><![CDATA[XSP.partialRefreshPost("#{id:dependencyOne}");]]></xp:this.script>
</xp:eventHandler>
</xp:comboBox>
The real power is the optional second parameter on the partialRefreshPost method. With this parameter you can include a function to execute when the post completes execution. This can then be another partialRefreshPost call with another element. So the source code becomes this:
<xp:comboBox id="comboBox1" value="#{document.ComboBox}" defaultValue="One">
<xp:selectItem itemLabel="One"></xp:selectItem>
<xp:selectItem itemLabel="Two"></xp:selectItem>
<xp:selectItem itemLabel="Three"></xp:selectItem>
<xp:eventHandler event="onchange" submit="false">
<xp:this.script><![CDATA[XSP.partialRefreshPost("#{id:dependencyOne}", {
onComplete: function() {
XSP.partialRefreshPost("#{id:dependencyTwo}");
}
});
]]></xp:this.script>
</xp:eventHandler>
</xp:comboBox>
Now, when you change the combo box, the panel with the ID of "dependencyOne" will refresh and also the panel with the ID of "dependencyTwo" will change. Pretty snazzy.