1
votes

I am using Teamstudio Unplugged to try and Extend a table row with inputTexts bound to a document.

The function of this table is for the user to write down a observation and then a description of the observation.

After this the user should be able to press a button and get another row so he can add another observation.

I cannot partially refresh the entire table because it would cause the inputTexts to reload the value bound to them.

I cannot partially refresh the new row and change its styleclass with serverside scripts because IDs does not carry over from the designer. Meaning that this in the designer:<xp:tr id="row1"> becomes this in the pc simulator: <tr> So I can't solve this problem with a computed styleclass and a partial refresh. So i have now built a button included below but it only changes works twice. after that the onclick string never changes.

<xp:button value="Flere observationer" id="button4" styleClass="button">
    <xp:this.attrs>
        <xp:attr name="onclick">
            <xp:this.value><![CDATA[#{javascript:
                return "$('.row"+sessionScope.rows+"').removeClass('hidden');"
            }]]></xp:this.value>
        </xp:attr>
    </xp:this.attrs>
    <xp:eventHandler event="onclick" submit="true" refreshMode="partial"
         refreshId="button4">
        <xp:this.action>
            <xp:executeScript script="#{javascript:sessionScope.rows++;}">
            </xp:executeScript>
        </xp:this.action>
    </xp:eventHandler>
</xp:button>
2

2 Answers

1
votes

This can be done in Unplugged using standard(-ish) XPages techniques, which may be easier for anyone not well versed in JQuery. I would never recommend using a table for layout purposes, use <div> and or <ul/li> tags and use CSS. However for the purpose of answering this specific question I've used a table (climbing off soapbox now)...

So I'm assuming that the data in each row is in the same document. If so and the user is writing one observation at a time why not use a full refresh? Everything is done client-side on Unplugged (even the server parts - if that makes sense) so its fast. This method shows existing observations (if applicable) and allows the users to enter one more row at a time:

Add a hidden field on your form - NoOfObservations - this can be a text field and will be used as an index in the XPage.

Add your datasource on an XPage to the form

Create a beforePageLoad event to set the index from either an existing doc or new one:

<xp:this.beforePageLoad><![CDATA[#{javascript:
var ObservationCount = 0;
if(!document1.isNewNote()){
ObservationCount = document1.getItemValue("NoOfObservations")[0];
}
sessionScope.put("observations", ObservationCount);
}]]>
</xp:this.beforePageLoad>

Create your table with existing rows - using the xp:repeat Control with the index in the sessionScope to produce your rows - adding 2 new lines for new entries:

<table>
    <xp:repeat id="repeat1" rows="30" var="rowData"
        indexVar="dataRows">
        <xp:this.value><![CDATA[#{javascript:sessionScope.get("observations");}]]></xp:this.value>
        <tr>
            <td>
                <xp:label value="Observation" id="label1"
                    style="color:rgb(255,255,255)">
                </xp:label>
            </td>
            <td>
                <xp:text escape="true" id="computedField1">
                    <xp:this.value><![CDATA[#{javascript:return document1.getItemValueString("ObservationTitle" + dataRows);}]]></xp:this.value>
                </xp:text>
            </td>
        </tr>
        <tr>
            <td>
                <xp:label value="Details" id="label2"
                    style="color:rgb(255,255,255)">
                </xp:label>
            </td>
            <td>
                <xp:text escape="true" id="computedField2">
                    <xp:this.value><![CDATA[#{javascript:return document1.getItemValueString("ObservationDesc" + dataRows);}]]></xp:this.value>
                </xp:text>
            </td>
        </tr>
    </xp:repeat>
    <tr>
        <td>
            <xp:label value="New Observation"
                id="newObservationTitle" style="color:rgb(255,255,255)">
            </xp:label>
        </td>
        <td>
            <xp:inputText id="inputText1"></xp:inputText>
        </td>
    </tr>
    <tr>
        <td>
            <xp:label value="New Description"
                id="newObservationDesc" style="color:rgb(255,255,255)">
            </xp:label>
        </td>
        <td>
            <xp:inputTextarea id="inputTextarea1"></xp:inputTextarea>
        </td>
    </tr>
</table>

Use an xp:button with the following SSJS in the onClick event:

<xp:button value="Save" id="button1">
    <xp:eventHandler event="onclick" submit="true"
        refreshMode="complete">
        <xp:this.action>
            <xp:actionGroup>
                <xp:executeScript>
                    <xp:this.script><![CDATA[#{javascript:
var newObservation = parseInt(sessionScope.get("observations")) +1;
document1.replaceItemValue("ObservationTitle" + newObservation,  getComponent("inputText1").getValue());
document1.replaceItemValue("ObservationDesc" + newObservation, getComponent("inputTextarea1").getValue());
document1.replaceItemValue("NoOfObservations", newObservation);
document1.save();}]]></xp:this.script>
                </xp:executeScript>
                <xp:openPage name="/UnpMain.xsp"></xp:openPage>
            </xp:actionGroup>
        </xp:this.action>
    </xp:eventHandler>
</xp:button>
0
votes

As with your other question, again I would be inclined to do this client side rather than trying to do partial refreshes. Simply add rows to the table using jQuery and then store the values from each row into hidden list fields when saving the document.

Also again, for the IDs that you want to work with, rather than rely on the IDs being generated by the server, add your own attributes and select items using those instead.