Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

compositeData of custom control is undefined in beforeRenderResponse event

Tags:

xpages

When passing data to a custom control, I have always used the compositeData object to access this data from inside the control. This is working fine, except for the beforeRenderResponse event of the custom control. Take this code as an example:

<xp:this.afterPageLoad><![CDATA[#{javascript:getComponent("lbl0").setValue(typeof(compositeData));}]]></xp:this.afterPageLoad>
<xp:this.beforeRenderResponse><![CDATA[#{javascript:getComponent("lbl1").setValue(typeof(compositeData));}]]></xp:this.beforeRenderResponse>
<xp:label value="" id="lbl0"/>
<xp:label value="" id="lbl1"/>

In the afterPageLoad event, the typeof of the compositeData is "com.ibm.xsp.binding.PropertyMap". Yet in the beforeRenderResponse event, the same typeof returns "undefined".

How can I access the compositeData in the beforeRenderResponse event?

like image 250
xpages-noob Avatar asked Feb 09 '13 16:02

xpages-noob


1 Answers

In beforePageLoad or afterPageLoad create a SSJS variable with a reference to the compositeData:

<xp:this.beforePageLoad>
   <![CDATA[#{javascript:
      var hlp=compositeData;
   }]]>
</xp:this.beforePageLoad>

This allows you to access the PropertyMap during the Rendering Phase. If you have a property test you can then acces it this way:

<xp:this.afterRenderResponse>
   <![CDATA[#{javascript:
      print( hlp.test );
   }]]>
</xp:this.afterRenderResponse>

EDIT: This works only if the page is opened (pageLoad). If you refresh the page, this won't work. If it has to run with partial refreshs, you have to do this:

First, you have to add an ID to your custom control:

<xc:ccWithId test="I am your property" id="ccWithId" />

This allows you to access the custom control as a regular component with getComponent(). Now you can access the propertyMap of the component in the custom control's event which holds the variable you want:

<xp:this.beforeRenderResponse>
   <![CDATA[#{javascript:
      var cmp:com.ibm.xsp.component.UIIncludeComposite = getComponent("ccWithId");
      print("Value of 'test' -> " + cmp.getPropertyMap().getString("test") )
   }]]>
</xp:this.beforeRenderResponse>

EDIT by xpages-noob: The example from above works fine for static custom control properties. However, in case a property is computed, the various get functions of the property map return a value binding object instead of the value itself. Hence, one can use the following function as a workaround:

 var thisData:com.ibm.xsp.binding.PropertyMap=getComponent("ccWithId").getPropertyMap();
function getPara(key) {
    var x=thisData.get(key);
    if (@Ends(typeof(x),"ValueBinding")) return x.getValue(facesContext);
    else return x
}

If you want to, for example, get the property "test", call getPara("test"). The returned value should be equal to compositeData.test.

like image 154
Sven Hasselbach Avatar answered Nov 13 '22 07:11

Sven Hasselbach