XPage fileDownload1 control becomes editable on page full refresh? - xpages

Why fileDownload1 control becomes editable (delete file attachment icon appears next to fileDownload control) when I just refresh the page. Here is my code where I use a button to refresh the page (just for the example)
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete"></xp:eventHandler>
</xp:button>
<xp:this.data>
<xp:dominoDocument var="document1" formName="myXpage"
databaseName="${javascript:sessionScope.SUPPORT_DB_FILE}"
action="openDocument">
</xp:dominoDocument>
</xp:this.data>
<xp:fileDownload
id="fileDownload1"
rows="30"
displayLastModified="false"
displayType="false"
displayCreated="false"
hideWhen="true"
allowDelete="true"
value="#{document1.MyBodyRTF}">
</xp:fileDownload>

I tried to replicate what you're describing, but am having trouble doing so. I created a new XPage and modeled it after your sample code.
Notable differences:
I never see the trash icon
I had to compute the UNID of some document with an attachment in the appropriate field
I set both the DB name and UNID in beforePageLoad
I noticed an interesting change in the UI behavior (see animated gif below)
I'm not sure what you're running into without having more source code to be able to view, but I can confirm that what I tried doesn't reproduce the result you're describing.
XPage source:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view
xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.beforePageLoad><![CDATA[#{javascript:sessionScope.myDbName = database.getFilePath();
var vw:NotesView = database.getView("SomeForms");
var first:NotesDocument = vw.getFirstDocument();
sessionScope.myFirstDoc = first.getUniversalID();
first.recycle();
vw.recycle();}]]></xp:this.beforePageLoad>
<xp:this.data>
<xp:dominoDocument
var="document1"
action="openDocument"
formName="SomeForm"
databaseName="${javascript:return sessionScope.myDbName;}"
documentId="${javascript:return sessionScope.myFirstDoc;}" />
</xp:this.data>
<xp:fileDownload
rows="30"
id="fileDownload1"
displayLastModified="false"
value="#{document1.SomeAttachments}" />
<xp:button
value="Refresh"
id="button1">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete" />
</xp:button>
</xp:view>

Related

duplicate items in Document after saving in a bean

I experience strange but reproduceable behaviour with an XPage which saves its values through a java bean. After copyAllItems to an document there are two richtext items in the document. First is empty, second is filled as expected.
This is my Xpage:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xc="http://www.ibm.com/xsp/custom">
<xp:this.data>
<xp:dominoDocument var="docDataSource" formName="test"></xp:dominoDocument>
</xp:this.data>
<xp:div id="test">
<xp:fileUpload id="fileUpload1" value="#{docDataSource.test}"></xp:fileUpload>
</xp:div>
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="test">
<xp:this.action><![CDATA[#{javascript:registration.testCopyAllItems(docDataSource);}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
This is my java bean method:
public void testCopyAllItems(DominoDocument docDataSource) throws NotesException{
Document docUser = database.createDocument(); // <- get any database
docDataSource.getDocument(true).copyAllItems(docUser, true);
docUser.save();
}
This is the result in the document:
Does anyone have a hint on what could cause the trouble?
This seems to be a "normal" behaviour and I have seen it a lot working with RichtText fields. It shouldn't matter. Notes can deal with a RichText field constisting of more than one item.
As a workaround,
delete the RichText field after copyAllItems() with removeItem() and
copy it with copyItem() separately.
This should result in one item only.

Rich text field in custom control with composite data

I am developing an xpages application and use 1 custom control where I have a rich text field on it.
The source document is on the main page.
The rich text field has it value via compositeData.
I pass the document and the field name.
In the CC I address the rich text field as
compositeData.DataSource[compositeData.Fieldname]
Where DataSource my document1 is and Fieldname the name of the rich text field on the notes document.
All works except inserting an image in the rich text and removing attachments.
I did find a lot of information about this but not a real solution.
Dit anybody ever found a solution for this?
Regards,
Peter
Here is the code:
Custom Control
<?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:panel>
<xp:label id="label1" value="Title:"></xp:label>
<xp:inputText id="inputText1">
<xp:this.value><![CDATA[#{compositeData.DataSource[compositeData.Title]}]]></xp:this.value>
</xp:inputText>
<xp:br></xp:br>
<xp:inputRichText id="richtext">
<xp:this.value><![CDATA[#{compositeData.DataSource[compositeData.Field]}]]></xp:this.value></xp:inputRichText>
<xp:fileUpload id="fileUpload1">
<xp:this.value><![CDATA[#{compositeData.DataSource[compositeData.Field]}]]></xp:this.value>
</xp:fileUpload>
<xp:fileDownload rows="30" id="fileDownload1"
displayLastModified="false" allowDelete="true">
<xp:this.value><![CDATA[#{compositeData.DataSource[compositeData.Field]}]]></xp:this.value>
</xp:fileDownload>
</xp:panel>
</xp:view>
XPAGE using the CC
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom"
xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:this.data>
<xp:dominoDocument var="document1" formName="testform"></xp:dominoDocument>
</xp:this.data>
<xe:applicationLayout id="applicationLayout1">
<xp:panel>
<xp:button id="button1">
<xp:this.value><![CDATA[Save & Close]]></xp:this.value>
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:saveDocument var="document1"></xp:saveDocument>
<xp:openPage name="$$PreviousPage"></xp:openPage>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:br></xp:br>
<xc:cc DataSource="#{javascript:document1}" Field="Body" Title="Title">
</xc:cc>
</xp:panel>
<xe:this.configuration>
<xe:bootstrapResponsiveConfiguration></xe:bootstrapResponsiveConfiguration>
</xe:this.configuration>
</xe:applicationLayout>
<xp:this.navigationRules>
<xp:navigationRule outcome="xsp-success" viewId="$$PreviousPage"></xp:navigationRule>
</xp:this.navigationRules>
</xp:view>
I use the following in a custom control. Notice that I use a different syntax for the value parameter for xp:inputRichText than for the upload and download controls - and that the value parameter is computed on page load ($) instead of dynamically (#):
<xp:inputRichText id="richtext" value="${javascript:'#{document.' + compositeData.fieldName + '}';}"></xp:inputRichText>
<xp:fileUpload id="fileUpload" value="#{document[compositeData.fieldName]}"></xp:fileUpload>
<xp:fileDownload id="fileDownload" value="#{document[compositeData.fieldName]}"></xp:fileDownload>

Get unid of document before it is saved and have it not change when saved

I have an XPage that has a single data source document1. I would like to know the unid of the document before it has been saved.
It's seems this is possible because document1.getDocument().getUniversalID() returns a value before it is saved.
However, this value always changes once the document is saved then it remains constant. Is there a way to set the unid so it doesn't change when saved? I've tried if (document1.isNewNote()) document1.getDocument().setUniversalID(document1.getDocument().getUniversalID()) but it is still changing when saved.
Change document's id on dominoDocument's querySaveDocument event.
if (document1.isNewNote()) {
document1.getDocument().setUniversalID(yourID);
}
Here is a complete XPage example:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view
xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.data>
<xp:dominoDocument
var="document1"
formName="Test">
<xp:this.querySaveDocument><![CDATA[#{javascript:
if (document1.isNewNote()) {
document1.getDocument().setUniversalID(document1.getItemValueString("id"));
}
}]]></xp:this.querySaveDocument>
</xp:dominoDocument>
</xp:this.data>
<xp:inputText
value="#{document1.id}"
defaultValue="#{javascript:document1.getDocument().getUniversalID()}">
</xp:inputText>
<xp:button
value="Label"
id="button1">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete"
immediate="false"
save="true">
</xp:eventHandler>
</xp:button>
</xp:view>

xpages - prevent SSJS on page load in CSJS

I have some SSJS within CSJS onclick event of a button. Is there any way to prevent this SSJS from executing during page load?
Thanks
This can be done by checking facesContext.getRenderResponse(). If it is true, the page is reloaded, otherwise it is false. The flag is not set correctly but gives you an easy way to check if the page is loaded or not.
Here is an example XPage:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:button value="Reload CSJS" id="buttonReloadCSJS">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.script>
<![CDATA[#{javascript:
facesContext.getRenderResponse()?"alert('NotOnLoad');":"alert('OnLoad')";
}]]>
</xp:this.script>
</xp:eventHandler>
</xp:button>
</xp:view>
If you open the XPage and click the button, the page will be reloaded and you will have another CSJS code.
EDIT:
Here is another way to calculate code only if the button was partial refreshed:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:div id="refreshMe">
<xp:button value="Reload CSJS" id="buttonReloadCSJS">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="refreshMe">
<xp:this.script>
<![CDATA[#{javascript:
var ajax = new com.ibm.xsp.ajax.AjaxUtil();
if( ajax.isAjaxPartialRefresh(facesContext) == true){
return "alert('Refreshed')";
}
}]]>
</xp:this.script>
</xp:eventHandler>
</xp:button>
</xp:div>
</xp:view>

Xpages Dynamic dojo dialog control

I have a list of products (created using a repeat control) and wish to click on a particular product and bring up a dialog with further information about that particular product. I don't really want to generate dijit.dialog thing for every single product on that page, so how can I do this dynamically possibly using AJAX and partial refresh.
A similar non xpages example can be seen here: http://www.replacementkeys.co.uk/window?dir=asc&limit=12&mode=grid&order=position - where you hover over an image and a quick view button comes up, which then dynamically loads the content for that product.
Any ideas would be truly appreciated.
We build the dialog outside the repeat control and then the action that launches or shows it also sets a viewScope variable that is used UNID for the data source in the dialog. Just make sure you refresh the contents of the dialog as you open it...
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:this.data>
<xp:dominoView var="promptView" viewName="dlgBoxes">
</xp:dominoView>
</xp:this.data>
<xp:panel>
<xp:repeat id="repeat1" rows="30" value="#{promptView}" var="promptEntry">
<xp:panel tagName="div">
<xp:text escape="true" id="computedField1" value="#{promptEntry.dlgName}">
</xp:text>
 
<xp:button value="details" id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:
var pe:NotesViewEntry = promptEntry;
viewScope.put("dlgDocUnid", pe.getUniversalID());
getComponent("dialog1").show();
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:panel>
</xp:repeat>
</xp:panel>
<xe:dialog id="dialog1" keepComponents="false" partialRefresh="true">
<xe:this.title><![CDATA[#{javascript:
var unid = viewScope.get("dlgDocUnid");
if(!unid) return "";
var doc:NotesDocument = database.getDocumentByUNID(unid);
return doc.getItemValueString("dlgName");}]]></xe:this.title>
<xp:panel>
<xp:this.data>
<xp:dominoDocument var="dlgDoc" formName="dlgBox" action="openDocument">
<xp:this.documentId><![CDATA[#{javascript:viewScope.get("dlgDocUnid");}]]></xp:this.documentId>
</xp:dominoDocument>
</xp:this.data>
<xp:text escape="true" id="computedField2" value="#{dlgDoc.Title}">
</xp:text>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:text escape="true" id="computedField3" value="#{dlgDoc.dlg}">
</xp:text>
</xp:panel>
</xe:dialog>
</xp:view>
Happy coding
/Newbs
You can combine your repeat control with the Extension Library dialog control in order to be able to launch a dialog when the user clicks on the individual row. Chris Toohey has created an excellent article called Popup Dialog Forms from Views in XPages that demonstrates this.

Resources