1
votes

Please see clarification at the botom of this email.

I have an Xpage where the user will choose an employee, after which a series of employee dependent fields should populate. I have done this before when my source was a document, but now I am using Objects. My object is bound to a java bean.

enter image description here

For some reason I cannot get the on change event to fire when the Employee Name changes; at other times I can get the event to fire, but when I try to send the selection to a java method to load the values, I cannot get the value of the field.

What I think I have to do is put code in the onChange event of the employee field that grabs the value the user chose and then call a java method in my bean that will load the other employee values and then reload the panel. Boy, takes a long time even to write that!

Any help would be greatly appreciated.

<?xml version="1.0" encoding="UTF-8"?>
<xp:view
    xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xc="http://www.ibm.com/xsp/custom"
    xmlns:xe="http://www.ibm.com/xsp/coreex"
    createForm="false">
    <xp:panel
        id="pnlAll">
        <xp:eventHandler
            event="refresh"
            submit="false"
            refreshMode="partial"
            loaded="false"/>    
        <xp:this.data>
            <xe:objectData
                saveObject="#{javascript:tr.save()}"
                var="tr">
                <xe:this.createObject><![CDATA[#{javascript:var tr = new com.scoular.model.TerminationRequest();
var unid = context.getUrlParameter("key")

if (unid != "") {
    tr.loadByUnid(unid);
    viewScope.put("readOnly","Yes");
} else {
    tr.create();
    viewScope.put("readOnly","No");
}
return tr;}]]></xe:this.createObject>
            </xe:objectData>
        </xp:this.data>
        <xp:div
            styleClass="container-fluid"
            id="divTravelRequest">



            <div
                class="panel panel-primary"
                id="div6">
                <div
                    id="divEmployeeInfo"
                    class="panel-collapse collapse in">
                    <div
                        class="panel-body"> 
                        <!--Row-->
                        <div
                            class="row">
                            <div
                                id="div2">
                                <div
                                    class="col-sm-6 pull-left">
                        <xp:inputText
                        value="#{tr.employeeName}"
                        id="employeeName1"
                        style="width:300px"
                        xp:key="field">
                        <xp:eventHandler
                            event="onchange"
                            submit="true"
                            refreshMode="norefresh"
                            id="eventHandler1">
                            <xp:this.action><![CDATA[#{javascript:var prmEmpNme:String = getComponent("employeeName1").getValue();
var javaClass = new com.scoular.model.TerminationRequest();
javaClass.setEmployeeData(prmEmpNme);}]]></xp:this.action>
                        </xp:eventHandler>
                        </xp:inputText>

                    &#160;&#160;&#160;

                    <xe:namePicker
                        id="namePicker2"
                        dialogTitle="Select a Name"
                        for="employeeName1" rendered="false">
                        <xe:this.dataProvider>
                            <xe:dominoNABNamePicker
                                addressBookDb="bryansMac!!names.nsf"
                                addressBookSel="db-name"
                                nameList="people"
                                people="true" />
                        </xe:this.dataProvider>
                        <xe:this.dojoAttributes>
                            <xp:dojoAttribute
                                name="maxRowCount"
                                value="1000" />
                        </xe:this.dojoAttributes>
                    </xe:namePicker>

                                            <xp:listBox
                                                xp:key="field"
                                                id="listBoxEmpNme"
                                                style="width: 100% !important;"
                                                value="#{tr.employeeName}">
                                                <xp:selectItems>
                                                    <xp:this.value><![CDATA[#{CacheBean.employees}]]></xp:this.value>
                                                </xp:selectItems>
                                                <xp:eventHandler
                                                    event="onchange"
                                                    submit="true"
                                                    refreshMode="norefresh">
                                                    <xp:this.action><![CDATA[#{javascript:var scriptCode = "alert('This got fired')"
view.postScript(scriptCode); }]]></xp:this.action>
                                                </xp:eventHandler></xp:listBox>

                                            <xp:div
                                        style="height:10.0px" />


<xp:scriptBlock id="scriptBlock2">
<xp:this.value><![CDATA[$(document).ready(
function() {
x$( "#{id:listBoxEmpNme}" ).select2({
placeholder: "Select The Scoular Employee To Term",
allowClear: true
});
}
);]]></xp:this.value>
            </xp:scriptBlock>                                       
            <xp:div style="height:10.0px" />
            </div>
                <div class="col-sm-6 pull-right">

                        <xp:inputText
                                id="inputText2"
                                xp:key="field"
                                value="#{tr.employeeLocation}">
                                <xp:this.disabled><![CDATA[#{javascript:true}]]></xp:this.disabled>
                                </xp:inputText>
                                </div>

                            </div>
                        </div>

                    </div>
                </div>
            </div>
        </xp:div>
    </xp:panel>
    </xp:view>

============================

The issue I have is that when the user changes the value of employeeName the partial refresh does fire, BUT value that has been changed [employeeName] is not reflected in the backing bean. If I can do this, then everything will be fine.

2
Why do you set createForm to false? This means that there's no form that can be submitted. This could explain your problemPer Henrik Lausten
Per, I am not sure. I believe there was a reason why I did this on a different project, and I copied the code from that project. I will remove this and see if that fixes the problem.Bryan Schmiedeler
I'd like to echo @PerHenrikLausten's concerns regarding createForm="false", as that interferes with how the page will normally post back changes. Also, what is that first xp:eventHandler block doing? The one bound to the xp:panel; I would remove it (even though it claims loaded="false", you obviously don't want it), as I've only had trouble with high level bound eventHandlers that don't directly tie to an actual event.Eric McCormick
I agree that I should remove both things and I have done so. My original problem generally is almost solved, but not quite. I cannot use the onChange event with Select2, so what dizdman wrote below unfortunately won't work. I discovered that I must use a panel as the target of my refresh in the JS code, so I have done that, and the items inside the panel get refreshed. The issue is that the item that fires the refresh, a change to the employeeName, doesn't bind to the back end bean, so my updates will fail. I will put the code above.Bryan Schmiedeler

2 Answers

1
votes

This is a working example of your sample XPage reduced to the things necessary.

It uses Select2 and it executes XSP.partialRefreshPost on listBox's onchange event.

XSP.partialRefreshPost submits the listBox value employeeName to server and gets the refreshed panel panelRefresh back. The Server calls bean's method setEmployeeName(employeeName) to set the new employeeName value in bean and calls getEmployeeLocation() to get employeeLocation.

<?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.resources>
        <xp:styleSheet href="select2v4/css/select2.css" />
        <xp:script src="select2v4/js/select2.js" clientSide="true" />
    </xp:this.resources>
    <xp:scriptBlock id="scriptBlock1">
        <xp:this.value><![CDATA[
            $(document).ready(
                function() {
                    x$("#{id:listBoxEmpNme}").select2({
                    placeholder: "Select the Employee",
                    allowClear:  true
                });
                x$("#{id:listBoxEmpNme}").on('change', function(e) { 
                    XSP.partialRefreshPost("#{id:panelRefresh}", {immediate: true});
                })}
            );
        ]]></xp:this.value>
    </xp:scriptBlock>
    <xp:this.data>
        <xe:objectData
            saveObject="#{javascript:tr.save()}"
            var="tr">
            <xe:this.createObject><![CDATA[#{javascript:
                var tr = new com.scoular.model.TerminationRequest();
                tr.create();
                return tr;
            }]]></xe:this.createObject>
        </xe:objectData>
    </xp:this.data>
    <xp:listBox
        id="listBoxEmpNme"
        value="#{tr.employeeName}">
        <xp:selectItems>
            <xp:this.value><![CDATA[#{CacheBean.employees}]]></xp:this.value>
        </xp:selectItems>
    </xp:listBox>
    <br /><br />
    <xp:panel id="panelRefresh">
        <xp:text
            escape="true"
            id="computedField1"
            value="#{tr.employeeLocation}" />
    </xp:panel>
</xp:view>
0
votes

In your onchange method you create new java object, and you are not using this object any more. Probably you should refer to ObjectData you have created before. Second thing is that you set refreshMode property for you input controls to norefresh. Even if you update the data the page won't be refreshed and you won't see the result. Try complete or patrial mode. Check the code below.

<xp:inputText
value="#{tr.employeeName}"
id="employeeName1"
style="width:300px"
xp:key="field">
<xp:eventHandler
    event="onchange"
    submit="true"
    refreshMode="complete"
    id="eventHandler1">
    <xp:this.action><![CDATA[#{javascript:var prmEmpNme:String = getComponent("employeeName1").getValue();
    tr.setEmployeeData(prmEmpNme);}]]>
    </xp:this.action>
</xp:eventHandler>