1

I have an EditBox control in a repeat control. Its iteration formula is:

return 5;

It is successfully displaying 4 edit boxes (the starting index is set to 1).

In SSJS, how can I get the value of the nth Edit Box?

user unknown
  • 35,537
  • 11
  • 75
  • 121
Bruce Stemplewski
  • 1,343
  • 1
  • 23
  • 66

4 Answers4

2

You could set a sessionScope variable (or any scope variable) on the onchange event of the edit box and then in your SSJS reference the sessionScope variable. Here is some sample code, the bottom bit just shows your sessionScope variables on the page.

<?xml version="1.0" encoding="UTF-8"?>

<xp:repeat id="repeat1" rows="30" value="#{javascript:5}"
    indexVar="rptIndex">

    <xp:inputText id="inputText1">

    <xp:eventHandler event="onchange" submit="true" refreshMode="complete">
        <xp:this.action>
            <xp:executeScript>
                <xp:this.script><![CDATA[#{javascript:sessionScope['text'+rptIndex] = getComponent("inputText1").getValue()}]]></xp:this.script>
            </xp:executeScript>
        </xp:this.action></xp:eventHandler></xp:inputText>

</xp:repeat>



<xp:table styleClass="debug">
<xp:tr>
<th>Variable Name</th>
<th>Variable Content</th>
</xp:tr>
<xp:repeat id="varRepeat" rows="30" value="#{javascript:sessionScope.keySet();}" var="scopeData">
<xp:tr>
<xp:td>
<xp:text escape="true" id="varName" value="#{javascript:scopeData}" />
</xp:td>
<xp:td>
<xp:text escape="true" id="varValue" value="#{javascript:sessionScope.get(scopeData)}" />
</xp:td>
</xp:tr>
</xp:repeat>
</xp:table> 
</xp:view>
Dan Herman
  • 1,395
  • 1
  • 15
  • 26
  • Yeah been down that road on a similar issue with multiple custom controls on the same xPage. What I really want to do is to get to the control itself so I can set the focus if a validation fails. I would think this should be able to be done since you can see an "index" number in the id of each edit box in the html source. One thought on that other issue was to use a "dynamic" id name but I haven't been able to figure that out. – Bruce Stemplewski Apr 04 '12 at 21:06
  • I dont know of any way to dynamically set the id unfortunately.. Not sure if that is possible. – Dan Herman Apr 05 '12 at 00:06
  • 1
    DONT use the session scope for this sort of things. Please use the correct scope. For a repeating edit box the viewscope should be the scope to use. – jjtbsomhorst Apr 05 '12 at 07:01
  • Have you noticed that if you click on a field and then click on the address bar, the onchange event doesn't get fired? – pipalia Apr 06 '12 at 15:15
2

When you add a submission to an onChange event you create a rather chatty application - might bite you. The solution for setting the focus is rather different. First: focus is a client side operation, so you need a client script that 'knows what control is the first failure. The good news: XPages adds to all fields that failed a server side validation the attribute aria-invalid=true. So you can use a dojo.onLoad script that queries that and sets the focus to the first member of the result. See also http://dontpanic82.blogspot.com/2011/07/xpages-styling-invalid-field.html And for the query syntax: http://dojotoolkit.org/reference-guide/1.7/dojo/query.html

stwissel
  • 20,110
  • 6
  • 54
  • 101
1

Repeats are fun to deal with to say the least. If you look at examples in the teamroom template mobileThread custom control you'll see a repeat for displaying a list of replies, you'll also notice a lot of javascript to go along with it as for example running script on one button click would run on all buttons in the repeat.

If you are looking for the validation problem stwissel's solution looks the best. If this is something else and at some point you just need the value of any given edit box, maybe you should think about something like:

var domEl = dojo.byId(' <repeatControlId> ');
var textBoxes = domEl.getElementsByTagName("input");
var certainValue = textBoxes[3].value;

Now certainValue contains the value of a given edit box.

haven't tried this out, might need a little tweaking but the general idea should work I would think.

Simon McLoughlin
  • 8,293
  • 5
  • 32
  • 56
  • This looks promising. But this seems to be Client side? I need server side. Is this the code that is found in the template or something you came up with? I can't seem to get it to work. I think this line var certainValue = textBoxes[3].value; is causing 'undefined' is null or not an object. My repeat control has an id of repeat1 so I have var domEl = dojo.byId('repeat1'); – Bruce Stemplewski Apr 05 '12 at 12:53
  • no this is client side, my thinking was this could be run in client side and passed off to the server. I don't know your use case but hidden input boxes, executeOnServer() function, jsonRpcService control something along these lines maybe. No this is something I made up on the spot, yes your issue there is that dojo.byId is a client side function and the client side id of the repeat is not 'repeat1' its eg. view:panel_34:repeat1. So use dojo.byId('#{id:repeat1}'); to get the full client id – Simon McLoughlin Apr 05 '12 at 13:30
  • Thanks! OK I am much closer but I am getting undefined for alert("Value 1= " + textBoxes[1]); A alert box shows Value 1= undefined. Sorry for being such a newb. :) – Bruce Stemplewski Apr 05 '12 at 13:43
1

added another comment so i could add code.

Did a quick test and works fine for me, see my example below. Hope it helps. Try adding some print outs to see is it getting each bit.

<xp:repeat id="TestRepeat" rows="100" var="rowData"
    indexVar="commentIndex" first="0" rendered="true">
    <xp:this.value><![CDATA[#{javascript:
        var dataArray = new Array();
        dataArray.push(" Test");
        dataArray.push(" Test");
        dataArray.push(" Test");
        dataArray.push(" Test");
        dataArray.push(" Test");
        return dataArray;
    }]]></xp:this.value>

    <xp:panel>
        <xp:label value="Test"></xp:label>
        <xp:inputText id="inputText1" value="Test" defaultValue="Test">
        </xp:inputText>
        <xp:br></xp:br>
    </xp:panel>

</xp:repeat>

<xp:button value="Test" id="button1">
    <xp:eventHandler event="onclick" submit="false">
        <xp:this.script>
            <xp:executeClientScript>
                <xp:this.script><![CDATA[
                var domEl = dojo.byId('#{id:TestRepeat}');
                var textBoxes = domEl.getElementsByTagName("input");
                alert( "Value 1: " + textBoxes[0].value);
                ]]></xp:this.script>
            </xp:executeClientScript>
        </xp:this.script>
    </xp:eventHandler>
</xp:button>
Simon McLoughlin
  • 8,293
  • 5
  • 32
  • 56
  • Yep works for me too. Not sure what I was doing wrong. You don't even have to declare that array. A simple return 4; works just fine. Thanks for the help. – Bruce Stemplewski Apr 05 '12 at 16:59
  • No prob, I look for questions when I can so I'll be around if anything else comes up. Don't be shy with marking anything as a top answer the reputation points look good while I'm trying to answer more ;-) – Simon McLoughlin Apr 05 '12 at 18:40