Search code examples
javascriptxpages

How to get selected document on viewPanel of xPage for external source data?


Here is my simple view that users JDBCQUERY as a source data. And it shows each row with a checkbox so you can select:

<?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:viewPanel rows="30" id="viewPanel1" showColumnHeader="false">
        <xp:this.data>
            <xe:jdbcQuery var="view1" scope="request">
                <xe:this.sqlQuery><![CDATA[#{javascript:"SELECT COLUMN1 FROM MYTABLE"}]]></xe:this.sqlQuery>
                <xe:this.connectionName><![CDATA[#{javascript:"DB2"}]]></xe:this.connectionName>
            </xe:jdbcQuery>
        </xp:this.data>

        <xp:viewColumn columnName="COLUMN1" id="viewColumn1" showCheckbox="true">
            <xp:viewColumnHeader id="viewColumnHeader1" rendered="false"></xp:viewColumnHeader>
        </xp:viewColumn>
    </xp:viewPanel>
</xp:view>

Now to get selected documents I use method/button:

var viewPanel=getComponent("viewPanel1");
var docIDArray=viewPanel.getSelectedIds();
for(i=0;i < docIDArray.length; i++){
    print(docIDArray[i]);
}

Since it's not NotesView/NotesDocument data it returns just row number of selected row (not document UNID)... getSelectedIds() returns selected rows 1 and 3.

Now how do I get column value of selected row (value2 and value4)? Is it something like that: getRow(3).getColumValues()... ?

     COLUMN1
[ ]  value1
[x]  value2
[ ]  value3
[x]  value4
[ ]  value5

Solution

  • I think <xp:viewPanel> is not appropriate for the task. I would change it for a <xp:dataTable>, although, at that point you need to re-implement the selection mechanism. Anyway, with the help of a view scoped bean, it could be something along these lines:

    <xp:this.data>
        <xe:jdbcQuery var="query" scope="request" connectionName="DB2"
            sqlQuery="SELECT COLUMN1 FROM MYTABLE" loaded="false" />
    </xp:this.data>
    
    <xp:dataTable id="dataTable1" binding="#{dataTable}"
        value="#{query}" var="row" indexVar="rowIndex">
        <xp:column id="column1">
            <xp:checkBox id="checkBox1"
                value="#{myBean.jdbcSelectedValues[rowIndex]}" uncheckedValue="false"
                checkedValue="true">
                <xp:this.converter>
                    <xp:convertBoolean />
                </xp:this.converter>
            </xp:checkBox>
        </xp:column>
        <xp:column id="column2">
            <xp:text value="#{row}" />
        </xp:column>
    </xp:dataTable>
    
    <xp:button id="button1" value="print selected">
        <xp:eventHandler event="onclick" submit="true"
            refreshMode="partial" refreshId="dataTable1"
            action="#{myBean.printSelectedColumnValues}">
        </xp:eventHandler>
    </xp:button>
    

    the view scoped bean

    private List<String> jdbcValues;
    private Map<Integer, Boolean> jdbcSelectedValues;
    
    public Map<Integer, Boolean> getJdbcSelectedValues() {
        if (jdbcSelectedValues == null) {
            jdbcSelectedValues = new HashMap<Integer, Boolean>();
        }
    
        return jdbcSelectedValues;
    }
    
    public void printSelectedColumnValues() {
        List<String> values = new ArrayList<String>();
    
        XspDataTableEx dataTable = (XspDataTableEx) FacesUtil.resolveVariable(FacesContext
                .getCurrentInstance(), "dataTable");
        List<?> wrappedData = (List<?>) dataTable.getDataModel().getWrappedData();
    
        for (Map.Entry<Integer, Boolean> entry : getJdbcSelectedValues().entrySet()) {
            if (entry.getValue()) {
                values.add((String) wrappedData.get(entry.getKey()).getColumnValue("COLUMN1"));
            }
        }
    
        System.out.println(values);
    
        jdbcSelectedValues.clear();
    }
    

    The idea is the one of grabbing the handle of the dataTable by means of the binding property (not really an orthodox way, I personally don't use these mixed approaches that disregard MVC pattern) and access the wrapped data that it contains: the wrapped data in nothing but the row set.

    WARNING the only thing I am not sure of is what exactly dataTable.getDataModel().getWrappedData(). You might wanna try to print the class name before doing any cast and subsequent work. But the sense is that with the index number and the wrapped data you should be able to get to the rows.