xpages: custom addOnLoad event on my xpage - xpages

The scenario:
Clicking on a link, I'm accessing an xpage, let say: start.xsp.
I've added the following script to this .xsp:
<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[
XSP.addOnLoad(function(){
XSP.openDialog("#{id:dialogSearch}")
});
]]></xp:this.value>
</xp:scriptBlock>
So, every time this .xsp is loaded, a dialog is showing up. The problem is the current start.xsp is being refreshed/loaded many times, considering the fact that the xpage have numerous fields/controls on it. It is uncomfortable every time this start.xsp is loaded / refreshed the dialog to show up.
Is it possible to show the dialog after the start.xsp is loaded but ONLY when the above link was clicked? I do want firstly to go to that xpage and after this to show the respective dialog.
Thanks for your time.

Set a session scope variable in your link
<xp:link
escape="true"
text="Link"
id="link1">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:
sessionScope.showDialogSearch = "yes";
context.redirectToPage("start.xsp")
}]]></xp:this.action>
</xp:eventHandler>
</xp:link>
Add a rendered attribute to your start.xsp's xp:scriptBlock
<xp:this.rendered><![CDATA[#{javascript:
var show = sessionScope.showDialogSearch;
sessionScope.remove("showDialogSearch");
return show
}]]></xp:this.rendered>
This way dialog is only be shown if start.xsp was executed from your link and only once because it gets deleted at first use in rendered attribute.

Related

XPages Dynamic Content Control: Hash does not update when clicking browser's back button

I have a very simple XPage that contains two links and a dynamic content control. If I click on the Page 1 link the hash is set to #content=page1 then I click on Page 2 link and the hash is set to #content=page2. Now I click the browser's back button and the facet switches to page1 but the hash stays at #content=page2 and the browser's forward button is grayed out. It looks like the URL flickers to me so it might be getting overwritten but I can't say for sure.
I am using Extension Library version 901v00_16.20160128-1014 and I have tested using Chrome and Firefox.
My XPage:
<xp:link escape="true" styleClass="list-group-item" text="Page 1" id="link1">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" id="eventHandler2" refreshId="dynamicContent1">
<xp:this.action><![CDATA[#{javascript:var c = getComponent("dynamicContent1"); c.show("page1")}]]></xp:this.action>
</xp:eventHandler>
</xp:link>
<xp:link escape="true" styleClass="list-group-item" text="Page 2" id="link2">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" id="eventHandler1" refreshId="dynamicContent1">
<xp:this.action><![CDATA[#{javascript:var c = getComponent("dynamicContent1"); c.show("page2")}]]></xp:this.action>
</xp:eventHandler>
</xp:link>
<xe:dynamicContent id="dynamicContent1" partialEvents="true" useHash="true" defaultFacet="page1">
<xp:this.facets>
<xp:div id="page1" xp:key="page1">Page 1</xp:div>
<xp:div id="page2" xp:key="page2">Page 2</xp:div>
</xp:this.facets>
</xe:dynamicContent>
I have been using the Extension Library Demo database: Core_DynamicPage.xsp page as a reference and this seems to works fine in there.
After changing my xsp property for "Minimum Supported Release" from "Release 9.0.1" to "Minimum release required by the XPage features used" the issue went away.

XPages:dialog box refreshing a panel on close

I have a document that contains a rating custom control (xInvolve, which is excellent!). In this application, administrators want the ability to delete certain ratings for a certain document or all of them (bad ratings on purpose, new version of the document, corrections made to the document ...).
I am showing up the ratings in a view, in a dialog box (the extension Library dialog box, not a Dojo one). In that dialog box, I have a "Delete All" button. That button calls a SSJS function that deletes the rating documents for the document that is currently opened, but I want to refresh the panel that displays the rating, as it should now be empty.
So far, I was able to close the dialog box, but I can't seem to get the panel to refresh. Here's the code for the "Delete All" button:
<xp:button value="Delete All" id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:confirm
message="Are you sure you want to proceed?">
</xp:confirm>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:deleteAllRatings(pageDocument.getDocument().getUniversalID());
var c = getComponent("dialogPageRatings");
c.hide("PanelHeader")}]]></xp:this.script>
</xp:executeScript>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>
The PanelHeader is the panel where the xRating control is inserted.
Should I try putting code in the onClose event of the dialog box? I tried but I didn't get more luck.
Thanks
So you can use client side code to achieve this. This is what we do:
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:var strClientCode = "$('#editDeliveryAddressDialog').modal('hide'); window.location.reload();"
view.postScript(strClientCode);}]]></xp:this.script>
</xp:executeScript>
Hope it helps.
Ben,
Here is a solution using the RPC control. This control allows you to call server code directly from clientside javascript. I have frequently used it to call java methods, but haven't used it to call a SSJS function in a library. I make the assumption that it would work the same.
<xe:jsonRpcService id="jsonRpcService1" serviceName="myRPC"
pathInfo="rpc">
<xe:this.methods>
<xe:remoteMethod name="callDeleteAllRatings">
<xe:this.script><![CDATA[deleteAllRatings(universalID)}]]></xe:this.script>
<xe:this.arguments>
<xe:remoteMethodArg name="universalID" type="string" />
</xe:this.arguments>
</xe:remoteMethod>
</xe:this.methods>
</xe:jsonRpcService>
You would not be able to use getComponent in the RPC, so you would need to pass the UNID. You could pass this to the clientside using a <xp:hiddenInput> when you launch the window. You would close the window in the same manner that you do now (I think).
To call the method of the service, you would use myRPC.callDeleteAllRatings("Open ATM", ""); Again, you call the RPC from clientside.
IMO, once you learn what the RPC can do for you, you wonder how you made due without it.
As Mark suggested in a comment above, you should be able to use the onHide property. For example if you wanted to refresh a panel with serverSide id panel1
<xe:dialog id="dialog1" title="Example Dialog"
onHide=" XSP.partialRefreshGet('#{id:panel1}'); ">
This is working for me
Can you not just do a partial refresh? I do that with a simple dialog like so...
<xp:button value="Save and Close" id="button2" styleClass="btn btn-primary">
<xp:eventHandler event="onclick"
submit="true" refreshMode="partial"
refreshId="panelRefresh"
disableValidators="true"
onComplete="$('#myModal').modal('hide');">
<xp:this.action><![CDATA[#{javascript:var value:string=getComponent("inputText1").value;
document1.replaceItemValue("modalTest",value)}]]>
</xp:this.action>
</xp:eventHandler>
</xp:button>

Setting focus to first field of a tab on a tabbed table

When a user clicks on a tab of a tabbed table, I want to be able to set the focus tot the first field on that tab.
Each tab seems to only have one event mouse onclick. So I tried placing the following code in one of that tab's onclick events.
var f = dojo.byId('#{id:NotInvitedMsg}');
if (f != null)
f.focus();
But when I click on the tab nothing happens. And I mean nothing. The tab can no longer be selected and the script is never executed.
Any way around this?
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:tabbedPanel id="tabbedPanel1">
<xp:tabPanel label="New Tab" id="tabPanel1">
<xp:panel>
<xp:inputText id="inputText1"></xp:inputText>
<xp:eventHandler event="onClientLoad" submit="false">
<xp:this.script><![CDATA[var edit = dojo.byId("#{id:inputText1}");
if (edit) {
edit.focus()
}]]></xp:this.script>
</xp:eventHandler>
</xp:panel>
</xp:tabPanel>
<xp:tabPanel label="New Tab2" id="tabPanel2">
<xp:panel>
<xp:inputText id="inputText2"></xp:inputText>
<xp:eventHandler event="onClientLoad" submit="false">
<xp:this.script><![CDATA[var edit = dojo.byId("#{id:inputText2}");
if (edit) {
edit.focus()
}]]></xp:this.script>
</xp:eventHandler>
</xp:panel>
</xp:tabPanel>
</xp:tabbedPanel>
</xp:view>
This is working code (tested on Chrome and IE9). It uses simple trick I saw few days ago (and I want to apologize to original author, I couldn't manage to find the original post): to create onClientLoad event at XP/CC level, and to move event handler in source view into the panel body. Works like charm...
Try the HTML5 Autofocus attribute:
<xp:inputText id="field1" value="#{document.Field1}">
<xp:this.attrs>
<xp:attr name="autofocus" value="autofocus"></xp:attr>
</xp:this.attrs>
</xp:inputText>
One caveat: The autofocus attribute is supported in all major browsers, except Internet Explorer.
This might not be exactly what you´re looking for, but maybe it can be of some help..
Link -> How can I set focus to Edit Box inside repeat control?

ExtLib Mobile Controls - How to build a button to switch to an appPage

I'm working on an XPage for mobile users for an existing application. I want to use the mobile controls from the ExtLib for this.
I've build an XPage with a SinglePageApp and some AppPages on it. Now I want to build an AppPage with a search menu, a simple inputText and a button to start the search.
The inputText is bind to a sessionScope variable. I want to use the variable in a second appPage to get the search value and show a filtered/searched view.
The problem is the button. I'm not sure how to build this button to move to the other appPage. This is my last attempt, which fails with a runtime error.
Any idea how to get this running or what's wrong ?
Kind regards
Ingo
<xe:appPage id="appPage34" pageName="searchPage" preload="true" resetContent="true">
<xe:djxmHeading id="djxmHeading34" label="Search..." back="Home" moveTo="home">
</xe:djxmHeading>
<xp:inputText id="searchInput" value="#{sessionScope.searchValue}">
</xp:inputText>
<xp:button value="Search" id="button1" refreshMode="complete" type="submit">
<xp:eventHandler event="onclick" submit="true">
<xp:this.action>
<xe:moveTo targetPage="#searchResult"></xe:moveTo>
</xp:this.action>
</xp:eventHandler>
</xp:button>
</xe:appPage>
What does the runtime error say?
If you can not get to the XPages log files on the server directly, then use XPages Log File Reader from OpenNTF to get easy access to the log files from a browser.
Does it work if you use "searchResult" as the value for targetPage (assuming the appPage is called "searchResult")?
I've now come to a solution with a static line item instead of a button, since I couldn't get the button working. I think it has something to do with the way the single page application handles the access to mobile pages.
The search page looks like this :
<xe:appPage id="appPage34" pageName="searchPage" preload="true" resetContent="true">
<xe:djxmHeading id="djxmHeading34" label="Search..." back="Home" moveTo="home">
</xe:djxmHeading>
<xp:inputText id="searchInput" value="#{sessionScope.searchValue}">
<xp:eventHandler event="onblur" submit="true" refreshMode="complete">
<xp:this.action>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:var svalue = getComponent("searchInput").getValue(); sessionScope.put("searchValue",svalue);}]]></xp:this.script>
</xp:executeScript>
</xp:this.action>
</xp:eventHandler>
</xp:inputText>
<xp:br></xp:br>
<xp:br></xp:br>
<xe:djxmLineItem id="djxmLineItem41" label="Start Search..." moveTo="#searchResult">
</xe:djxmLineItem>
</xe:appPage>
In the mobile page for showing the search result I simply get the value of the sessionScope variable, issue a full text search with the value and use the resulting document collection in a repeat control.
I still would rather use a button because the static line item is not really what a user expects as a gui element to start the search. But at least this is working.

onclick event of a radiobuttongroup does not fire after clearing sessionscope variables

Below is a simple Xpage with a radiobuttongroup that is bound to a sessionScope variable. The onclick event of the radio button group sets the computed field. There is an afterPageLoad event to initialize the session scope variable.
All works great. However, if I clear the session Scope variables (using the debug custom control) then the onclick event never fires. The user can click on the radio button all they want and the computed field never changes until the page is reloaded by pressing F5. Below is my page source. Any suggestions on how to get the onclick event to fire? This would be a big usability issue if the user let the session variables time out and then starting clicking on the radio button.
Howard
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.afterPageLoad><![CDATA[#{javascript:print("starting the afterPageLoad event");
if (sessionScope.init != true|| sessionScope.radioData == null){
//setup default values'
print("initing the value");
sessionScope.init = true;
sessionScope.radioData = "Red";
}
}]]></xp:this.afterPageLoad>
<xp:radioGroup id="radioButtons" value="#{sessionScope.radioData}">
<xp:selectItem itemLabel="Red"></xp:selectItem>
<xp:selectItem itemLabel="Green"></xp:selectItem>
<xp:selectItem itemLabel="Blue"></xp:selectItem>
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="computedField1">
<xp:this.action><![CDATA[#{javascript:print("starting onclick event");
if (sessionScope.init != true){
print("reload the page");
context.reloadPage();
}
var radioval = getComponent("radioButtons").getValue();
getComponent("computedField1").setValue(radioval); }]]></xp:this.action>
</xp:eventHandler></xp:radioGroup>
<xp:text escape="true" id="computedField1"></xp:text></xp:view>
I've seen this same behavior several times in my own xpage apps, and I've found that the problem happens only for partial page refreshes where the target refreshId is not large enough in scope to reload all of the data needed by the control. When I change the refreshId to the page's main div (or use full page refresh), then all works as expected.
I think that it's the call to location.reload in the client-side code which is actually fixing your issue. I'd be interested to learn if increasing the scope of refreshId also fixes the problem.

Resources