0
votes

Just fyi, I've been developing with xpages since they were introduced, so I feel like I somewhat know what I'm doing. However, this one case is driving me nuts.

I have two combo boxes, a ShipTo and a BillTo. The ShipTo selection will update the choices for the BillTo combobox. Nothing fancy.

Here's the problem. When the page opens, both fields are set with defaults. If I choose a different ShipTo, the BillTo choices change (as expected, from the panel partial refresh) BUT the onChange ssjs code in the ShipTo field does not run. Follow me, here.... when I change the ShipTo, it partial refreshes the enclosing panel onChange. The first thing that recomputes is the choices for the BillTo field. THEN, the onChange ssjs is triggered in the ShipTo field. It's not what one would expect, but my console messages show this to be true.

So, when the BillTo has a value (i.e. not = "-Select-") then the onChange ssjs does not fire. Once the BillTo refreshes to -Select- (because of the ShipTo change) then the ShipTo onChange ssjs will run just fine. Every time. UNTIL I select a BillTo... then the onChange ssjs will not run.

Crazy, I know. But, this is for a customer application, so I need to get it figured out.

Here's the console when the BillTo = "-Select-"

HTTP JVM: getting billto choices

HTTP JVM: ... billto values complete

HTTP JVM: shipto onchange

HTTP JVM: sel=CelayaH4999

Now, when I select a valid BillTo (no refresh or onchange events there) and then reselect a ShipTo, I get this...

HTTP JVM: getting billto choices

HTTP JVM: ... billto values complete

The ShipTo onChange ssjs NEVER RUNS. Go figure.

Here's my test page:

    <?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="Entry1">

        <xp:this.postNewDocument>
            <xp:executeScript>
                <xp:this.script><![CDATA[#{javascript:document1.replaceItemValue("CurrentForm","Entry1");
var res = InitializeWF("Entry1",document1,true);  //newdoc
var res = InitializeDefaults(document1);

document1.replaceItemValue("ShipToKeyx",document1.getItemValueString("ShipToKey"));
document1.replaceItemValue("BillToKeyx",document1.getItemValueString("BillToKey"));

document1.replaceItemValue("MpxLoc","Y");   //for compatibility

}]]></xp:this.script>
            </xp:executeScript>
        </xp:this.postNewDocument></xp:dominoDocument>
    </xp:this.data>
    <xp:this.resources>
        <xp:script src="/xpServerSide.jss" clientSide="false"></xp:script>
    </xp:this.resources>
    <xp:panel id="panelPage">


        <xp:comboBox id="ShipToKey" value="#{document1.ShipToKeyx}">
            <xp:selectItems id="selectItems5">
                <xp:this.value><![CDATA[#{javascript:var list = @DbColumn(@DbName(),"shpmstlookupui",9);
list.sort();
list.unshift("-Select-");
@Unique(list)}]]></xp:this.value>
            </xp:selectItems>
            <xp:eventHandler event="onchange" submit="true"
                refreshMode="partial" refreshId="panelPage" id="eventHandler9">
                <xp:this.action>
                    <xp:executeScript>
                        <xp:this.script><![CDATA[#{javascript:print("shipto onchange")
var sel = getComponent("ShipToKey").getValue();
print("sel="+sel)
var res = true;
if(sel==null || sel=="" || sel=="-Select-"){
    document1.replaceItemValue("ReqShipToAddress","");
    res = false;
}

if(res){
    var sview = database.getView("shpmstlookupui");
    var vdoc = sview.getDocumentByKey(sel,true);
    if(vdoc!=null){
        document1.replaceItemValue("ReqShipToAddress",vdoc.getItemValue("ShipFull"));
    }
}

//verify billto is from this same whs
//print("shipwh = " + document1.getItemValueString("ShipWh")+", billwh = "+document1.getItemValueString("BillWh"))
if(!res || document1.getItemValueString("ShipWh")!=document1.getItemValueString("BillWh")){
    document1.replaceItemValue("BillToKey","-Select-");
}
    }]]></xp:this.script>
                    </xp:executeScript>
                </xp:this.action>
            </xp:eventHandler>
        </xp:comboBox>
        <xp:br></xp:br>
        <xp:text escape="false" id="computedField11">
            <xp:this.value><![CDATA[#{javascript:var list = new Array(document1.getItemValue("ReqShipToAddress"));
//print("shipto address list len = "+list.length+", list = "+list)
if(list.length==0){return null;}
return "<UL style='list-style-type: none;padding: 0px;margin: 0px'><LI>" + @Implode(list,"<LI>") + "</UL>";}]]></xp:this.value>
        </xp:text>
        <xp:br></xp:br>
        <xp:br></xp:br>
        <xp:comboBox id="BillToKey" value="#{document1.BillToKeyx}">
            <xp:selectItems id="selectItems6">
                <xp:this.value><![CDATA[#{javascript:var tmparrx = new Array("bob","tim")
tmparrx.sort();
tmparrx.unshift("-Select-");

print("getting billto choices ==============================================================================")
var sel = getComponent("ShipToKey").getValue();
if(sel==null || sel=="-Select-" || sel==""){
print("sel is null, returning tmparrx");
return @Unique(tmparrx);
    //try xsp value
    sel = document1.getItemValueString("ShipToKey");
    if(sel==null || sel=="-Select-" || sel==""){
        var shipwh = null;
    }
    else {
        var shipwh = null;
        var sview = database.getView("shpmstlookupui");
        var vdoc = sview.getDocumentByKey(sel,true);
        if(vdoc!=null){
            shipwh = vdoc.getItemValueString("Shipwh");
        }
    }
}
else {
    var shipwh = null;
    var sview = database.getView("shpmstlookupui");
    var vdoc = sview.getDocumentByKey(sel,true);
    if(vdoc!=null){
        shipwh = vdoc.getItemValueString("Shipwh");
    }
//  print("got shipwh = "+shipwh)
//  return @Unique(tmparrx);
}
if(shipwh==null){return null;}

var list = @DbLookup(@DbName(),"shpmstlookup2",shipwh,9);
if(typeof list==="string"){
    var tmparr = new Array(list);
}
else {
    var tmparr = list;
}
tmparr.sort();
tmparr.unshift("-Select-");
print("... billto values complete");
//return @Unique(tmparrx);
return @Unique(tmparr);


/*
//check existing selection
var sel = document1.getItemValueString("BillToKey");
print("initial value = "+sel)
var found = false;
for(x=0;x<tmp2.length;x++){
    var entry = tmp2[x];
    if(entry.toLowerCase().indexOf(sel.toLowerCase())>=0){
    print("found = true")
        found = true;
    }
}
if(!found){
print("not found")
    document1.replaceItemValue("BillToKey","-Select-");
}
var sel = document1.getItemValueString("BillToKey");
print("post value = "+sel)
tmp2
*/}]]></xp:this.value>
            </xp:selectItems>

        </xp:comboBox>
        <xp:br></xp:br>
        <xp:br></xp:br>

    </xp:panel>

</xp:view>

It's the craziest thing.

If I return a new Array("bob","tim") for the BillTo choices, then all works as it should - no matter what the BillTo selection is. But, when I return the BillTo choices as computed, then it doesn't work. So, it appears there's a problem with the BillTo choices formula, but I can't find anything wrong.

Can someone identify the stupid mistake I'm making? - or, point me in the right direction to get this cleared up?

1
Try replacing all your getComponent calls with data source calls (ie. document1.getValue(“ShipToKeyx”) etc.) in order to make sure that you get the actual changed valuesPer Henrik Lausten
Thanks, but those values are getting pulled correctly.Bob Cross

1 Answers

0
votes

I narrowed down the problem to this: The ShipTo selection changes the choices for the BillTo field. If the BillTo was -Select- then everything worked fine, because -Select- is always a valid choice for any ShipTo. However, if the BillTo had a valid selection, then when the ShipTo was changed, that BillTo selection is now no longer valid for the new BillTo choices. This caused the ShipTo onChange event to not run. (remember, the BillTo choices formula runs BEFORE the ShipTo onChange)

I could not find a solution, so I instead just used a workaround.

I put my ShipTo onChange code in a script library function and then call it in both the ShipTo onChange event AND also the BillTo selection choices formula. So, now, if the current BillTo selection does not match the new list of choices for the BillTo, then I call the ShipTo onChange function from the choices formula - because I know it won't run once the choices are calculated. This workaround works, but I have a feeling this issue will probably bite me again in the future.

Now that I have a better understanding, you can easily test it yourself by using two comboboxes where the second set of choices depends on the first box selection. Put a print statement in the first box onChange and you'll see that it will not fire unless the second box selection matches one of the new set of choices based on the first box selection.

I can't explain it any more than that, but I hope this post can help someone else.