Rich text field in custom control with composite data - xpages

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>

Related

compute partial refresh ID?

I would like to compute the ID of a partial refresh target ID. Is this possible?
I am working an a reusable component (custom control) and would like to specify the target ID via the Property Definition instead of hard-coding it.
You mean something like this?
Code for CustomControl
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="#{compositeData.refreshId}">
</xp:eventHandler>
</xp:button>
</xp:view>
Code for 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:label
value="#{javascript:java.lang.System.currentTimeMillis()}"
id="label1" />
<xc:CC refreshId="#{label1}" />
</xp:view>
The custom property of the CC is a String named refreshId

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>

XPage fileDownload1 control becomes editable on page full refresh?

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>

The xpage ssjs code to open xe:dialog does not open dialog but change document mode from edit to read

My Xpage has five sections for workflow. Section 1 submit button works fine.
For second section submit button I'm calling xe:dialog box (using ssjs) to get some user inupt and it does open the xe:dialog box. But original document is now in read mode and submit button is not visible
If I remove the section 1, the section 2 button open dialog and does not change the document mode of original document.
Here is a sample code of xpage with dialog box and button.
<?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"
dojoTheme="true"
dojoParseOnLoad="true">
<xp:this.resources>
<xp:dojoModule
name="dijit.Dialog"></xp:dojoModule>
<xp:dojoModule
name="dijit.form.Button"></xp:dojoModule>
<xp:dojoModule
name="dijit.form.TextBox"></xp:dojoModule>
</xp:this.resources>
<xp:br></xp:br>
<xp:this.data>
<xp:dominoDocument
var="document1"
formName="MetalWorking">
</xp:dominoDocument>
</xp:this.data>
<xp:panel>
<xp:panel>
 
<xp:button
value="Lab Man Approval"
id="button4">
<xp:this.rendered><![CDATA[#{javascript:document1.isEditable() & (document1.getItemValueDate("Section1DateCompleted")!=null) & (document1.getItemValueDate("Section2DateCompleted") == null)
}]]></xp:this.rendered>
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete"
immediate="false"
save="true">
<xp:this.action>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:var d=getComponent('dialog2');
d.show();}]]></xp:this.script>
</xp:executeScript>
</xp:this.action>
</xp:eventHandler>
</xp:button>
   <xp:br></xp:br>
<xe:dialog
id="dialog2">
<xp:panel
style="background-color:rgb(226,226,226)">
<xp:table>
<xp:tr>
<xp:td>
<xp:label
value="Response"
id="responseArea_Label1"
for="responseArea1">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText
id="responseArea1">
</xp:inputText>
</xp:td>
</xp:tr>
</xp:table>
</xp:panel>
</xe:dialog>
</xp:panel>
</xp:panel>
<xp:table>
<xp:tr>
<xp:td>
<xp:label
value="Doc history:"
id="docHistory_Label1"
for="docHistory1">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText
value="#{document1.DocHistory}"
id="docHistory1">
</xp:inputText>
</xp:td>
</xp:tr>
</xp:table>
</xp:view>
Are you sure thats because of the "document1.isEditable()" and not because of all the other parts in your if your statement?
if i change your rendering code just like that
<xp:this.rendered><![CDATA[#{javascript: document1.isEditable() }]]></xp:this.rendered>
the button is pretty much visible.

XPages Mobile Control Partial refresh returns to menu page

I have a simple page inside mobile controls. I have an edit box and what I want to happen is to a partial refresh of the current in the onChange event of the edit control. Basically type something in the edit control - hit enter and do the partial refresh.
What's happening is hitting enter if returning the page to the main menu. If I put a value in and hit TAB then it works as I would want.
I'm starting a new app from scratch. But I've done this concept many times with an app in production. I can't find anything special in the code that would "trap" an enter button... So I'm at a loss why I can't get the behavior I want this time around.
Here's a video demo of the problem:
http://traffic.libsyn.com/notesin9/SO-Question2-HB.mp4
Below is the full code.
Thanks for any help!!
<?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"
xmlns:xc="http://www.ibm.com/xsp/custom">
<xp:this.resources>
<xp:styleSheet href="/.ibmxspres/dojoroot/dijit/themes/tundra/tundra.css">
</xp:styleSheet>
<xp:styleSheet href="/mobile.css"></xp:styleSheet>
</xp:this.resources>
<xe:singlePageApp id="singlePageApp1"
selectedPageName="mainMenu">
<xe:djxmHeading id="djxmHeading1" label="My App"></xe:djxmHeading>
<xe:appPage id="mainMenuID" pageName="mainMenu">
<xe:djxmRoundRectList id="djxmRoundRectList1"
title="Main Menu">
<xe:djxmLineItem id="djxmLineItem9" moveTo="#container"
label="Test Page">
</xe:djxmLineItem>
</xe:djxmRoundRectList>
</xe:appPage>
<xe:appPage id="containerID" pageName="container"
resetContent="true">
<xe:djxmHeading id="djxmHeading5" label="My Page"
back="Main Menu">
</xe:djxmHeading>
<xe:djxmRoundRectList id="djxmRoundRectList2">
<xp:panel id="mainPanel">
<xp:table style="width:100.0%">
<xp:tr>
<xp:td style="width:50%"></xp:td>
<xp:td>Details</xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:inputText id="inputText1" styleClass="target alignVMiddle"
value="#{sessionScope.myValue}">
<xp:this.attrs>
<xp:attr name="autocorrect" value="off"></xp:attr>
<xp:attr name="placeholder" value="Tap to Scan...">
</xp:attr>
</xp:this.attrs>
<xp:eventHandler event="onchange" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:viewScope.put("test", "test");}]]></xp:this.action>
</xp:eventHandler>
</xp:inputText>
</xp:td>
<xp:td></xp:td>
</xp:tr>
</xp:table>
<xp:br></xp:br>
Current Value: 
<xp:text escape="true" id="computedField1" value="#{sessionScope.myValue}"></xp:text>
<xp:br></xp:br>
<xp:br></xp:br>
Current Time: 
<xp:text escape="true" id="computedField2" value="#{javascript:#Now();}">
<xp:this.converter>
<xp:convertDateTime type="time"></xp:convertDateTime>
</xp:this.converter>
</xp:text>
</xp:panel>
</xe:djxmRoundRectList>
</xe:appPage>
</xe:singlePageApp>
</xp:view>
Can you do something like this to force a partial refresh on Enter?
<xp:inputText id="inputText1" value="#{sessionScope.myValue}">
<xp:eventHandler event="onkeypress" submit="true" refreshMode="partial" refreshId="something">
<xp:this.script><![CDATA[//partial refresh on Enter
if( thisEvent.keyCode === dojo.keys.ENTER ){
dojo.stopEvent( thisEvent );
} else {
return false;
}
]]></xp:this.script>
</xp:eventHandler>
</xp:inputText>
I think the problem is that enter will try to do a submit and submit will return you to the first page. Try to add a check in onkeyup or down for charcode 13 and if this is found return false.
You might also need to do a stopproprigate or something like that.
Google for enter key submit form
From my mobile ;-)
Or perhaps this post. http://tinyurl.com/bsgy9g6

Resources