Sven Hasselbach has created an optimized version of the XSP.partialRefreshPost() method. This works great to reduce the number of form fields that are included in the request for a partialRefreshPost.
But his version does not include support for running server-side actions because the the form fields included in the POST doesn’t include the server-side event handler.
So I have created an optimized version of his optimized version that supports this 🙂
My versions adds a ‘submitid’ parameter that should point to the id of the event handler that you want to execute on the server.
XSP.partialRefreshPost(
'#{id:somePart}',
{
clearForm: true,
submitid: '#{id:submitEventHandler}'
}
);
Here’s an example of using the optimized partial refresh for an eventhandler:
<xp:button id="button1">
<xp:eventHandler event="onclick" submit="false" id="submitEventHandler" refreshMode="partial" refreshId="somePart">
<xp:this.action><![CDATA[#{javascript:someServerSideAction();}]]></xp:this.action>
<xp:this.script><![CDATA[
XSP.partialRefreshPost(
'#{id:somePart}',
{
clearForm: true,
submitid: '#{id:submitEventHandler}'
}
);
]]></xp:this.script>
</xp:eventHandler>
</xp:button>
Here’s the complete code snippet (available as an OpenNTF XSnippets too):
<xp:scriptBlock id="scriptBlockPROptimized">
<xp:this.value><![CDATA[
XSP.addOnLoad(function(){
// hijack the existing partial refresh method
if( !XSP.__partialRefresh ){
XSP.__partialRefresh = XSP._partialRefresh;
}
// add the new one to the XSP object
XSP._partialRefresh = function x_prfh(method, form, refreshId, options){
// clear the form?
if( options.clearForm ){
// create a new HTML form...
var newForm = document.createElement( "form" );
newForm.setAttribute( "method", form.method );
newForm.setAttribute( "action", form.action );
// ... and loop all existing fields
for( var i = 0; i<form.length; i++ ){
var field = form[i];
var fieldName = field.name;
var includeField = false;
try{
// check for addition fields
if( options.additionalFields ){
includeField = dojo.indexOf(options.additionalFields, fieldName)!=(-1)?true:false;
}
// only add XPages relevant fields and addtional fields
if( fieldName == form.id || fieldName.substr(0,2) == '$$' || includeField ){
var newField = null;
if( field.options ){
// special handling for fields with options
for( var j=0; j<field.length; j++ ){
if( field.options[j].selected ){
newField = document.createElement( "input" );
newField.setAttribute( "type", "hidden" );
newField.setAttribute( "name", fieldName );
newField.setAttribute( "value", field.options[j].value );
newForm.appendChild( newField );
}
}
}else{
// default field handling: just clone the DOM element
// check for $$xspsubmitid option
if( options.submitid && fieldName == "$$xspsubmitid"){
newField = document.createElement( "input" );
newField.setAttribute( "type", "hidden" );
newField.setAttribute( "name", "$$xspsubmitid" );
newField.setAttribute( "value", options.submitid );
newForm.appendChild( newField );
} else {
newField = field.cloneNode( true );
newForm.appendChild( newField );
}
}
}
}catch(e){
console.log(e);
}
}
// call the original refresh method with the new form
return XSP.__partialRefresh(method, newForm, refreshId, options);
}
XSP.__partialRefresh(method, form, refreshId, options);
};
});
]]></xp:this.value>
</xp:scriptBlock>
Keep in mind that to optimize a partial refresh you need to focus on more than just the size of the POST request. You should also look at partial execution mode (execMode=“partial”) in order to reduce the amount of work that the server has to do.