I am working on application and I got stuck when I wanted to open a link on new tab or window.
I am using Lotus Notes Designer Release 8.5.2FP1.
I have attached my piece of code.
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:try{
var doc = database.getProfileDocument("frmConfiguration","");
var url = doc.getItemValueString("HeaderLink1URL");
view.postScript("var tempwindow =window.open('" +url+"','_blank');tempwindow.focus();");
}catch(e){
}}]]></xp:this.action>
Based on your updated code in comment you can simply add target="_blank" and instead of using the onClick event use the value attribute which would point to the URL to be opened. So your code would be something like this:
<xp:link escape="false" id="link1" target="_blank">
<xp:this.text>some code</xp:this.text>
<xp:this.value><![CDATA[#{javascript:var doc = database.getProfileDocument("frmConfiguration","");
var href = doc.getItemValueString("HeaderLink1URL");
return href;}]]></xp:this.value>
</xp:link>
The simpliest way to do this would be something like:
<xp:text escape="false" id="newTab"><xp:this.value><![CDATA[#{javascript:return "Google";}]]></xp:this.value></xp:text>
This will open google in a addtional tab.
Update:
If you want to use a xp:link you could try:
<xp:link escape="false" id="newTab" text="test">
<xp:this.onclick><![CDATA[var ret = window.open("http://www.google.com",'_blank');
]]></xp:this.onclick>
</xp:link>
If you want to open the link in a seperate window or tab i recomend dont use the aktion use the onclick client side event in the option tab.
Here is some sample code of opening a URL both client side and server side.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:button value="Client Side Open Button." id="ClientSideButton">
<xp:eventHandler event="onclick" submit="false">
<xp:this.script><![CDATA[var href = "http://www.ibm.com";
var tempwindow = window.open(href,'_blank');
tempwindow.focus();
]]></xp:this.script>
</xp:eventHandler>
</xp:button>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:button id="serverSideButton" value="Server Side Open Button ">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:var href = "http://www.ibm.com";
view.postScript("var tempwindow = window.open('" + href + "','_blank'); tempwindow.focus();");
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:view>
If this code does not work as expected, two things to check.
Check that the url variable is being set correctly.
Make sure you are on the latest release. window.open() didn't work as expected until 8.5.1FP2.
Related
I have the following code logging out the user from app and "send" him back to the session based authentication page ( Thanks Paul Withers ):
clearing_function(sessionScope);
var appUrl = facesContext.getExternalContext().getRequest().getContextPath();
var url = appUrl + "?logout&redirectto=" + appUrl;
facesContext.getExternalContext().redirect(url);
Is there any chance to have like a #prompt formula with yes/no and just in case if user selects yes the above code ( from ssjs ) to be executed? Or I must write the confirmation message in csjs. But, then, how can I transform the above code in csjs?
You can use the Dialog component from extension library to build a confirmation box with two buttons where the positive button runs your logout code
<xe:dialog id="dialog1">
<xp:panel>
<xp:button value="OK" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:clearing_function(sessionScope);
var appUrl = facesContext.getExternalContext().getRequest().getContextPath();
var url = appUrl + "?logout&redirectto=" + appUrl;
facesContext.getExternalContext().redirect(url);}]]></xp:this.action>
</xp:eventHandler></xp:button>
<xp:button value="Cancel" id="button2">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="dialog1">
<xp:this.action><![CDATA[#{javascript:getComponent("dialog1").hide();}]]> </xp:this.action>
</xp:eventHandler></xp:button></xp:panel>
</xe:dialog>
To hide the default x button just override the relevant css classes:
for oneui themes it's the "lotusBtnImg" class
for webstandard it's the ".dijitDialogCloseIcon" class
I have a simple form with an onchange event on a field of type inputText.
Onchange event start when I click another object. Example the save button.
The code runs but the onchange click on the Save button is lost.
I enclose the sample code of a page that reproduces the problem.
Suggestions?
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:div style="padding:20px;"></xp:div>
<xp:button value="Save" id="button1" style="margin:20px;">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:print('click');}]]></xp:this.action>
<xp:this.script><![CDATA[alert('click');]]></xp:this.script>
</xp:eventHandler>
</xp:button>
<xp:radioGroup id="radioGroup1" style="margin:20px;">
<xp:selectItem itemLabel="val1"></xp:selectItem>
<xp:selectItem itemLabel="val2"></xp:selectItem>
<xp:selectItem itemLabel="val3"></xp:selectItem>
<xp:eventHandler event="onchange" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:print('onchange - radiobutton');}]]></xp:this.action>
</xp:eventHandler>
</xp:radioGroup>
<xp:inputText id="inputText1" style="margin:20px;">
<xp:eventHandler event="onchange" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:print('onchange - start');
var millis = 10000;
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
print('onchange - finish');}]]></xp:this.action>
</xp:eventHandler>
</xp:inputText>
</xp:view>
You can do it by oninput event instead of onchange. Just change the event attribute in the eventHandler. However,
It's not supported before IE9,
Every keystroke will trigger the event which could be bad for user-experience
In case of a partial refresh, when the refresh is over, the focus will be shifted to another component if it's not the first item in the form. Again, bad for UX.
You may also fire a CSJS code on onkeyup event to focus another component on the page. Therefore it will refresh the page. You may do this with setTimeout() function therefore, if the user does not press any keys for a moment, it will fire the refresh.
Thanks for reply but I think that these solutions are not good for UX.
I think that only possible solutions are:
1 disable server onchange event and add refresh button
2 when possible use onchange client js event
Others suggestion?
Really looking for an idea why my XPage is doing this.
I have field with a dynamic databinding:
<xp:inputText id="CORE_Input" value="#{Document[compositeData.PARA_DataBinding]}"</xp:inputText>
That works quit well until I start to hide it based on a notes formula.
Let me tell what it does: I click a checkbox in my XPage. That checkbox is running SSJS which is calling: Document.getDocument(true) to push the data from my XPage back into the notesdocument without saving it. Once that is done I can use session.evaluate("checkbox!="something"") to hide the inputText field.
It works quit well but the problem is that once I untick the checkbox the value is gone from the inputfield.
If you know a better way to use notes formulas for hiding or the reason why the inputfield is empty once it comes back would be highly appreciated. Here is an example:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:checkBox id="checkBox1" value="#{Document.Check}" text="hide" checkedValue="hide">
<xp:eventHandler event="onchange" submit="false">
<xp:this.script><![CDATA[document.getElementById("#{id:hide}").click()]]></xp:this.script>
</xp:eventHandler>
</xp:checkBox>
<xp:panel id="test">
<xp:inputText id="CORE_Input" type="#{compositeData.NODE}"
value="#{Document[compositeData.PARA_DataBinding]}"
defaultValue="#{javascript:compositeData.PARA_DefaultValue}" style="margin-left:24px">
<xp:this.styleClass><![CDATA[#{javascript:DOMElement.getAttribute("stylesize");}]]></xp:this.styleClass> <xp:this.rendered><![CDATA[#{javascript:var doc:NotesXspDocument=Document;
var erg=session.evaluate('Check="hide"',doc.getDocument());
if(#Text(erg)=="1")
{return false}
else
{return true}}]]></xp:this.rendered>
</xp:inputText>
<xp:button value="hide" id="hide">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="test">
<xp:this.action>
<![CDATA[#{javascript:var doc:NotesXspDocument=Document;doc.getDocument(true)}]]></xp:this.action>
</xp:eventHandler></xp:button>
<xp:button value="unhide" id="unhide">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="test">
<xp:this.action><![CDATA[#{javascript:sessionScope.hide=""}]]></xp:this.action>
</xp:eventHandler></xp:button>
</xp:panel></xp:view>
The problem you have is your default value: As soon the component is unhidden, the value is recalculated. You have to check if the component is partially refreshed. If so, stop the recalculation:
<xp:this.defaultValue>
<![CDATA[#{javascript:
importPackage( com.ibm.xsp.ajax );
if( AjaxUtil.isAjaxPartialRefresh(facesContext) == true )
return;
compositeData.PARA_DefaultValue
}]]>
</xp:this.defaultValue>
This should solve your problem
I have a document data source (create document with no parent id) bound to a panel. Within the panel I have 2 other panels. On completing the fields in panel 1 I click a link to reveal the 2nd panel and that has a save button on it. Once saved the document appears in the db correctly.
The save buttons does a dds save and then clears all fields and does a partial update on the outer panel and a partial execute on that panel too as I have other dds on the XPage outside of my main panel.
If I now create another document the previous document gets updated rather than create a new doc. I've tried different scope for the dds and other options. Not sure what to try next.
Anyone know what the problem is?
Here is a example how you can add a new datasource with a partial refresh:
<xp:panel id="myPanel">
<xp:this.data>
<xp:dominoDocument var="document1"></xp:dominoDocument>
</xp:this.data>
<xp:br></xp:br>
<xp:inputText id="inputText1" value="#{document1.Test}"></xp:inputText>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:button value="Save" id="buttonSave">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="myPanel">
<xp:this.action>
<xp:actionGroup>
<xp:saveDocument var="document1"></xp:saveDocument>
<xp:executeScript>
<xp:this.script>
<![CDATA[#{javascript:
var panel = getComponent("myPanel");
var ds = new com.ibm.xsp.model.domino.DominoDocumentData();
ds.setComponent(panel);
ds.setVar("document1");
panel.getData().clear();
panel.addData(ds);
}]]>
</xp:this.script>
</xp:executeScript>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:panel>
Hope this helps
Sven
EDIT:
Added a clear() to remove all previous defined datasources from the panel.
That's default behaviour. If you don't want to reload the whole page one option is to get rid of the datasource and create the new doc in SSJS event when Save button is clicked.
I used Sven's answer succesfully, however, I had to add an extra line in ths server side JavaScript
<xp:executeScript>
<xp:this.script>
<![CDATA[#{javascript:
var panel = getComponent("myPanel");
var ds = new com.ibm.xsp.model.domino.DominoDocumentData();
ds.setComponent(panel);
ds.setVar("document1");
ds.setFormName('form1');
panel.getData().clear();
panel.addData(ds);
}]]>
</xp:this.script>
</xp:executeScript>
Using 8.5.3 UP1
When I save my document from a dialog box certain fields are not being populated. If I save the document from within the xpage it saves these fields just fine. Here is a simple example to illustrate the issue:
<xp:link text="Save Document By Dialog"
id="link21">
<xp:eventHandler event="onclick" submit="false">
<xp:this.script><![CDATA[XSP.openDialog("#{id:dialog1}");]]></xp:this.script>
</xp:eventHandler>
</xp:link>
<br/>
<xp:button value="Save By Button" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:saveDocument var="document1"></xp:saveDocument>
</xp:this.action>
</xp:eventHandler>
</xp:button>
<xe:dialog id="dialog1" title="Dialog">
<br />
<b>
<xp:text escape="true" id="computedField1">
<xp:this.value><![CDATA[#{javascript:"Save this document?"}]]></xp:this.value>
</xp:text>
</b>
<br />
<br />
<xp:button value="Yes" id="button7">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.script><![CDATA[XSP.closeDialog("#{id:dialog1}");]]></xp:this.script>
<xp:this.action>
<xp:saveDocument var="document1"></xp:saveDocument>
</xp:this.action></xp:eventHandler>
</xp:button>
<xp:button value="No" id="button8">
<xp:this.onclick><![CDATA[XSP.closeDialog("#{id:dialog1}");]]></xp:this.onclick>
</xp:button>
</xe:dialog>
<br/><br/>
<xp:inputText id="TitleTX" value="#{document1.TitleTX}"></xp:inputText>
<br/><br/>
<xp:inputRichText id="inputRichText1" value="#{document1.ProcessMapsRT}">
</xp:inputRichText>
The DOJO processes associated with the xe:dialog moves the dialog to another place in the DOM which means it will loose track of the data sources in the main parts of the document. If you do you saving in the dialog with SSJS instead of simple actions it may work better.
I have had the most success using a dialog contained in a custom control where the datasource is passed in through the composite data. That way the connection to the data is not lost and still works, BUT, I still use SSJS for saving in these situations.
/Newbs
UPDATE: This may be a time to use the technique Steve Pridemore described in NotesIn9 #42 (see xpages.tv).
First put a new event onto your XPage at the level with the data source in it.
<xp:eventHandler
id="saveEventHandler"
submit="true"
save="true"
event="calledbyid"
refreshMode="complete">
</xp:eventHandler>
Next, have the action in the dialog invoke this event using client side javascript:
XSP.executeOnServer('#{id:saveEventHandler}')
That "should" do it. I have not fully tested it but the examples from NoteIn9 do work.
/Newbs
Have you tried using dataContexts to define your datasource? I believe dataContext is a global object.
Update: dataContexts or even dominoDocument datasource worked when saving a document, but the problem was that the values were not saved. I therefore used a viewScope variable to store the values and that did the trick. I am not sure if this will help you, but here you go, this works for me:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:this.data>
<xp:dominoDocument var="newDoc" formName="frmContact"></xp:dominoDocument>
</xp:this.data>
<xp:inputText id="inputText1" value="#{viewScope.firstName}"></xp:inputText>
<xp:inputText id="inputText2" value="#{viewScope.lastName}"></xp:inputText>
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="dialog1">
<xp:this.action><![CDATA[#{javascript:getComponent("dialog1").show();}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xe:dialog id="dialog1">
<xp:button value="Label" id="button2">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:newDoc.replaceItemValue("fldFirstName", viewScope.firstName);
newDoc.replaceItemValue("fldLastName", viewScope.lastName);
newDoc.save();
getComponent("dialog1").hide();}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</xe:dialog>
</xp:view>
Hope this helps!
Ensure your data are posted to server before opening dialog. I would suggest to open such dialog with SSJS syntax - getComponent("dialog1").show()