0

Hi I'm new to Xpages and have encountered an issue for which I am unable to find a relevant question / answer after searching (see title for search terms).

I would be grateful for insight into how to solve the following issue.

I have a nest of 3 Dojo Tab Containers, each container holds a repeat container with a Dojo Tab Control, the inner most Tab Control carries a standard checkBoxGroup.

The computed labels for the tabs are read from a multi-dimensional sessionScope variable, the final dimension carries the computed 'label|value' pairs for the checkBoxGroup. The data is bound to a document.

I can switch between the various tabs and select/deselect check boxes and the status remains tracked when switching back an forth among the tabs. However, and this is the crux, only the checkBoxGroup values on the final tab are written back to the underlying document on submission, the checkBoxGroup values displayed on the other innermost tabs are ignored.

Any advice guidance on how to resolve this issue would be gratefully received.

    <xe:djTabContainer id="djTabContainer1"
                        style="height:600px;width:1200.0px"
                        doLayout="false">
                        <xe:this.rendered><![CDATA[#{javascript:control = getComponent("STP2radioGroup1");
control2 = getComponent("STP2radioGroup2");

if (control == null || control2 == null){return false;};

val = control.getValue();
val2 = control2.getValue();

if (val == "None" || val2 == "All") {
    false ;
}                           
else {
    true;
}}]]></xe:this.rendered>
                        <xp:repeat id="repeat1" rows="30"
                            value="${sessionScope.GHC}" var="GHCTabs" first="0"
                            indexVar="GHCTabIndex" repeatControls="true">
                            <xe:djTabPane id="djTabPane1"
                                title="#{javascript:GHCTabs}">
                                <xe:this.rendered><![CDATA[#{javascript:!empty(sessionScope.Services[GHCTabIndex])}]]></xe:this.rendered>
                                <xe:djTabContainer id="djTabContainer2"
                                    style="height:550px" doLayout="false">
                                    <xp:repeat id="repeat3" rows="30"
                                        value="${sessionScope.Enviro}" var="EnviroTabLables"
                                        indexVar="EnviroTabIndex" first="0" repeatControls="true">
                                        <xe:djTabPane id="djTabPane2"
                                            title="#{javascript:EnviroTabLables}">
                                            <xe:this.rendered><![CDATA[#{javascript:!empty(sessionScope.Services[GHCTabIndex][EnviroTabIndex])}]]></xe:this.rendered>
                                            <xe:djTabContainer
                                                id="djTabContainer3" style="height:500px"
                                                doLayout="false">
                                                <xp:repeat id="repeat2"
                                                    rows="30" value="${sessionScope.Aspect}" var="AspectTabs"
                                                    indexVar="AspectTabIndex" first="0"
                                                    repeatControls="true">
                                                    <xe:djTabPane
                                                        id="djTabPane3" title="#{javascript:AspectTabs}">
                                                        <xe:this.rendered><![CDATA[#{javascript:try{
if (sessionScope.Services[GHCTabIndex][EnviroTabIndex][AspectTabIndex] == null){false}
else
{true}
}
catch(e){
dBar.error("Error in 'Visible' property for Aspect Tab for checkBoxGroup - " + e.toString)}}]]></xe:this.rendered><xp:checkBoxGroup
                                                            id="checkBoxGroup1" styleClass="threeColumnCheckboxGroup"
                                                            value="#{Subscription.Services}" style="width:100.0%">
                                                            <xp:selectItems>
                                                                <xp:this.value><![CDATA[${javascript:try{
if (sessionScope.Services[GHCTabIndex][EnviroTabIndex][AspectTabIndex] == null){
dBar.error("sessionScop.Services["+GHCTabIndex+"]["+EnviroTabIndex+"]["+AspectTabIndex+"] = null")}
else
{sessionScope.Services[GHCTabIndex][EnviroTabIndex][AspectTabIndex]}
}
catch(e){
dBar.error("checkBoxGroup")}}]]></xp:this.value>
                                                            </xp:selectItems>
                                                        </xp:checkBoxGroup>






                                                </xe:djTabPane>
                                            </xp:repeat>
                                        </xe:djTabContainer>
                                    </xe:djTabPane>
                                </xp:repeat>
                            </xe:djTabContainer>
                        </xe:djTabPane>
                    </xp:repeat>
                </xe:djTabContainer>
  • As an attempt to find a work around I put the following in CSJS on the onClick event for the repeated checkBoxGroup control....the idea being to see if I can get a handle to the value of the field and may be do something with it in order to create a work around. – Phill Beckman Jan 11 '17 at 13:17
  • try{ var currId = '#{javascript:getClientId("checkBoxGroup1")}'; var checkField = document.getElementsById(currID); var result=[]; for(var i=0;i – Phill Beckman Jan 11 '17 at 13:21
  • it gives the following alert response - "function toString(){[native code]}" which doesn't help me at all :-( – Phill Beckman Jan 11 '17 at 13:21
  • currId is returning a the ID and is of the form view:_id1:SubscriptionTabPanel2:djTabContainer1:repeat1:0:djTabPane1:.....[insert more tab and pane descriptions]....:checkBoxGroup1. But it doesn;t return a value when I use it to get at the control values. – Phill Beckman Jan 11 '17 at 13:44

1 Answers1

1

All rows of the repeat are bound to the same sessionScope variable. That means they will replace not append to the scoped variable.

For binding editable fields within a repeat, you'll need to do something along the lines of Tim's answer to this question. I would recommend setting repeatControls="true" on all repeats, so the rows are created and bound when the page is loaded. You may get unpredictable results with components bound dynamically because, after the initial load, it's a one-way mapping from the component to wherever the value is stored. If the order of the repeat changes, the component values won't, and so the values will be out of step with what you expect.

Community
  • 1
  • 1
Paul Stephen Withers
  • 15,699
  • 1
  • 15
  • 33
  • Thank you Paul for taking the time to post an answer, unfortunately I lack the skill to interpret Tims answer enough to elicit a solution from it. I'm not sure how to apply the data context to single field ...in a nested container and how I relate that back to the underlying 'Services' field which is bound as the data resource for the checkBoxGroup, would you be able to provide any further insight ? – Phill Beckman Jan 11 '17 at 10:35
  • Please note I already have 'create controls at page creation' checked for all repeats i.e. repeatControls = true – Phill Beckman Jan 11 '17 at 10:38
  • The checked status of the checkBoxGroup is correct at time of load, i.e. it's reading the labels correctly and displaying the individual check marks correctly for the values stored in the 'Services' field of the back end document....how do I apply the 'data context' so that all the repeated checkBoxGroup controls update only their own values in the 'Services' field. – Phill Beckman Jan 11 '17 at 10:59
  • "All rows of the repeat are bound to the same sessionScope variable. That means they will replace not append to the scoped variable." - Actually the scoped variable only gives the labels for the Tab Panes, and the labels and values for the repeated checkBoxGroup.....the 'Data Source' of which is bound to the 'Services' field on a 'Subscription' form of the current database. – Phill Beckman Jan 11 '17 at 13:49
  • That's correct, but the same issue is still true - they're all bound to the same field, which means each is overwriting the value set by the previous row, not appending. The scenario Tim uses is to add a `dataContext` (which can be added via the `Data` area in the All Properties area of a Panel) to compute a unique field name. Setting `indexVar` on the repeat control will allow you to get the row number, e.g. 0, 1, 2 etc. Binding to `#{myDoc[fieldName]`, assuming `fieldName` is the `var` of the `dataContext`. – Paul Stephen Withers Jan 11 '17 at 16:26
  • Alternatively, if you create a scoped variable that's an array, with the relevant number of values, you may be able to map to an element in that array, and in your save, write it back to your underlying document. But it's not functionality I've had to use, so this is purely theoretical. – Paul Stephen Withers Jan 11 '17 at 16:27
  • Thanks Paul I've studied your answer and can understand the error I made and have now made the viewScope variables to contain the list|value pairs for each repeat control input checkBoxGroup along with a viewScope variable containing the names of additonal viewScope variables which contain the current selected matches. I removed the nesting for proof of concept purposes and have come up with this . – Phill Beckman Jan 15 '17 at 01:19
  • code <![CDATA[#{javascript:viewScope.vwScSelNames[tabsIndex];}]]> code – Phill Beckman Jan 15 '17 at 01:20
  • code <![CDATA[#{javascript:viewScope[selectedVSName];}]]> <![CDATA[#{javascript:viewScope.get(viewScope.vwScPairsNames[tabsIndex]);}]]> code – Phill Beckman Jan 15 '17 at 01:20
  • The checkBoxGroup's successfully show the currently selected values as held on the back end document but no check boxes ! looks as if the control is read only. if I remove this line <![CDATA[#{javascript:viewScope[selectedVSName];}]]> It shows the correct editable empty check boxes but then they're not bound to anything to write the selected values back to storage...I'm really stumped. – Phill Beckman Jan 15 '17 at 01:25
  • Thanks for the help I now have this control working by binding to a multi dimensional array for data[i][j][k][l] (viewScope) with the same dimensions as the sessionScope array containing the label|value pairs. – Phill Beckman Jan 19 '17 at 12:57