XPages xe:listView won't hide the columns - xpages

I created a sample to demonstrate. I have a view called "testView" with three columns referencing "field1", "field2", "field3".
When I run this XPage all three columns in the display when it should not show the third column. Clicking the button does not hide the second column either.
Can anyone tell me what I have wrong?
<?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.beforePageLoad><![CDATA[#{javascript:if ( sessionScope.showCol2 == null )
sessionScope.showCol2 = true;}]]></xp:this.beforePageLoad>
<xe:restService id="restService1">
<xe:this.service>
<xe:viewJsonService viewName="testView"
defaultColumns="true">
</xe:viewJsonService>
</xe:this.service>
</xe:restService>
<xp:panel style="margin-left:20.0px;margin-top:20.0px">
<xe:listView id="listView1" storeComponentId="restService1">
<xe:listViewColumn id="listViewColumn1" columnName="field1"
columnTitle="Field1">
</xe:listViewColumn>
<xe:listViewColumn id="listViewColumn2" columnName="field2"
columnTitle="Field2">
<xe:this.rendered><![CDATA[#{javascript:return sessionScope.showCol2;
}]]></xe:this.rendered></xe:listViewColumn>
<xe:listViewColumn id="listViewColumn3" columnName="field3"
columnTitle="Field3" rendered="false">
</xe:listViewColumn>
</xe:listView></xp:panel>
<xp:panel style="margin-top:20.0px;margin-left:20.0px">
<xp:button id="button1" value="Toggle Column 2">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="listView1">
<xp:this.action><![CDATA[#{javascript:if ( sessionScope.showCol2 == false ) {
sessionScope.showCol2 = true;
}
else {
sessionScope.showCol2 = false;
}}]]></xp:this.action>
</xp:eventHandler></xp:button>
</xp:panel></xp:view>

Looks like a bug in ExtLib. But you can hide the column in your code with hidden* property:
<xp:button id="button1" value="Toggle Column 2">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="listView1">
<xp:this.action>
<![CDATA[#{javascript:
var cmp = getComponent('listViewColumn2');
if( cmp.isHidden() ){
cmp.setHidden(false);
}else{
cmp.setHidden(true);
}
}]]>
</xp:this.action>
</xp:eventHandler>
</xp:button>
*: the property is hidden too

Related

checkbox control not calculating value consistently

I want to use the feature of the checkbox control by using SSJS to return "true" or "false" based on the value of a session variable. The calculation only runs when the page is completely refreshed. The code does not on a partial or full refresh once the page is loaded (The only exception is that the code will run on the first partial or full refresh - which is interesting). I wrote a quick demonstration program.
I am sure this has something to do with the JSF lifecycle, but am not sophisticated in the technology to decipher what is going on.
Thanks,
---Lisa&
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.beforeRenderResponse><![CDATA[#{javascript:if (sessionScope.uncheck === true) {
sessionScope.checked = false;
} else {
sessionScope.checked = true;
}}]]></xp:this.beforeRenderResponse>
<xp:panel id="Panel1">
<xp:label id="label1" value="Panel1" style="font-weight:bold"></xp:label>
<xp:button id="button1" value="Button1 - Check the Box">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="Panel2">
<xp:this.action><![CDATA[#{javascript:sessionScope.checked = true;
print("just clicked Button1 sessionScope.checked = ",sessionScope.checked);}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button id="button3" value="Button 2 - Uncheck the Box">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="Panel2">
<xp:this.action><![CDATA[#{javascript:sessionScope.checked = false;
print("just clicked Button2 sessionScope.checked = ",sessionScope.checked);}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button id="button2" value="Reload page - Uncheck the Box">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:sessionScope.uncheck = true;
context.reloadPage();}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button id="button4" value="Reload page - Check the Box">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:sessionScope.uncheck = false;
context.reloadPage();}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:panel>
<xp:panel id="Panel2">
<xp:label id="label2" value="Panel2" style="font-weight:bold">
</xp:label>
<xp:checkBox id="checkBox1" text="Computed Checkbox">
<xp:this.defaultChecked><![CDATA[#{javascript:print("Calculating CheckBox - sessionScope.checked = ",sessionScope.checked);
return sessionScope.checked}]]></xp:this.defaultChecked>
</xp:checkBox>
</xp:panel>
</xp:view>
Bind your sessionScope variable directly to the xp:checkBox. This way any changes to the sessionScope variable will be reflected by the checkbox when refreshed:
<xp:checkBox id="checkBox1" text="Computed Checkbox" value="#{sessionScope.checked}"></xp:checkBox>
Here's an example using your buttons for partial refresh and for full reload:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:panel id="Panel1">
<xp:label id="label1" value="Panel1" style="font-weight:bold"></xp:label>
<xp:button id="button1" value="Button1 - Check the Box">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="Panel2">
<xp:this.action><![CDATA[#{javascript:
sessionScope.checked = true;
print("just clicked Button1 sessionScope.checked = ",sessionScope.checked);
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button id="button3" value="Button 2 - Uncheck the Box">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="Panel2">
<xp:this.action><![CDATA[#{javascript:
sessionScope.checked = false;
print("just clicked Button2 sessionScope.checked = ",sessionScope.checked);
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button id="button2" value="Reload page - Uncheck the Box">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:
sessionScope.checked = true;
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button id="button4" value="Reload page - Check the Box">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:
sessionScope.checked = false;
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:panel>
<xp:panel id="Panel2">
<xp:label id="label2" value="Panel2" style="font-weight:bold">
</xp:label>
<xp:checkBox id="checkBox1" text="Computed Checkbox" value="#{sessionScope.checked}"></xp:checkBox>
</xp:panel>
</xp:view>

Xpages: Refresh read only field on competition of DialogBox

My Xpage is in read mode. There is a Notes field with a "Add Notes" button. Click the button, user adds notes in dialogbox and clicks "Add Notes". The button does the work of adding the notes and saving the document.
I want to update the underlying notes field so the user will see their additions. How can I accomplish this?
<?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 id="pnlAll">
<xp:this.data>
<xe:objectData saveObject="#{javascript:PCModel.save()}"
var="PCModel">
<xe:this.createObject><![CDATA[#{javascript:var pc = new com.scoular.model.PC();
var unid = sessionScope.get("key");
if (unid != null) {
pc.loadByUnid(unid);
sessionScope.put("key","");
viewScope.put("readOnly","Yes");
} else {
pc.create();
viewScope.put("readOnly","No");
}
viewScope.status = pc.status;
return pc;}]]></xe:this.createObject>
</xe:objectData>
</xp:this.data>
<xp:inputTextarea id="inputTextarea3" cols="1" rows="10"
disabled="true" value="#{PCModel.notes}">
</xp:inputTextarea>
<xp:br></xp:br>
<xp:button value="Add Notes" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:getComponent("dialogAddNotes").show()}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:br></xp:br>
<xp:div styleClass="modal fade" id="model1" role="dialog">
<xe:dialog id="dialogAddNotes" styleClass="modal-dialog"
title="Add Notes">
<xp:div style="margin-left:10.0px;margin-right:10.0px">
<xp:inputTextarea id="inputTextarea4" value="#{viewScope.addNotes}"
cols="1" rows="18">
</xp:inputTextarea>
</xp:div>
<xp:div styleClass="modal-footer">
<xp:button type="button" styleClass="btn btn-primary" id="button17"
value="Add Notes">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="dialogAddNotes">
<xp:this.action><![CDATA[#{javascript:var newLne = "\n";
var oldNte = PCModel.notes;
var usrNme:String = userBean.displayName;
var dte = session.createDateTime(#Now());
var lnkStr:String = "Notes added by " + usrNme + " at " + dte + newLne + newLne + viewScope.addNotes + newLne + newLne + oldNte;
var newNotes:String = lnkStr
PCModel.notes = newNotes;
PCModel.save();}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:div>
</xe:dialog>
</xp:div>
</xp:panel>
</xp:view>
You need to partially refresh the updated text area field called inputTextarea3 instead of the dialog.

Xpages-Setting Up the ViewScope from client-side javaScript (oncontextmenu)

I have a Xpages in which I have repeat control, Now I have the list of documents from a view. Onclick on the row is setting the viewScope Array with the Unid.
I have done this actually for the purpose of selecting the document and to keep track that which document is selected, I am successfull in doing that but the main purpose was, I wanted to obtain the UNID on right-Click context menu.
Now, Also the right click event is providing me the UNID in one text field. I have obtained this by using "oncontextmenu" attribute in a div tag.
<div oncontextmenu="javascript:
var a = document.getElementById('#{id:inputText1}').value;
document.getElementById('#{id:inputText2}').value=a;
return false;">
There is "inputText1" in each row with the default value UNID of the perticular row.
In above code I am getting the UNID from "inputText1" and setting it up to the "inputText2", So on right click I am successfully getting the UNID of the clicked row.
In futher case I have an idea that I can do any operation by using that UNID but instead of setting the UNID to the "inputText2", I want to set this UNID to viewScope not in "inputText2".
Basically my overall issue is that I want to set UNID which I am getting on right-click(oncontextmenu) to viewScope not in any text field("inputText2") using above client-side java script.
example code:
<?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.afterPageLoad><![CDATA[#{javascript:var myList = new java.util.ArrayList();
sessionScope.put("myList",myList);}]]></xp:this.afterPageLoad>
<xp:button value="Refresh" id="button3">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="repeat2">
</xp:eventHandler></xp:button>
<xp:repeat id="repeat2" rows="30" value="#{sessionScope.myList}"
var="listData">
<xp:text escape="true" id="computedField1">
<xp:this.value><![CDATA[#{javascript:listData+" , "}]]></xp:this.value>
</xp:text>
</xp:repeat>
<xp:inputText id="inputText2"></xp:inputText>
<xp:repeat id="repeat1" rows="30" var="rowData"
indexVar="repeatIndex" first="0" styleClass="abc">
<xp:this.value><![CDATA[#{javascript:var viewName = "Adressakten";
var v:NotesView = database.getView(viewName);
return v.getAllEntries();}]]></xp:this.value>
<xp:br></xp:br>
<div oncontextmenu="javascript:
var a = document.getElementById('#{id:inputText1}').value;
document.getElementById('#{id:inputText2}').value=a;
return false;">
<xp:inputHidden id="inputText1">
<xp:this.defaultValue><![CDATA[#{javascript:var doc:NotesDocument = rowData.getDocument();
return doc.getUniversalID();}]]></xp:this.defaultValue>
</xp:inputHidden>
<xp:div id="div1">
<xp:this.style><![CDATA[#{javascript:javascript:var keyCode = rowData.getDocument().getUniversalID();
var myArray = sessionScope.get("myList");
if(myArray.contains(keyCode))
return "border-color:rgb(192,192,192);border-style:solid;border-width:thin;height:42.0px;background-color:green;cursor:pointer;"
else
return "border-color:rgb(192,192,192);border-style:solid;border-width:thin;height:42.0px;background-color:rgb(255,255,128);cursor:pointer;"}]]></xp:this.style>
<xp:text escape="true" id="computedField2">
<xp:this.value><![CDATA[#{javascript:var doc:NotesDocument = rowData.getDocument();
return doc.getItemValueString('aTitel');}]]></xp:this.value>
</xp:text>
<br />
document Id:
<xp:text escape="true" id="computedField3">
<xp:this.value><![CDATA[#{javascript:var doc:NotesDocument = rowData.getDocument();
return doc.getUniversalID();}]]></xp:this.value>
</xp:text>
<xp:br></xp:br>
<xp:button value="Add" id="button1" rendered="false">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="computedField2">
<xp:this.action><![CDATA[#{javascript:var keyCode = rowData.getDocument().getUniversalID();
var myArray = sessionScope.get("myList");
if(!myArray.contains(keyCode)){
myArray.add(keyCode);
}}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button value="Remove" id="button2" rendered="false">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:var keyCode = rowData.getDocument().getUniversalID();
var myArray = sessionScope.get("myList");
myArray.remove(keyCode)}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:var keyCode = rowData.getDocument().getUniversalID();
var myArray = sessionScope.get("myList");
if(!myArray.contains(keyCode)){
myArray.add(keyCode);
}
else{
myArray.remove(keyCode);
}}]]></xp:this.action>
</xp:eventHandler>
</xp:div></div>
<br />
</xp:repeat>
</xp:view>
It sounds like the JSON RPC Service from the Extension Library is what you need. That will allow you to run SSJS using a value passed from CSJS. It's covered on pages 351-3 of XPages Extension Library book and there may be examples in Extension Library Demo database.
I absolutely agree with the answer of Paul Stephen Withers, the best way to do this is using JSON RPC.
Here a JSON RPC working 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">
<xe:jsonRpcService id="jsonRpcService1" serviceName="rpcService">
<xe:this.methods>
<xe:remoteMethod name="setUniqueID" script="sessionScope.put('sessionScopeVarTest', unid);">
<xe:this.arguments>
<xe:remoteMethodArg name="unid" type="string"></xe:remoteMethodArg>
</xe:this.arguments>
</xe:remoteMethod>
</xe:this.methods>
</xe:jsonRpcService>
Show Value of "sessionScope.sessionScopeVarTest" ->
<xp:text escape="true" value="#{sessionScope.sessionScopeVarTest}" style="font-weight:bold">
</xp:text>
<br/>
<br/>
<xp:button id="btnTriggerRPC" value="Trigger RPC Method">
<xp:eventHandler event="onclick" submit="false">
<xp:this.script><![CDATA[rpcService.setUniqueID('13F51C65D8C257FCC1257ED000361786')]]></xp:this.script>
</xp:eventHandler>
</xp:button>
<xp:button id="btnRefresh" value="Refresh Page">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
</xp:eventHandler>
</xp:button>
</xp:view>

Change the state of a checkbox in the backend

In ssjs I try to change the state of a checkbox.
I tried :
doc.replaceItemValue( 'picWeb', "true" );
which doesn't seem to change anything (checkbox doesn't change to checked)
I also tried :
doc.replaceItemValue( 'picWeb', true );
which throws an error
( [TypeError] Exception occurred calling method NotesDocument.replaceItemValue(string, boolean) null)
If I understand it well : you can't change a checkbox (boolean) with replaceItemValue, but how do I change it then ?
Is it possible with ssjs or java or ...
Define in checkbox which string relates to checked value and which to unchecked value with the properties checkedValue and uncheckedValue:
<xp:checkBox
...
uncheckedValue="false"
checkedValue="true">
</xp:checkBox>
You can set the value then with
document1.replaceItemValue("picWeb", "true")
This is a complete example to demonstrate how to set a checkbox value in SSJS:
<?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.data>
<xp:checkBox text="picWeb" id="checkBox1"
value="#{document1.picWeb}"
uncheckedValue="false"
checkedValue="true">
</xp:checkBox>
<xp:button value="True" id="button2">
<xp:eventHandler event="onclick" submit="false"
refreshMode="partial" refreshId="checkBox1">
<xp:this.action><![CDATA[#{javascript:
document1.replaceItemValue("picWeb", "true")
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button value="False" id="button3">
<xp:eventHandler event="onclick" submit="false"
refreshMode="partial" refreshId="checkBox1">
<xp:this.action><![CDATA[#{javascript:
document1.replaceItemValue("picWeb", "false")
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button value="Submit" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete" immediate="false" save="true">
</xp:eventHandler>
</xp:button>
</xp:view>
The value is set in document as string

xpages number converter with combobox in ND9

I'm having trouble using number conversion with numberConvert in a combo box in xpages on a Domino 9 server. This used to work on the 8.5 server.
When I submit the values I get: Validation Error: Value is not valid
I also tried to populate the values with "new javax.faces.model.SelectItem" but that didn't make any difference.
Does anyone know how to use numbers in combo boxes in ND9?
Here is the source (I removed everything unneccesary for this example):
<xp:comboBox id="combo" value="#{viewScope.testfield}">
<xp:this.converter>
<xp:convertNumber type="number"></xp:convertNumber>
</xp:this.converter>
<xp:selectItem itemLabel="9" id="selectItem1" itemValue="9">
</xp:selectItem>
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:var arr=new Array("0","1","2"); return arr;}]]></xp:this.value>
</xp:selectItems>
</xp:comboBox>
<xp:message id="message1" for="combo"></xp:message>
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:save></xp:save>
</xp:this.action>
</xp:eventHandler>
</xp:button>
Please ensure that field 'testField' is of type 'Number' on the underlying form.
I had the same issue on 8.5.3 server. So, i wrote the below code to overcome the issue..
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:
var arr = ['0','1','2']
var comboOptions = [];
for (i = 0; i < arr.length; i++){
comboOptions.push(new javax.faces.model.SelectItem(parseFloat(arr[i]), arr[i]))
}
return comboOptions}]]>
</xp:this.value>
</xp:selectItems>
You can simplify the above code, if you know how to use managed beans.
Below is the code for bean.
public class ApplicationSettings implements Serializable{
private static final long serialVersionUID = 1L;
private List comboOptions;
public ApplicationSettings(){
loadDefaults();
}
public void loadDefaults(){
for(int x = 0; x <= 3; x = x+1){
SelectItem item = new SelectItem(new Double(x),""+x);
comboOptions.add(item);
}
}
public List getComboOptions() {
return comboOptions;
}
public void setComboOptions(List comboOptions) {
this.comboOptions = comboOptions;
}
}
In faces-configxml, register the managed bean(name: ApplicationSettings, scope:application).
Then in your xpage..
<xp:selectItems value="#{ApplicationSettings.comboOptions}"></xp:selectItems>
EDIT:
If you want to select numbers in a ComboBox you have to define comboBox's possible values as an array of numbers, not strings.
<xp:this.beforePageLoad><![CDATA[#{javascript:viewScope.testfield = 1}]]></xp:this.beforePageLoad>
<xp:comboBox id="combo" value="#{testfield}">
<xp:selectItem itemLabel="0" itemValue="${javascript:0}"></xp:selectItem>
<xp:selectItem itemLabel="1" itemValue="${javascript:1}"></xp:selectItem>
<xp:selectItem itemLabel="2" itemValue="${javascript:2}"></xp:selectItem>
</xp:comboBox>
This example works perfect without using a converter if the value is a scope variable.
If you have a flexible number of entries you can use both ways shown in Adibabu Kancharla's answer.
The number converter is necessary for binding to a document's number field. The following example works for me in ND853 and ND9. I had to add integerOnly="true" though:
<?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="NumberTest"
action="editDocument"
documentId="477FF8697EE50EDBC1257B710073DDE3">
</xp:dominoDocument>
</xp:this.data>
<xp:comboBox id="combo" value="#{document1.Number}">
<xp:selectItem itemLabel="0" itemValue="${javascript:0}"></xp:selectItem>
<xp:selectItem itemLabel="1" itemValue="${javascript:1}"></xp:selectItem>
<xp:selectItem itemLabel="2" itemValue="${javascript:2}"></xp:selectItem>
<xp:this.converter>
<xp:convertNumber type="number" integerOnly="true"></xp:convertNumber>
</xp:this.converter>
</xp:comboBox>
<xp:message id="message1" for="combo"></xp:message>
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:save></xp:save>
</xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:view>

Resources