Monday, December 7, 2015

nhttp preview won't "switch ID"

With XPages I use the nhttp preview a lot. Today I wrapped up work using one ID and switched to another one. I had made a simple change and was checking on it and it wouldn't load. The error was that it couldn't open a database - both were on my local, and working for months. It turns out that the nhttp preview was the problem. I shut it down and relaunched the clients and it worked.

I wonder if nhttp has a reload command...

Cheers,
Brian

Wednesday, November 4, 2015

DirectoryNavigator via Java

So looking into something, I discovered there has been an addition called a "DirectoryNavigator", it's supposed to make it easier to get to person docs in the NAB. I needed something like this, but in Java - the examples are in LotusScript, and I'm working in a bean. Those examples are "TBD". I did get it working, so I'm sharing. It looks like this came out in R8.

What you do is create a vector with the field names you want to retrieve, and you create a vector with what you want to look up (names). You check to see if there is a match, and if so, iterate through the resultset and get the items retrieved. Here is a snippet of the code (dir is the NAB):

            Vector<String> itV = new Vector<String>();
            itV.addElement("ShortName");
            itV.addElement("HTTPPassword");
            itV.addElement("FullName");

            Vector<String> nameV = new Vector<String>();
            nameV.addElement("Smith");

            System.out.println("before dirNav");
            // DirectoryNavigator dirNav = dir.l
            DirectoryNavigator dirNav = dir.lookupNames("$Users", nameV, itV, true);

            while (dirNav.isMatchLocated()) {
                System.out.println("found");
                // dirNav.findFirstName();
                System.out.println("The first value is: " + dirNav.getFirstItemValue());
                for (int i = 0; i < 5; i++) {
                    try {
                        System.out.println("Next value is: " + dirNav.getNextItemValue());
                    } catch (Exception divE) {
                        System.out.println("in catch");

                    }
                }
                dirNav.findNextMatch();
            }

 
Here is the print results. I've obscured the names, but we get the hierarchical names, and the common names.

10/28/2015 08:45:00 AM  HTTP JVM: starting
10/28/2015 08:45:00 AM  HTTP JVM: new start
10/28/2015 08:45:00 AM  HTTP JVM: before dirNav
10/28/2015 08:45:00 AM  HTTP JVM: found
10/28/2015 08:45:00 AM  HTTP JVM: The first value is: [lsmith]
10/28/2015 08:45:00 AM  HTTP JVM: Next value is: [(390ACEC884A01BFDF5FA36AE5E6B29B1)]
10/28/2015 08:45:00 AM  HTTP JVM: Next value is: [CN=RRRRRRRRR]
10/28/2015 08:45:00 AM  HTTP JVM: Next value is: []
10/28/2015 08:45:00 AM  HTTP JVM: Next value is: []
10/28/2015 08:45:00 AM  HTTP JVM: Next value is: []
10/28/2015 08:45:00 AM  HTTP JVM: found
10/28/2015 08:45:00 AM  HTTP JVM: The first value is: [RSmith, smithr]
10/28/2015 08:45:00 AM  HTTP JVM: Next value is: [(CBA717BC74064A8F7EC075DA95ACB8F6)]
10/28/2015 08:45:00 AM  HTTP JVM: Next value is: [CN=TTTTTTTTTTTT]
10/28/2015 08:45:00 AM  HTTP JVM: Next value is: []
10/28/2015 08:45:00 AM  HTTP JVM: Next value is: []
10/28/2015 08:45:00 AM  HTTP JVM: Next value is: []


 You can see I cheated and did hard coded 5 cycles - so when there is nothing to display, you get an empty array. 

This may be useful for someone.

Cheers,
Brian


PS: If whoever does the Notes help wants to use this, or have me do the rest of the methods, I'll volunteer. BM

Wednesday, August 12, 2015

Bootstrap Progress Bars - sample database

I've been digging into Bootstrap for a bit now. One of the useful components is the progress bar. David Leedy did a great NotesIn9 on them and I followed it, and it was greatly valuable. I took his work and made a sample database. This is all his work, I just transcribed it (I changed the viewScope variable names however). Hopefully having this in a sample database will be useful.

Download the file

Cheers,
Brian




Tuesday, July 14, 2015

dataTable column width

In my last post, I'd say I'd look into controlling the column width. It's a setting:

<xp:column
  id="column4"

 style="width:5.0%">

so that was easy.

Cheers,
Brian

dataTable with Categories

I've been using DataTables for a number of things lately, where I need a bit more flexibility than a viewPanel, but I don't want to build it from scratch with a Repeat.

I'm currently working on process where I'm making a nsf to replace a MS Access database. So I'm having to adjust from the relational method. This means I need to use a key to look things up in a view to display the human friendly words rather than the code. So traditional Notes views don't do that. DataTables give me the flexibility I need. For part of this, I have 'events', and these will have one to several classes at each of these events. I want to hide the classes for each event until I click something to make it look neater and to save space.

DataTables don't have a native way to show categories, so I found one. I put a repeat in a column, and populate that repeat with a NotesViewEntryCollection from a value in a row of the DataTable. I tried to use the plus/minus icons like shown here in a great post by Ulrich Krause. But when I paged the icons disappeared. Both of them. So I used the basic idea, and put a link in that was always there to show the classes, and another link to hide them if desired. It works like I desire, so fine.

So this does what I wanted. I'm putting the code below. I have a few things to adjust. First, the classes should be in a table so they display better (I'm not putting it in to make the code a little shorter). Also, the columns resize when the repeat is expanded. Something I'll look into fixing after I post this.

Cheers,
Brian

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <xp:this.data>
        <xp:dominoView
            var="view1"
            viewName="Event\Name">
            <xp:this.databaseName><![CDATA[#{javascript:var curServer = @Subset(@DbName(),1);
if(@Left(curServer.toLowerCase(), "/") == "cn=svrname") {
    session.getDatabase('
svrname/OU', 'foldername\\Data.nsf');
} else {
    session.getDatabase('', '
foldername\\Data.nsf');
}}]]></xp:this.databaseName>
        </xp:dominoView>
    </xp:this.data>
    <xp:dataTable
        id="dataTable1"
        rows="30"
        var="rowData"
        value="#{view1}">
        <xp:this.facets>
            <xp:pager
                partialRefresh="true"
                layout="Previous Group Next"
                xp:key="header"
                id="pager1">
            </xp:pager>
            <xp:pager
                partialRefresh="true"
                layout="Previous Group Next"
                xp:key="footer"
                id="pager2">
            </xp:pager>
        </xp:this.facets>
        <xp:column id="column1">
            <xp:this.facets>
                <xp:label
                    value="Event Name"
                    id="label1"
                    xp:key="header">
                </xp:label>
            </xp:this.facets>
            <xp:link
                escape="true"
                id="link1">               
            </xp:link>
            <xp:text
                escape="true"
                id="computedField4">
            <xp:this.value><![CDATA[#{javascript:rowData.getColumnValues()[0];}]]></xp:this.value></xp:text></xp:column>
        <xp:column id="column2">
            <xp:text
                escape="true"
                id="computedField5">
            <xp:this.value><![CDATA[#{javascript:rowData.getColumnValues()[4];}]]></xp:this.value></xp:text>
           
            <xp:this.facets>
                <xp:label
                    value="Date"
                    id="label2"
                    xp:key="header">
                </xp:label>
            </xp:this.facets>
        </xp:column>
        <xp:column id="column3">
        
            <xp:this.facets>
                <xp:label
                    value="Group"
                    id="label3"
                    xp:key="header">
                </xp:label>
            </xp:this.facets>
            <xp:text
                escape="true"
                id="computedField6">
            <xp:this.value><![CDATA[#{javascript:rowData.getColumnValues()[3];}]]></xp:this.value></xp:text></xp:column>
        <xp:column id="column4">           
            <xp:this.facets>
                <xp:label
                    value="Number"
                    id="label4"
                    xp:key="header">
                </xp:label>
            </xp:this.facets>
            <xp:text
                escape="true"
                id="computedField7">
                <xp:this.value><![CDATA[#{javascript:rowData.getColumnValues()[2];}]]></xp:this.value>
                <xp:this.converter>
                    <xp:convertNumber
                        type="number"
                        integerOnly="true">
                    </xp:convertNumber>
                </xp:this.converter>
            </xp:text></xp:column>
        <xp:column id="column6">
        <xp:panel id="mainpanel">   
            <xp:link
                escape="true"
                text="Classes"
                id="link6">
            <xp:eventHandler
                event="onclick"
                submit="false">
                <xp:this.script><![CDATA[var visibility = 'show';
XSP.partialRefreshGet("#{id:mainpanel}", {
params: {'$$xspsubmitvalue': visibility},
onComplete: function () {
    XSP.partialRefreshGet("#{id:secondpanel}", {
        params: {'$$xspsubmitvalue': visibility}});}
});]]></xp:this.script>
            </xp:eventHandler></xp:link>
        </xp:panel></xp:column>
        <xp:column id="column5">
            <xp:this.facets>
                <xp:label
                    value="Courses"
                    id="label5"
                    xp:key="header">
                </xp:label>
            </xp:this.facets>
            <xp:panel id="secondpanel">
            <xp:repeat
                id="repeat1"
                rows="30"
                rendered="#{javascript:context.getSubmittedValue()== 'show'}"
                var="rptRowData">
                <xp:this.value><![CDATA[#{javascript:var curServer = @Subset(@DbName(),1);
if(@Left(curServer.toLowerCase(), "/") == "cn=svrname") {
    var dataDb:NotesDatabase=session.getDatabase('
svrname/ou', 'foldername\\Data.nsf');
} else {
    var dataDb:NotesDatabase=session.getDatabase('', '
foldername\\Data.nsf');
}

var v:NotesView=dataDb.getView('Class Instance\\Event-Course');
var nvec:NotesViewEntryCollection=v.getAllEntriesByKey(rowData.getColumnValues()[2] + '', true);
return nvec;}]]></xp:this.value>
                <xp:text
                    escape="true"
                    id="computedField1">
                    <xp:this.value><![CDATA[#{javascript:rptRowData.getColumnValues()[1];}]]></xp:this.value>
                </xp:text>
                &#160;&#160;&#160;
                <xp:text
                    escape="true"
                    id="computedField2">
                    <xp:this.value><![CDATA[#{javascript:rptRowData.getColumnValues()[2];}]]></xp:this.value>
                    <xp:this.converter>
                        <xp:convertNumber
                            type="number"
                            integerOnly="true">
                        </xp:convertNumber>
                    </xp:this.converter>
                </xp:text>
                &#160;&#160;&#160;&#160; &#160;
                <xp:text
                    escape="true"
                    id="computedField3">
                    <xp:this.value><![CDATA[#{javascript:var cNumV:NotesView=database.getView('Course Number');
var cNVE:NotesViewEntry=cNumV.getEntryByKey(rptRowData.getColumnValues()[1], true);
if(cNVE != null){
return cNVE.getColumnValues()[1];
}
return "Course Name not found";}]]></xp:this.value>
                </xp:text>
                &#160;&#160;&#160;&#160;&#160;&#160;
            </xp:repeat>
            <xp:link
                escape="true"
                text="Close"
                rendered="#{javascript:context.getSubmittedValue()== 'show'}"
                id="link5">
                <xp:eventHandler
                    event="onclick"
                    submit="false">
                    <xp:this.script><![CDATA[var visibility = 'hide';
XSP.partialRefreshGet("#{id:mainpanel}", {
    params: {'$$xspsubmitvalue': visibility},
    onComplete: function () {
    XSP.partialRefreshGet("#{id:secondpanel}", {
    params: {'$$xspsubmitvalue': visibility}});}
});]]></xp:this.script>
                </xp:eventHandler>
            </xp:link>
            </xp:panel>
        </xp:column>
    </xp:dataTable>
    <xp:br></xp:br>
    </xp:view>




Saturday, July 4, 2015

StartKeys for categorized viewPanel and number column

In case this helps someone:

I have a database shared by a couple of departments, I use a field to segregate them. Each document has a MemberKey with a number value.

The first column is the department, sorted but not categorized, then a view were the column is sorted on numbers. As numbers they don't sort in the "proper" order. So I created a new column that padded it with zeroes to for the sort to be correct:

@Right("00000" + @Text(MemberKey);5)

So the third column is just the number, so it appears properly.

So I want this in an XPage viewPanel and to use the startKeys to get the the number desired.

I set the viewPanel to filter by the department name, and don't display the padded view. But it doesn't work. It doesn't work if I use the padded column either. It's because I'm getting just one category, so it's not really "starting" there.

I noticed the startKeys element can take a Vector, so I tried that. And it works.

I have a view panel that does not

I have a field  where I populate a viewScope called vFilter. If that is null, it return just one element in the vector, the department. Otherwise it returns a two element vector, with the department and the number I want to go to.

Here is my code in the startKeys element. (I'm using part of Thomas Adrian's Intrapages).

var query = new java.util.Vector();
var v = database.getView("(LookupUsers)");
var userdoc:NotesDocument = v.getDocumentByKey("User_UNID_" + userid,true);
if(userdoc!=null){
    query.add(userdoc.getItemValueString('regDepartment'));
    } else {
    query.add("Department not found");
    }
if(viewScope.vFilter != null){
query.add(@Right('00000' +  viewScope.vFilter,5));
return query;
}
return query;


Cheers,
Brian

Wednesday, July 1, 2015

ComboBox - Validate so default value is not selected

One of the things that I've been trying to get to work in XPages is getting validation to reject the default value of a combobox. Well, this morning I sat down and decided to get it done. I've used other methods to get around this until now, but this seems to do it.

I have a combobox with "--Select--" as the default value. If that value is still there on submission, I want a display error control to execute. To do this, I think you need to have "--Select--" as the itemValue as well as the itemLabel, but I'm not sure, as I habitually use both anyway.

Add a validateContraint, and use the RegEx "^((?!--Select--).)*$" , I got this from this StackOverflow Post. So on submission, if a value hasn't been selected (errm, sorry) no dice.

I tested on a combobox that needed the user to select the month, the entire element is below.

There may be a better way, but having this will be a relief for me.

Cheers,
Brian
                    <xp:comboBox
                        id="comboBox1"
                        value="#{document1.rptCover}"
                        style="width:125.0px"
                        defaultValue="--Select--">

                        <xp:this.validators>                           
                            <xp:validateConstraint
                                regex="^((?!--Select--).)*$"
                                message="Select a month">
                            </xp:validateConstraint>
                        </xp:this.validators>
                        <xp:selectItem
                            itemLabel="--Select--"
                            id="selectItem15" itemValue="--Select--"/>

                        <xp:selectItem
                            itemLabel="January"
                            itemValue="January"
                            id="selectItem1" />

                        <xp:selectItem
                            itemLabel="February"
                            itemValue="February"
                            id="selectItem2" />

                        <xp:selectItem
                            itemLabel="March"
                            itemValue="March"
                            id="selectItem3" />

                        <xp:selectItem
                            itemLabel="April"
                            itemValue="April"
                            id="selectItem4" />

                        <xp:selectItem
                            itemLabel="May"
                            itemValue="May"
                            id="selectItem5" />

                        <xp:selectItem
                            itemLabel="June"
                            itemValue="June"
                            id="selectItem6" />

                        <xp:selectItem
                            itemLabel="July"
                            itemValue="July"
                            id="selectItem7" />

                        <xp:selectItem
                            itemLabel="August"
                            itemValue="August"
                            id="selectItem8" />

                        <xp:selectItem
                            itemLabel="September"
                            itemValue="September"
                            id="selectItem9" />

                        <xp:selectItem
                            itemLabel="October"
                            itemValue="October"
                            id="selectItem10" />

                        <xp:selectItem
                            itemLabel="November"
                            itemValue="November"
                            id="selectItem11" />

                        <xp:selectItem
                            itemLabel="December"
                            itemValue="December"
                            id="selectItem12" />
                    </xp:comboBox>

Friday, June 26, 2015

Populate an InputText Date field (that has a calendar picker)

I didn't see much on this, so I'm posting in case it helps someone.

I'm working on an application that has an XPage that a user fills out, then clicks to get a new version of that page. Most of the data should carry over, including an inputText field for a Domino document bound to a date field and I have the default datepicker on it.

I put the values from the first page into sessionScopes and used that to populate them for the next page. Easier on the user. All of them worked except the date.

Here is what worked.

Getting the value:

var nDT:NotesDateTime = document1.getItemValueDateTime('EventDate');
sessionScope.put("EventDate", nDT.getDateOnly());


Setting the value in afterPageLoad:

document1.replaceItemValue('EventDate', session.createDateTime(sessionScope.EventDate));

I've not found a way to set the component value yet, it's just not worked in any permutation I've tried so far. This does what I need so far, so I stopped trying on the component.

Cheers,
Brian

Wednesday, June 10, 2015

Looking for Domino/XPages Developer positions

My employer had decided to migration off the Domino platform. The direction chosen is not one I'm comfortable with, and so we have decided to part ways. They are doing no new development, and there will be limited allowance for changes to the existing .nsfs. I'm sad to have to go from what otherwise has been a great position, but where they are going is the one I don't want to go.

So, this puts me open. I'm up for contract or perm situations. I've been hitting the boards, but if you have a suggestion, please contact me at my yahoo.com address: brian.moore100 I've got quite a bit of experience, and I can bring that to work for you.

Cheers,
Brian

Thursday, June 4, 2015

First 2 repeat values on the same row - a simple example

I have some data where I want to show records about people in two columns. Even in one column, odd on the other. So like a categorized view, only rather then have each subsidiary datum on it's own row, I want two columns, so like this:




I'm using repeats for this. It's not overly complicated, but I thought it would be nice to post in case anyone wanted to see it. And this is a simple example, since I think those are important.

There may be better ways of doing this, but this is one solution. First, I take a repeat and populate it with 1 through 10 in an array. Then I iterate through that array and if the index of the array element is even, I put it in an array called "evenArray" (naturally). As you can guess, the other is "oddArray". Those arrays are each put in a sessionScope. After this, I create a new array with a single value and return that (the repeat needs to return something). I'm keeping this simple, but you could populate the arrays using a function or whatever.

Then I have a table with one row and two columns. Each column has a repeat in it. One column's repeat uses the oddArray sessionScope, the other uses the even one. There is a computed field returning the collection name of each array.

This can be expanded, of course. But this is a nice simple example of the process. I have the entire XPage below. You can pop it in and run it.

Cheers,
Brian

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <xp:panel>
        <xp:repeat
            id="repeat1"
            rows="30"
            var="rowData">
            <xp:this.value><![CDATA[#{javascript:var headArray = [];
headArray[0] = '1';
headArray[1] = '2';
headArray[2] = '3';
headArray[3] = '4';
headArray[4] = '5';
headArray[5] = '6';
headArray[6] = '7';
headArray[7] = '8';
headArray[8] = '9';
headArray[9] = '10';

var evenArray = [];
var oddArray = [];

for(n = 0; n < headArray.length; n++){
    if (n %2 == 0){
        evenArray.push(headArray[n]);
    } else{
        oddArray.push(headArray[n]);
    }
}

sessionScope.put('evenArray', evenArray);
sessionScope.put('oddArray', oddArray);

var rtnArray=[1];

return rtnArray;}]]></xp:this.value>
            <xp:table>
                <xp:tr>
                    <xp:td>
                        <xp:repeat
                            id="repeat2"
                            rows="30"
                            value="#{sessionScope.evenArray}"
                            style="width:161.0px"
                            var="evenRowData">
                            <xp:text
                                escape="true"
                                id="computedField2"
                                value="#{javascript:evenRowData.toString();}">
                            </xp:text>
                            <xp:br></xp:br>
                        </xp:repeat>
                    </xp:td>
                    <xp:td>
                        <xp:repeat
                            id="repeat3"
                            rows="30"
                            style="width:325.0px"
                            value="#{sessionScope.oddArray}"
                            var="oddRowData">
                            <xp:text
                                escape="true"
                                id="computedField3"
                                value="#{javascript:oddRowData.toString();}">
                            </xp:text>
                            <xp:br></xp:br>
                        </xp:repeat>
                    </xp:td>
                </xp:tr>
            </xp:table>
        </xp:repeat>
        </xp:panel>
    </xp:view>

Wednesday, June 3, 2015

Archive of my last Blog

I'm moving my blog over here, from BleedYellow. I created an XPage application to hold all my posts from there so that I have them and so they are independently available. I considered posting all here, but who wants that, eh? Here it is.

It should be easier to post here. And I have a couple coming up.

Cheers,
Brian

New blog

Moving over from my previous blog at http://www.bleedyellow.com/blogs/DominoHerald I'll be looking to move my posts to here or elsewhere. This will be a IBM/Lotus Notes/Domino centered blog and what I do in Java and NoSQL.

Cheers,
Brian