Can pagerControls have onclick events? - xpages

I've got a dynamic view that totals what's displayed on the screen using a viewScope variable and I want to have it reset my viewScope variable. It doesn't and it appears not to be executing any script I put in there.
<xp:pager partialRefresh="true" id="upperPager"
for="viewRowRepeat" styleClass="tsDynamicViewPager" pageCount="8"
alwaysCalculateLast="true">
<xp:pagerControl id="pagerControl4" type="First">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="viewRowRepeat">
<xp:this.action><![CDATA[#{javascript:dBar.info("pagerControl4 clicked");
clearColumnTotals();}]]></xp:this.action>
<xp:this.script><![CDATA[alert("Clicked!");]]></xp:this.script>
</xp:eventHandler>
</xp:pagerControl>
<xp:pagerControl id="pagerControl5" type="Group">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:dBar.info("pagerControl5 clicked");
clearColumnTotals();}]]></xp:this.action>
<xp:this.script><![CDATA[alert("Clicked!");]]></xp:this.script>
</xp:eventHandler>
</xp:pagerControl>
<xp:pagerControl id="pagerControl6" type="Last">
<xp:eventHandler event="onclick"
submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:dBar.info("pagerControl6 clicked");
clearColumnTotals();}]]></xp:this.action>
<xp:this.script><![CDATA[alert("Clicked!");]]></xp:this.script>
</xp:eventHandler>
</xp:pagerControl>
</xp:pager>
Needless to say, I don't know if I've coded it incorrrectly or if there isn't supposed to be any onclick event for pagerControls. I know the IDE doesn't show one for pagers themselves.

Connect your pager controls with a Dojo onclick event to execute client side code when pager control is clicked:
<xp:eventHandler
event="onClientLoad"
submit="false">
<xp:this.script><![CDATA[
dojo.query(".xspFirst").forEach(function(node) {
dojo.connect(node, "onclick", function() {
alert("First clicked");
});
});
dojo.query(".xspGroup").forEach(function(node) {
dojo.connect(node, "onclick", function() {
alert("Group clicked");
});
});
...
]]>
</xp:this.script>
</xp:eventHandler>
Classes rendered for pager controls are "xsp" + type like "xspFirst", "xspGroup" and "xspLast". Use this classes to get the controls.

Related

How do you make the onStart and onComplete events work for the xp:pager

I use a full page overlay to display a Loading mask for my XPages. This works fine for most xp controls, buttons, combo boxes, checkboxes etc by adding CSJS to call the overlay on the onStart() and onComplete() events of the event handler. However this does not work with the xp:Pager control. The onStart and onComplete events are available for each part of the pager but they do not seem to activate. I have some big repeat controls whereby the pager refresh can take several seconds so having the overlay is essential to let the user know the pager is working.
I have added my code to the onStart and onComplete of the xp:Pager elements but they simply do not run. The loader works for all other xp elements. I have tried partial refresh and Full Update but neither cause the onStart and onComplete events to trigger?
<xp:pager partialRefresh="true" id="pager1" for="displayData">
<xp:pagerControl type="First" id="pagerControl1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="questionBlock"
onStart="makeButtonInactive('','');" onComplete="makeButtonActive('','');">
</xp:eventHandler>
</xp:pagerControl>
<xp:pagerControl type="Previous" id="pagerControl2">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="pagerControl1" onStart="makeButtonInactive('','');"
onComplete="makeButtonActive('','');">
</xp:eventHandler>
</xp:pagerControl>
<xp:pagerControl type="Group" id="pagerControl3">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="pagerControl1" onStart="makeButtonInactive('','');"
onComplete="makeButtonActive('','');">
</xp:eventHandler>
</xp:pagerControl>
<xp:pagerControl type="Next" id="pagerControl5">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="pagerControl1" onStart="makeButtonInactive('','');"
onComplete="makeButtonActive('','');">
</xp:eventHandler>
</xp:pagerControl>
<xp:pagerControl type="Last" id="pagerControl6">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="pagerControl1" onStart="makeButtonInactive('','');"
onComplete="makeButtonActive('','');">
</xp:eventHandler>
</xp:pagerControl>
</xp:pager>
The makeButtonActive() and makeButtonInactive() functions simply CSJS functions to display a page overlay or an individual button overlay. In this care I am trying to do a full page overlay so the only code that will run is
onStart(document.getElementById("overlay").style.display = "block";)
and
onComplete(document.getElementById("overlay").style.display = "none";)
the full funtions are
function makeButtonActive(btnId, innerId) {
if (btnId=="") {
document.getElementById("overlay").style.display = "none"; //Full Page
} else {
document.getElementById(btnId).disabled=false; //Button Only
document.getElementById(innerId).className=tmpclassName;
}
}
and
function makeButtonInactive(btnId, innerId) {
if (btnId=="") {
document.getElementById("overlay").style.display = "block"; //Full Page
} else {
document.getElementById(btnId).disabled=true; //Button Only
tmpclassName=document.getElementById(innerId).className;
document.getElementById(innerId).className="glyphicon glyphicon-refresh gly-sm gly-spin";
}
}
Most developers I know use Fredrik Norling's Standby Dialog Custom control from OpenNTF. You might be able to work out what's different by cross-referencing, or it might be easier to just use this instead.
If you're using a bootstrap theme, use this one. If you're using OneUI or non-standard theme, use this one.

put tabPanel forward: best method?

i tried this with sessionScope (didn't work):
The following Tabs should be controllable with the help of variable 'm1':
<xp:tabbedPanel id="tabbedPanel1"
selectedTab="#{javascript:sessionScope.get('m1')}">
<xp:tabPanel label="Config" id="conf">
<xc:k_conf></xc:k_conf>
</xp:tabPanel>
<xp:tabPanel label="Solution" id="sol">
<xc:k_sol></xc:k_sol>
</xp:tabPanel>
</xp:tabbedPanel>
In Control k_conf is a button 'calculate' which performs an agent and then sets the varable 'm1' to 'sol'.
I would expect, that the Tab switches to 'Solution', but nothing happens (although refreshmode="complete").
<xp:button value="calculate" id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
...
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:
...
agent.runWithDocumentContext(docVG.getDocument());
sessionScope.put("m1","sol");
}]]>
</xp:this.script>
</xp:executeScript>
...
</xp:button>
Another approach was to use component (didn't work because 'show is not allowed for TabPanel'):
<xp:this.action>
<![CDATA[#{javascript:
var c = getComponent("IdofTab");
c.show("IdofTab");
}]]>
</xp:this.action>
That sessionScope approach should work, I just tried it and verified that. Is there some CSJS part to the button eventHandler that is not returning true and thus preventing the SSJS executeScript from being performed?
For the second approach, you can use the setSelectedTab method of the tabbed panel rather than show, for example:
<xp:button id="button2" value="Change Tab 4">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<![CDATA[#{javascript:
var c = getComponent("tabbedPanel1");
c.setSelectedTab("tabPanel4");
}]]>
</xp:this.action>
</xp:eventHandler>
</xp:button>

XPages Dialog boxes stacking

I got the problem, that my dialog boxes are stacking each time I click the button that opens the dialog. So if I've clicked three times I get this:
I couldn't find out how to prevent this. No matter which button I click (OK does a partial refresh | Abbrechen (Cancel) does a full update) I get another box each time I click the button.
Code of the button that opens the dialog:
<xp:button value="Plan meeting" id="buttonPlanMeeting">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:try {
var c = getComponent("dPlanMeeting")
c.show();
} catch(e) {
dBar.error(location + e);
}}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
Code for the complete dialog box:
<xe:dialog id="dPlanMeeting" title="Plan meeting" keepComponents="true">
<xp:panel>
<xp:text escape="true" id="MBPlanMeeting">
<xp:this.value><![CDATA[#{javascript:specialstrings.getString("ccEsgDocWflContentEditInfos.dPlanMeeting.MBPlanMeeting")}]]></xp:this.value>
</xp:text>
</xp:panel>
<xe:dialogButtonBar>
<xp:button value="Ok" id="buttonDelegateOk" styleClass="lotusFormButton">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:try {
//will create a meeting for every day the visit is registered
var wfDoc:NotesDocument = docApplication.getDocument(true);
specialMeetingCreate(wfDoc);
var c = getComponent("dPlanMeeting");
c.hide();
var c = getComponent("dMeetingCreated")
c.show();
} catch (e) {
dBar.error(location + e);
}
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button value="Cancel" id="buttonDelegateCancel" styleClass="lotusFormButton">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:try {
var c = getComponent("dPlanMeeting");
c.hide();
} catch (e) {
dBar.error(location + e);
}
}]]></xp:this.action>
</xp:eventHandler></xp:button>
</xe:dialogButtonBar>
</xe:dialog>
Does this have anything to do with keepComponents? I've tried true and false, but the effect stays the same.
Any idea?
Ok it seems that the solution was just to set "keepComponents = false". I've tried that before, but now it'S working. I get the dialog box only once no matter how often I click the button

XPages How to use an action in an Action Group to stop form submission

I have a button built on an Action Group. I would like to have an action to stop processing the button -- stop the next actions from firing.
I tried a Confirm Action, but the user can click OK and it will continue. I tried an Execute Script that returns false, but that did not do anything.
I have been reading about event handlers, but not sure how to incorporate this in the button's code itself.
Here is the current code behind the button:
<xp:button id="button1" value="Create Account">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete" id="eventHandler1">
<xp:this.action>
<xp:actionGroup>
<xp:modifyField
name="ac_Key" value="#{javascript:#Unique()}"
var="document1">
</xp:modifyField>
<xp:saveDocument></xp:saveDocument>
<xp:openPage
name="/successAccount.xsp">
</xp:openPage>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>
Thanks for all your help!
This simple example uses the confirm action to only continue if the user selects OK. If the user clicks cancel, nothing further happens. If the user clicks OK, the browser opens the index.xsp page.
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:confirm message="Sure?"></xp:confirm>
<xp:openPage name="/index.xsp"></xp:openPage>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>
Update: This example uses a condition on the actionGroup that can prevent the actionGroup from executing if the condition is false:
<xp:actionGroup condition="#{javascript:validateSomething()}">
<xp:save name="/opskrifter.xsp"></xp:save>
</xp:actionGroup>

by clicking on one button invoke two other buttons

I would like by clicking on a button to "activate" the clicking of 2 other buttons.
I've put this ccjs in the onclick event:
document.getElementById("#{id:button28}").click();document.getElementById("#{id:button29}").click();
But then only button 28 gets clicked !
Then I tried putting this part1 of the code under the onclick event and part2 under the onmousedown event. Then I have to click 2 times this button before he actually does the job.
the code so far:
<xp:button value="Save" id="button26">
<xp:eventHandler event="onclick" submit="false">
<xp:this.script>
<xp:executeClientScript>
<xp:this.script><![CDATA[document.getElementById("#{id:button29}").click();
></xp:this.script>
</xp:executeClientScript>
</xp:this.script></xp:eventHandler></xp:button><xp:button id="button29" value="button29">
<xp:eventHandler
event="onclick" submit="true" refreshMode="partial"
id="eventHandler21" refreshId="outsidePanel5">
<xp:this.action>
<xp:actionGroup>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:sessionScope.put("test","");// and some more code}]]>
</xp:this.script>
</xp:executeScript>
</xp:actionGroup>
</xp:this.action>
<xp:this.onComplete><![CDATA[document.getElementById("#{id:button28}").click();]]></xp:this.onComplete>
</xp:eventHandler></xp:button><xp:button value="button28" id="button28">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="outsideMogelijkheid">
<xp:this.action>
<xp:executeScript
script="#{javascript://some code}">
</xp:executeScript>
</xp:this.action>
</xp:eventHandler></xp:button>
If you want to run the SSJS in another button, you can actually call the eventHandler programmatically rather than triggering the button in CSJS. This will also perform better, because you're not switching between CSJS and SSJS all the time. The following code should work:
var eventHandler:com.ibm.xsp.component.xp.XspEventHandler = getComponent("button29");
eventHandler.getAction().invoke(facesContext, null);
eventHandler = getComponent("button28");
eventHandler.getAction().invoke(facesContext, null);
If these buttons execute SSJS code you need to add the code to click on the second button in the
onComplete event of the first button.
http://xpagesblog.com/XPagesHome.nsf/Entry.xsp?documentId=0574D334CB03EACF852578CB00667F54
Addition
Working example of onComplete not that it only works with partial refresh
<xp:button value="Save" id="button26">
<xp:eventHandler event="onclick" submit="false">
<xp:this.script><![CDATA[document.getElementById("#{id:button29}").click()]]>
</xp:this.script>
</xp:eventHandler></xp:button>
<xp:button id="button29" value="button29">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="computedField1">
<xp:this.action><![CDATA[#{javascript:viewScope.test="Almost Done"}]]>
</xp:this.action>
<xp:this.onComplete>
<![CDATA[document.getElementById("#{id:button28}").click();]]>
</xp:this.onComplete>
<xp:this.onError><![CDATA[alert("error")]]></xp:this.onError>
</xp:eventHandler></xp:button>
<xp:button value="button28" id="button28">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="computedField1">
<xp:this.script><![CDATA[alert("Button 28")]]></xp:this.script>
<xp:this.action>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:viewScope.test="Done"}]]>
</xp:this.script>
</xp:executeScript>
</xp:this.action></xp:eventHandler>
</xp:button>
<xp:br></xp:br>
<xp:text escape="true" id="computedField1" value="#{viewScope.test}"></xp:text>

Resources