xpages button - possible to change text or item while events are running? - xpages

Is it possible to change the text on an <xp:button> element when the code under the onclick event is running (and the partial refresh is not completed)?

The XPages way is to use the onStart and onComplete properties (there's also onError):
<xp:button value="Search" id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial"
onStart="changeText()" onComplete="unchangeText()">
<xp:this.action><![CDATA[#{javascript:serverFunction();}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
You can pass the id of the button to the functions using "#{id:button1}" and use it to retrieve the button in CSJS.

We have something like that in place for our xp:button elements. We change the text and also add an FontAwesome "spinning wheel" until code is finished. At the start of our funtion we change text and icon, after code is finished - we revert to original xp:button text.
We use jQuery to modify the button element, basically you can to that with plain JavaScript (innerHTML) or dojo as well.
<xp:button value="Save" id="button-save" xp:key="submitSave">
<xp:eventHandler event="onclick" submit="false">
<xp:this.script><![CDATA[submitSaveFunction();]]></xp:this.script>
</xp:eventHandler>
</xp:button>
submitSaveFunction {
$("button[id$=button-save]").attr("disabled", "true").addClass("disabled").html('<i class="fa fa-spinner fa-pulse fa-fw"></i> Saving');
.....your code.....
$("button[id$=button-save]").removeAttr("disabled").removeClass("disabled").html('Save');
}

Related

SSJS code is not executed in XPages onclick

In my code I have the following Event Handler
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" disableValidators="true"
refreshId="#{javascript:compositeData.refreshid}">
<xp:this.script><![CDATA[
alert('clicked');
]]></xp:this.script>
<xp:this.action><![CDATA[#{javascript:print("jkafkjsfjk");}]]></xp:this.action>
</xp:eventHandler>
Unfortunately, I never get jkafkjsfjk printed in the console while CSJS code works fine and there's clicked alert pops up.
I know that the most common reason of not executing it has to do with some required fields equal to null or empty.
However, I've commented everything out but the code isn't executed anyway..
How do I resolve that and what's the reason?
Thanks in advance.
A couple of things...
First, if your CSJS returns false then the SSJS never runs (which is handy when you want the user to confirm...). I guess you should be alright here - but you could return true to be safe....
Second, partial refresh's, refresh ids, and partial executions can do things that may not be what you expect. So for the test I would just do a complete refresh and skip the id.
What kind of object is the eventhandler set on?
I normally use these kind of event handlers for links or buttons like:
<xp:button value="Add zone" id="button2" styleClass="btn-xs btn-primary">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="fields">
<xp:this.action><![CDATA[#{javascript:AssociationAdmin.createZone()}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
And this works fine :-)
Here is an example with a confirmation first:
<xp:link escape="true" text="Delete" id="link5" styleClass="action" rendered="#{javascript:!AssociationAdmin.isCatchInfoInUse(row.getKey())}">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete" id="eventHandler5">
<xp:this.action><![CDATA[#{javascript:AssociationAdmin.removeCatchInfo(row.key);}]]></xp:this.action>
<xp:this.script><![CDATA[return window.confirm("Are you sure you want to delete these fields: #{javascript:row.getName()}?\n\nDeletion cannot be undone!!")]]></xp:this.script>
</xp:eventHandler>
</xp:link>
Further notes:
You may want to submit without validating. You can do this by adding disableValidators="true" to your eventhandler
Please remember to have an id on the control where you have your eventhandler. Just wasted an evening and morning with the most strange behaviour cased by the button opening dialog did NOT have and id attributee...
Hope these samples will get you going :-)
/John

xpages - partial refresh from dialogbox does not seem to work on repeat control. from outside the dialogbox it works

In an xp:dialog I have a button which loads back-end data and closes the dialog.
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick"
submit="true" refreshMode="partial" refreshId="rptContainer">
<xp:this.action><![CDATA[#{javascript:
//load data. will not add the code for that but works fine;
viewScope.put("customers",promoBean.getCampaign().getCustomers());
getComponent("dlgCampaign").hide();}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
On the event I have set partial refresh on a xp:panel control that contains a repeat control that is data-binded to viewScope.
<xp:panel id="rptContainer">
<xp:repeat id="rptCustomers" var="obj" indexVar="index" value="#{viewScope.customers}">...
With help of the xpages debug toolbar I see that the viewScope from the button in the dialog is being updated. but when the dialog is closed the changes are not visible in the repeat control.
I have placed a button outside the dialogbox which only performs the partial refresh and then the repeat control renders the changes.
Can anyone explain me how I can update the repeat control from within the dialog box?
I tried the onHide property of the dialog and used as code:
XSP.partialRefreshGet('#{id:rptContainer}');
But this has no effect.
I even tried a full update for the button event but this has also no result.
Can someone guide me how to do it the proper way?
when I close a dialogbox through SSJS, I close it using following syntax:
<xp:button value="OK" id="btnOK">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:/*your processing code*/
var dialogBox = getComponent('/*id of the dialog to close*/');
dialogBox.hide('/*id of the component to refresh*/');}]]>
</xp:this.action>
</xp:eventHandler>
</xp:button>
Although the refresh mode is 'complete', only the component in the 'hide' method is refreshed.

POI 4 XPages - document generation works only once

Ok, to be honest: the headline doesn't tell the whole truth. I am using a custom control with several buttons (save, close, edit etc.) and a button that executes a POI action - it's generates a Word file.
I experience a problem here: after hitting the POI-button my other buttons (and the POI one as well) won't work anymore, no click is triggered.
Now the strange one: after waiting a few seconds (depending on which browser I use, Chrome is fastest) I am able to click the buttons (all of them) again so that I can e.g. leave (close) or edit my Xpage.
I don't know if that helps but here is the event code of my POI button:
<xp:button id="button5" styleClass="btn btn-sm printbutton"
style="display:none">
<i class="fa fa-print"></i>
 
<xp:text>
<xp:this.value><![CDATA[#{javascript:"Nach MS Word exportieren"}]]></xp:this.value>
</xp:text>
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp_1:generateDocument documentId="wordprint"
loaded="true">
</xp_1:generateDocument>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>
Any ideas how to avoid this behavior or is it a bug in POI 4 XPages?
BTW: I am not able to execute another action right after getting the Word document, e.g. execute a script or open a page. That would be also an acceptable way to close the xpages after "printing".
Thanks in advance!
Oliver, add the client-side JS call XSP.allowSubmit() to your button in order to allow new submits after pressing the button:
<xp:button id="button5" styleClass="btn btn-sm printbutton" style="display:none">
<i class="fa fa-print"></i>
 
<xp:text>
<xp:this.value><![CDATA[#{javascript:"Nach MS Word exportieren"}]]></xp:this.value>
</xp:text>
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp_1:generateDocument documentId="wordprint"
loaded="true">
</xp_1:generateDocument>
</xp:actionGroup>
</xp:this.action>
<xp:this.script><![CDATA[XSP.allowSubmit()]]></xp:this.script>
</xp:eventHandler>
</xp:button>
I believe the issue is you're generating the word document from the button on the same page.
Do the generation from an XAgent. Have the button call the XPage containing the XAgent and you should be fine.

Button to save document doesn't work as expected

I would like my "save" button to make a change in the document, to save the document , to give a confirmation message, and to refresh.
When using the following code on an iPhone I have to click 2 times before getting the confirmation message and the document doesn't refresh. When using the same code in Google chrome I get the confirmation message after 1 click, but the document or page also doesn't refresh. What's wrong?
<xp:button value="Save" id="button1" style="mybutton;font-size:14pt;font-family:Arial">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:executeScript>
<xp:this.script>
<![CDATA[#{javascript:value1 = viewScope.get("client");
document1.replaceItemValue("visNrClient",value1);}]]>
</xp:this.script>
</xp:executeScript>
<xp:saveDocument var="document1"></xp:saveDocument>
<xp:confirm message="SAVED !!"></xp:confirm>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>
Are you moving from the same component in both cases? If you have onblur or onchange code on the component you were in, if that triggers a partial refresh, that will run and take precedence over the button click event, which would explain the need to click twice.

Is it possible to programmatically set the partial refresh element for an event?

I have a custom control I use for view filtering and I'd like to set the viewPanel that it filters based on a property of the custom control but in order to do this I would need to partially refresh the viewPanel whatever the ID of that viewPanel is. I know I could put a facet in my custom control and put a panel around the facet and then just partially refresh that panel, but I was wondering if there is a way to do this without having to drop the viewPanel into a facet. Here is the button code:
<xp:button value="Filter" id="btnFilter">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="viewPanel1">
<xp:this.action><![CDATA[#{javascript:filterView();}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
Thanks
Oops, just realized I could do this by adding a computed element ID for the partial refresh set to the compositeData value. I missed that little triangle next to "Specify Element ID".
<xp:button value="Filter" id="btnFilter"> <xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="#{javascript:compositeData.viewPanel}">
<xp:this.action><![CDATA[#{javascript:filterView();}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
You could use the dynamic viewpanel of the extension library.

Resources