1

I have an XPage with a fileupload control and some fields. I use serverside validation (some of the fields need lookups etc. to validate content). Now if a user specifies a file to be uploaded and one of the other fields fails to validate (showing a message to the user) then the fileupload control loses its client name (and effectively the file) - meaning that the user would have to select the file again to upload it.

Any ideas as to how to solve this? Can the uploaded temp. file be "kept in memory" in e.g. the view bean - and then "injected" back when validation doesn't fail for other fields?

This question is related to same issue as asked here: How can I "keep" the uploaded image on a form validation error? - which does not give a solution to above (although does discuss the temp. file).

Community
  • 1
  • 1
John Dalsgaard
  • 2,797
  • 1
  • 14
  • 26
  • Sven Hasselbach made a series of 2 posts regarding that problem: http://hasselba.ch/blog/?p=1019 – Oliver Busse Mar 23 '14 at 19:12
  • Oliver, just to make sure I understand your suggestion: I could use Sven's idea to disable validation of the other fields, is that right? But I still need to validate the other fields though... – John Dalsgaard Mar 23 '14 at 21:19
  • Yes, it disables the validation of other fields while using the fileupload and deletion actions. You can also try to just save the document onChange - maybe as a temporary doc (a flag field for it which is removed after a "real" save after validation. – Oliver Busse Mar 23 '14 at 21:44
  • With ND9, the IBM has changed some internal objects, this is why the trick does only work with Domino – Sven Hasselbach Mar 24 '14 at 07:20
  • I do not know XPages, but the general idea is to keep the uploaded file on the server and add a hidden field containing a pointer to the file. It could be a partial path to a temp file. This is an example in Ruby on Rails, but the same must be possible in XPages: https://github.com/carrierwaveuploader/carrierwave#making-uploads-work-across-form-redisplays – Bo Frederiksen Mar 24 '14 at 16:28
  • Bo, the file IS uploaded even before any validators run. So I cannot grap the file in memory - but I can get a hold of the temp file (in the xspupload directory of the data directory) - and then use a temp field to control if it was uploaded. I'll briefly describe the solution for others to understand... – John Dalsgaard Mar 31 '14 at 15:23

2 Answers2

0

You should change your UI and give the user a special button for uploading their files (maybe in a modal dialog). Here is a small example XPage:

<?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="RTItem" action="editDocument" concurrencyMode="force" />
    </xp:this.data>

    <xp:div id="refreshMe">
        <xp:fileUpload  id="fileUpload1" value="#{document1.Body}" />

        <xp:button value="Upload File" id="buttonUpload">
            <xp:eventHandler event="onclick" submit="true" refreshMode="complete" disableValidators="true" />
        </xp:button>

        <!-- A download control to show the datasource --> 
        <xp:fileDownload rows="30" id="fileDownload1" displayLastModified="false" value="#{document1.Body}" />

        <!-- A required field and a messages element -->
        <xp:inputText id="inputText1" required="true" />
        <xp:messages id="messages1" />

        <!-- a button to refresh the page -->
        <xp:button value="Refresh Me" id="buttonRefreshMe">
            <xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="refreshMe" />
        </xp:button>

    </xp:div>

</xp:view>

You can combine this with an AJAX file uploader progress in the background, which would give a better UX to the users.

Sven Hasselbach
  • 10,455
  • 1
  • 18
  • 26
  • Sven, I appreciate your idea. It would, however, give me a quite different approach - and way to validate the file before uploading it. Your idea is similar to the fileupload component that Mark Leusink has created - which I considered but left in this case for the same reasons. – John Dalsgaard Mar 31 '14 at 15:20
0

Ok, I just want to give a quick overview of the way I ended up solving this.

First thing to notice is that the file is uploaded before any validators are run. It is placed in a directory named xspupload in the Domino data library - and the file gets an "obscure" name with no file suffix.

However, I can grap this file (I have the file upload control mapped to an object of type com.ibm.xsp.component.UIFileuploadEx.UploadedFile in a managed bean). When a value is set for this object I can get the uploaded file by calling getUploadedFile() of the control, which will return an object of type: com.ibm.xsp.http.UploadedFile. This file object has a getClientFileName() and getServerFile() that can be used to find out what file the user uploaded and temp. rename it to another name. If you do not rename it then it will automatically be removed when the http request is done. So you have to remember to rename (or remove) the file once you are done (I found some inspiration in this: http://www.bleedyellow.com/blogs/m.leusink/entry/processing_files_uploaded_to_an_xpage?lang=en).

I then remeber the temp. filename of the file in a simple hidden input field bound to a string value in my bean. This way the page knows it has been uploaded and I can show the name to the user (by hiding the normal file upload control and provide my own icon that will show any "pending name" and "click" the native control when clicked on).

This way I can get a hold on the file and keep it - and validate it - together with the other fields. Even in a repeat control where I do it.

But, alas, no simple "out of the box" solution. You will have to code it yourself (or use a client centric approach as suggested by Sven).

Thanks for your input.

John Dalsgaard
  • 2,797
  • 1
  • 14
  • 26