Nov 19, 2015, 2:23 AM
8 Posts

copyAllItems - value disappears on xpage save when computed field control

  • Category: Other
  • Platform: Windows
  • Release: 9.0.1
  • Role:
  • Tags:
  • Replies: 7

Hi All

I have XPage1 where I enter values, there is a button to save the data sources and use the Create Response document to open XPage2. The beforePageLoad on XPage2 performs a copyAllItems between the new document and the parent (data source XPage1) and DOESN'T save data source on XPage2 (yet). I can edit values and save Xpage2 using a button and everything works fine and fields hold their values nicely.

So I then wanted to extend this further and change some of the Edit Boxes to Computed Fields on XPage2, so that the I can see but not edit the value. This looks ok until I try to save the XPage/data source. My problem is that when I use my save button on XPage2, the fields that I have binded to the Computed Fields are not saved on the XPage2 data source. However if I save XPage2 data source back at the copyAllItems on XPage1, the values hold. Unfortunately I don't want to save this document then in the event I cancel out from XPage2.

All data sources are notes document.

Any thoughts? I basically want the value to save while allowing the user to view it but not change it

Thanks Steven

 

Edit: I have also tried this with an Edit Box enabling Read Only and/or Show disabled controls for read-only and it gives the same result as the Computed Field control.

Nov 19, 2015, 10:34 AM
453 Posts
First....

I never use a response document, it is a ticking time bomb if you ever get a save/Rep Conflict. I just use a plain old Notes Document and store a unique value in ( use @Unique() ) both the parent and the child. There are several threads in this forum on doing that. 

Second, with out some code it is pretty hard to comment on what might be going wrong, but if I understand your issue correctly I do this all the time, then use nested repeat controls to display them. You can make Domino into a pretty relational database.

Nov 19, 2015, 3:06 PM
589 Posts
hmmm

Did you say "resonse document"?  Unless you're piggy backing on a notes client app that you want to maintain compatibility with I can't think of any reason to ever use a response document in XPages.  It's not a good practice.  I also wonder about the need to "copyAllitems"...  that sounds like a notes client thing... not something typically ever needed in XPages world since XPages is a little more "relational" then is possible in the Notes Client.

 

I agree with Bob.  You might want to rethink the response document thing or provide a little more detail and code as to what you're trying to do.

 

Dave

NotesIn9

Nov 19, 2015, 6:00 PM
8 Posts
Re: copyAllItems - value disappears on xpage save when computed field control

Thanks for the responses Bill and David, I've seen your other "do not use" response documents comments throughout the forum while I was trying to research this issue. Yes the app is hybrid - XPages for external and internal use the traditional notes elements. Unfortunately not all apps can be built from green fields so using response documents and maintaining this database's current structure is required to remain within the client's budget/time frame and their staff's current processes and familiarity.

BUT the issue is repeatable outside of the use of response documents anyway. Taking the evil 'response' wording out of this for a moment, the problem is that I have is that when a copyAllItems is used to build a new document data source for a page, when unsaved and presented into an XPage bound to a computed field control, on the data source save via a button on the xpage, it removes the entire field in the data source document.

Here is a stripped down page to demonstrate the issue. You'll need to create a form called "testform" with fields "field1" & "field2". Note that when you open the page, the computed field control binded to document1.field2 shows the value but when you click save, the value disappears - because the field doesn't exist on document1 anymore. As I mentioned in the first post, using an Edit Box with read only etc doesn't resolve the issue either.

Sample page that will cause the issue.

<?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="testform"></xp:dominoDocument>
    </xp:this.data>
    <xp:this.beforePageLoad><![CDATA[#{javascript:var getDoc = database.getDocumentByUNID("1157F42AE5A17FFA4A257F02007B769F") //Change to UNID within your database
if (getDoc){
    getDoc.copyAllItems(document1.getDocument(), false);
}
}]]></xp:this.beforePageLoad>
    <xp:inputText id="inputText1" value="#{document1.field1}"></xp:inputText>
    <xp:br></xp:br>
    <xp:br></xp:br>
    <xp:text escape="true" id="computedField1" value="#{document1.field2}"></xp:text>
    <xp:br></xp:br>
    <xp:br></xp:br>
    <xp:button value="Save" id="button1"><xp:eventHandler event="onclick" submit="true" refreshMode="complete">
    <xp:this.action>
        <xp:saveDocument var="document1"></xp:saveDocument>
    </xp:this.action></xp:eventHandler></xp:button></xp:view>

 

Workarounds:

1) Saving document1 after the copyAllItems will eliminate the issue, however this will cause rogue documents in the database if the user cancels (user doesn't have deletion access and no scheduled agents to delete these docs either please)

2) Binding an Edit Box with display:none to document1.field2 on the xpage in addition to the Computed Field binded to the same will also resolve the issue - credit to David for this (see link in first post) but the difference here is that I'm not trying to update the computed field on the fly. Unfortunately I'll have to do this about 45 times on the page (so 45 extra controls = messy). Probably the way I'll need to go though.

I'm thinking that this will fall into the "it can't be done" category, but really it's pretty basic what I'm trying to do so it's a shame that XPages does this.

Nov 19, 2015, 6:55 PM
589 Posts
hmmm

Steven,

Well first I'm sure something can be done here.  I've never seen a real XPages limitation at this level.

I'm not sure I'm totally getting the issue.  I don't really work with NotesDocuments any more so I kinda forget some of the issues.  I do think that computed fields by design don't get saved... they act as "Computer for Display" in Notes Client terminology.

You're trying to copy values FROM the getDoc TO the bound document1 right?  I suggest you give it a try not in beforePageLoad but in one of the document events..  queryOpenDocument...  see if you can set the values there...  if not then querySaveDocument might also be a help before you put 45 extra controls on the form...

This is a solvable problem I'm sure....

Give that a try...  If that doesn't work..  Create a SMALL, clean database with some data so I can reproduce the problem an I will try and take a look at it.

Dave

Nov 20, 2015, 3:15 PM
453 Posts
Think it is an issue of timing

have not had time to run a  test, but I would guess that document1 is not there until after the page loads. If my memory serves me right (great memory just not very long) I ran into something similar to this in an application I worked on but can't remember which one it was. Try moving the code to the afterPageLoads and see what happens.

Nov 22, 2015, 3:08 PM
453 Posts
Well This works

I created a simple custom control that I think pretty much duplicates your situation. For simplicity sake I am doing it a little bit differently. Some of the code might be able to be optimized a bit but..

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <xp:this.data>
        <xp:dominoDocument var="thisXSPDoc" formName="frmTestCopy">
        </xp:dominoDocument>
    </xp:this.data>
    <xp:this.beforePageLoad><![CDATA[#{javascript:var profileView:NotesView = database.getView("vwAllProfiles");
var copyDoc:NotesDocument = profileView.getFirstDocument();
if (copyDoc) {
    //got a doc to copy
    var thisDoc:NotesDocument = thisXSPDoc.getDocument();
     copyDoc.copyAllItems(thisDoc, true);
}}]]></xp:this.beforePageLoad>
    <xp:panel id="panelData">
        <xp:table>
            <xp:tr>
                <xp:td>
                    Profile Name :&#160;</xp:td>
                <xp:td>
                    <xp:inputText id="inputText1" value="#{thisXSPDoc.WFSProfileName}"></xp:inputText>
                </xp:td>
            </xp:tr>
            <xp:tr>
                <xp:td>
                    Application :</xp:td>
                <xp:td>
                    <xp:inputText id="inputText2" value="#{thisXSPDoc.WFSAppName}"></xp:inputText></xp:td>
            </xp:tr>
        </xp:table>
        </xp:panel>
</xp:view>

When I run this the fields Profile Name and Application display the correct values based on the values that are in the Profile document that is loaded into copyDoc. I did have to add the thisXSPDoc definition to the custom control rather than to panelData so that the beforeLoad sees the dataSource. So there are timing issues that need to be considered. I added the copyAllItems code in both the beforePageLoad and the afterPageLoad and they both work. I think the beforePageLoad is probably the best option as it should only fire once. The only two changes that I see is I define thisDoc = thisXSPDoc.getDocument() outside the copyAllItems and I use a true in the copyAllItems, and my fields are inputText not computed but ..... This worked on the first try so I didn't go any further.