Wednesday, January 13, 2016

Reversing the display order of a Multi-value field (XPages)

Today I needed to reverse the display of a multi-value field. It's a log of actions and we needed to show the most recent on top rather then the first added. JavaScript arrays have a reverse() function but when I took the vector I got back it was coming in as an object not an array. I didn't want to spend more time on it, so I decided to reverse the elements in the vector.  I'm showing the results in a repeat.

So what I decided to do was reverse the vector. Below is my code to do it. It takes one vector and puts all the elements into a new vector and returns that:

  var iVector = new java.util.Vector();
    iVector = SSJSgetItemValueSet(doc, "lastresult", iVector);
    var oVector = new java.util.Vector();
    for(var nV=(iVector.size()-1); nV >= 0; nV--){
        oVector.addElement(iVector.elementAt(nV));
    } 

return oVector;
 
SSJSgetItemValueSet is a function I have in a library to assure that I get a vector from a NotesItem. Here is that function:

   function SSJSgetItemValueSet(iDoc:NotesDocument, iItemName:String, iVector:java.util.Vector) {
    //this is designed to see if there is any value in the field, and if so, to get all of it.
    //if there is only one value, still put it in a vector
    //if null, put null in as the value
    //java.util.Vector.size() is the # of elements in the vector
    //call as: iVector = SSJSgetItemValueSet(nDoc, approvedField, iVector);
    //this overloaded method is for when we want to do this from an XPage, and we can't pass a Notes object (like a Doc) into a bean,
    iVector = null; // always set to null
        try {
            if (iDoc.hasItem(iItemName)) {               
                var iItem:NotesItem = iDoc.getFirstItem(iItemName);
                var passObj = getValueAsVector(iItem.getValues());
                iVector = passObj;
            } else {
                iVector = null;
            }
        } catch (e) {
            e.toString();
        }   
    return iVector;
}
Hopefully this will be useful for someone.

Cheers,
Brian


1 comment:

  1. This is simpler and you don't have to worry about making sure of returning a Vector from the doc...


    <!-- JUST SETTING A FAKE DOCUMENT WITH INITIAL VALUES FOR THE ARRAY -->

    <xp:this.data>
    <xp:dominoDocument var="document1">
    <xp:this.postNewDocument><![CDATA[#{javascript:document1.setValue("myArray", ["1", "2", "3"]);}]]></xp:this.postNewDocument>
    </xp:dominoDocument>
    </xp:this.data>



    <!-- THIS IS NORMAL -->


    <p>
    <b>normal:</b>
    <xp:text value="#{document1.myArray}" />
    </p>



    <!-- THIS IS REVERSED -->


    <p>
    <b>reverse:</b>
    <br />
    <xp:text value="#{document1.myArray}" escape="false">
    <xp:this.converter>
    <xp:customConverter getAsObject="#{javascript: return value}">
    <xp:this.getAsString><![CDATA[#{javascript:var reverse = new java.util.Vector(value);
    java.util.Collections.reverse(reverse);
    return reverse.toArray().join("<br>");}]]></xp:this.getAsString>
    </xp:customConverter>
    </xp:this.converter>
    </xp:text>
    </p>

    ReplyDelete