Passing xp:link parameters through custom control - xpages

I have a custom control with the following code:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:panel tagName="li">
<xp:this.styleClass><![CDATA[${javascript:#If(view.getPageName().equals(compositeData.linkPage), "active", "")}]]></xp:this.styleClass>
<xp:link escape="true"
text="${javascript:compositeData.LinkLabel}"
value="${javascript:compositeData.linkPage}"
parameters="${javascript:compositeData.parameters}">
</xp:link>
</xp:panel>
</xp:view>
This is the property definition tree of the control:
I try to use the custom control like this:
<xc:sideMenuPageLink LinkLabel="Registration"
linkPage="/Registration.xsp">
<xc:this.parameters>
<xc:parameters name="id" value="new"></xc:parameters>
</xc:this.parameters>
</xc:sideMenuPageLink>
When I build my application, I get the following error:
The method addParameter(Parameter) in the type UIOutputLink is not applicable for the arguments (Object)
on SideMenuPageLink.java (my custom control)
How can I pass the parameters for the link from my Xpage to the Custom Control?

It seems that parameters have to passed one by one, not as a single object.
You may want to try the following code, which works for me:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:panel tagName="li">
<xp:this.styleClass><! [CDATA[${javascript:#If(view.getPageName().equals(compositeData.linkPage), "active", "")}]]></xp:this.styleClass>
<xp:link escape="true"
text="${compositeData.LinkLabel}"
value="${compositeData.linkPage}">
<xp:this.parameters>
<xp:parameter
name="${compositeData.parameters.name}"
value="${compositeData.parameters.value}">
</xp:parameter>
</xp:this.parameters>
</xp:link>
</xp:panel>
</xp:view>
Edit 2019-01-30: Corrected typos

Related

xpages, save all documents in a repeat panel

I'm trying out a simple xpage that fetches a parent document (form fParent) and a few child documents (form fChild) via view vChildren. I can get the children as read only via a normal view control but these are read-only and I'd like to bind the children to documents so the save/submit button makes changes to both the parent and child documents.
In the repeat control, I'm binding the variable rowData to a DocumentCollection object which I'm assuming is iterated over and returns a Document object for each item (this seems to work as the xpage displays the correct number of custom controls). I understand from the HCL documentation that in order for the save action to be able to make changes to the child documents I need to add a document data source which I have done in the custom control.
The issue I have is that document2 in the custom control is picking up the parent form data and not the child form data (the note IDs for each child are the same as the parent which makes me think this is the case).
What am I doing wrong? Code below and thanks in advance.
xPage for the parent
<?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 formName="fParent" var="document1" />
<xp:dominoView
var="view1" viewName="vChildren"
categoryFilter="#{document1.Key}">
</xp:dominoView>
</xp:this.data>
Name
<xp:inputText id="inputText2" value="#{document1.Name}"></xp:inputText>
<xp:br></xp:br>
Key 
<xp:text escape="true" id="computedField1" value="#{document1['Key']}">
</xp:text>
<xp:br></xp:br>
<xp:repeat id="repeat1" rows="30" var="rowData">
<xp:this.value><![CDATA[#{javascript:
var key = currentDocument.getItemValueString("key");
return database.getView('vChildren').getAllDocumentsByKey(key);}
]]>
</xp:this.value>
<xc:ccChildDoc></xc:ccChildDoc>
</xp:repeat>
<xp:button id="button1" value="Save" save="true" type="submit"></xp:button>
</xp:view>
Custom control for each child document
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" binding="#{rowData}">
<xp:this.data>
<xp:dominoDocument
formName="fChild" var="document2"
action="editDocument" computeWithForm="both"
documentId="#{javascript:rowData.getNoteID();}">
</xp:dominoDocument>
</xp:this.data>
<xp:panel>
Note id: 
<xp:text escape="true" id="computedField1" value="#{javascript:document2.getNoteID();}">
</xp:text>
<xp:br></xp:br>
Comment 
<xp:inputText id="inputText1" value="#{document2.Comment}" readonly="false">
</xp:inputText>
<xp:br></xp:br>
Field2 
<xp:inputText id="inputText2" value="#{document2.Field2}" readonly="false">
</xp:inputText>
<xp:br></xp:br>
<hr />
</xp:panel>
</xp:view>
Try adding ignoreRequestParams="true" to your data source for the child document.
This parameter tells XPages to ignore the documentId parameter in the URL for the child document data source and the child data source should then use documentId="#{javascript:rowData.getNoteID();}".

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

How to make headingText of navBar clickable?

I want the headingText be clickable. Well I can make it as a navbarBeforeLinks node but don't believe there is no way to make headingText clickable. E.g. I want the app redirect to Homepage by clicking on it.
<?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">
<xe:navbar id="navbar1" headingText="My application name"></xe:navbar>
</xp:view>
Use client side JavaScript to add an onclick event and style "pointer" to navBar's headingText:
<?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">
<xe:navbar
id="navbar1"
headingText="My application name">
</xe:navbar>
<xp:eventHandler
event="onClientLoad"
submit="false">
<xp:this.script><![CDATA[
function goHome() {
window.location.href = "... your home URL ..."
}
dojo.query(".navbar-brand").forEach(function(node, index, arr){
node.style.cursor = "pointer";
node.addEventListener("click", goHome);
});
]]></xp:this.script>
</xp:eventHandler>
</xp:view>
You can find headingText's node element in DOM with the help of class "navbar-brand".

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>

Resources