1 2 3 4 Previous Next 56 Replies Latest reply on Sep 19, 2013 9:57 AM by haseeb

    workaround for multipleUpload capability in <rich:fileUpload>

    simone.83

      Hi folks,

      i'm working to migration project of a web application from Richfaces 3.xx to Richfaces 4.x (4.3.1.Final)

      and I need the multiple upload feature that it is not supported in RichFaces 4.3.1.Final as I can see in rf4 documentation.

       

      So, I've found a way to enable the browser component multiple upload functionality directly from javascript (in bold, blue text color). Here is the code...

       

      <rich:fileUpload id="upload" render="info" listHeight="150px"

      acceptedTypes="DOC, DOCX, PDF, XLS, XLSX, PPT, PPTX, WPD, RTF, TXT, VSD, MPP, MPPX, DWF, SWF, FLV , ODT, ODS, ODP, ODG, ODF, SXW, SXI, SXC, SXD, JPEG, JPG, JPEG2000, GIF, BMP, TIFF, TIF, PNG"


      fileUploadListener="#{trasformBean.listener}"

      ontyperejected="alert('file format is not supported')"

      onclick="document.getElementsByClassName('rf-fu-inp')[0].setAttribute('multiple','multiple');"

      immediateUpload="#{trasformBean.autoUpload}"

      maxFilesQuantity="#{trasformBean.uploadsAvailable}">

       

      <a4j:ajax event="clear"actionListener="#{trasformBean.cleanListener}" />

       

      </rich:fileUpload>

       

      That works, 'cause the html returned by the RichFaces FileUpload UI component contains the element: <input type="file" class="rf-fu-inp">

      and with js .setAttribute('multiple','multiple')  i'm going to set a new attribute multiple="multiple"" that does the trick!!!

       

      But this only solves the problem by browser's side:

      in fact, when I select more than one file (A.txt, B.txt, and C.txt for instance), the value of inputText component inside the file upload  component

      contains a string like: "A.txt" "B.txt" "C.txt" ... and that's ok, but seems only one file is loaded on the server side fileUploadListener="#{trasformBean.listener}".

       

      How can I fix this problem?

       

       

      Community:: RichFaces, I need your help, please!

       

       

      Regards,

      Simone

        • 1. Re: workaround for multipleUpload capability in <rich:fileUpload>
          agallo73

          I saw several discussions related to the fileupload in richfaces 4 and I have to say that it's very complicated, when migrating from a previous version providing many functionalities, to make user experiment regression in usability and possible actions to be performed.

           

          Coming back to the fileupload, my users are used to upload multiple files. How can now I tell them to do it one by one?

           

          It's a great regression for them and I have to provide a solution.

           

          I also tried to  integrate PrimeFaces fileupload with very bad results as far as layout is concerned.

           

          Is it possible that there's no way to have an immediate upload and multiple file upload as it happende before?

           

           

          Is there some work in progress within the community?

           

          Can someone help me?

           

          We can not deliver with rediuced functionalities.

           

          Thanks in advance.

           

          Antonio.

          • 2. Re: workaround for multipleUpload capability in <rich:fileUpload>
            simone.83

            Yes, antonio, i don't understand why they have not implemented the multi-upload functionality on the new 4.x release of RichFaces.

            The only way seems to use javascript calling directly the RichFaces.ui.FileUpload upload method how many times that are files uploaded, but this is not the right way to solve this problem.

            Can anyone help me with multi-upload ?

            • 3. Re: workaround for multipleUpload capability in <rich:fileUpload>
              agallo73

              Excuse me but where's the community? Can we please know if there's some solution or something in progress? We already spent a lot of time migrating from 3.3 to 4 because someone decided to change names and implementations without providing any backward compatibility. I think that it's important to provide the customer with already know functions. How can we tell our users that the multiple upload does not work any more? Why immediate upload has been dismissed? Is it possible that noone cares of it? 

              • 4. Re: workaround for multipleUpload capability in <rich:fileUpload>
                simone.83

                Hello,

                anyone can help me with this problem? It is possible to extend this multi upload functionality to Rich Faces 4.x components? Otherwise, does the next RichFaces 5 release the UI <rich:fileUpload> component support the multiple upload ? I like RF so much and we don't want to rollback and implement the application with Prime Faces (that is, it's the only one actually supports the multi-upload in the <input type="file"...> wrapping UI component).

                 

                Thanks for support.

                 

                Simone

                • 5. Re: workaround for multipleUpload capability in <rich:fileUpload>
                  agallo73

                  I have the same problem and it's really important for me to have this functionality. Rich faces team, are you alive? May some of you plese reply to Simone and me? How can tell users to upload several files one each time?  Is it possible to have feedback ? Have we to solve all problems by our selves rewriting the whole?

                  • 6. Re: workaround for multipleUpload capability in <rich:fileUpload>
                    simone.83

                    Hello, world  !

                     

                    I've found the solution (zip file in attachments) to the multi-upload problem for FileUpload component in RichFaces 4.x. This workaround consist in re-define an our custom renderer in your "WEB-INF/faces-config.xml", and then going to change the default behaviour in the original org.richfaces.renderkit.RendererBase class. Follow these two simple steps and you can add multi-upload support to the richfaces FileUpload component.

                     

                     

                     

                    [1] Edit "WEB-INF/faces-config.xml" adding the following rows

                     

                     

                        <render-kit>

                             <renderer>

                              <component-family>org.richfaces.FileUpload</component-family>

                              <renderer-type>org.richfaces.FileUploadRenderer</renderer-type>

                              <renderer-class>my.pkg.name.MyFileUploadRenderer</renderer-class>

                             </renderer>

                        </render-kit>

                     

                     

                    [2] Create two classes: "my.pkg.name.MyFileUploadRenderer extends MyFileUploadRendererBase" and "my.pkg.name.MyFileUploadRendererBase extends FileUploadRendererBase"

                         where my.pkg.name is the name of package where we are going to add these two classes.

                     

                        The first class can be the exact copy (except following rows) of org.richfaces.renderkit.html.FileUploadRenderer class,  you can find that in the RichFaces sources (try with the sources on-line archive at www.grepcode.com).  In this class you should modify the FileUploadRenderer.doEncodeEnd(....) method, after these lines :

                         .....

                        responseWriter.startElement("input", component); 

                        responseWriter.writeAttribute("class","rf-fu-inp",null);

                        responseWriter.writeAttribute("type","file",null);

                             .....

                     

                         adding the following row:

                     

                         responseWriter.writeAttribute("multiple", "multiple", null); //enables HTML5 multiple upload feature

                     

                     

                        The last class contains only one method. You can pick up the source code from here: org.richaces.renderkit.FileUploadRendererBase

                        The changes you need to made consists only in   remove/comment the break instruction in the if block inside the for loop.

                        The code is there:

                     

                        package my.pkg.name; //change with your own package!

                     

                        import javax.faces.component.UIComponent;

                        import javax.faces.context.ExternalContext;

                        import javax.faces.context.FacesContext;

                     

                        import org.richfaces.event.FileUploadEvent;

                        import org.richfaces.model.UploadedFile;

                        import org.richfaces.renderkit.RendererBase;

                        import org.richfaces.request.MultipartRequest;

                     

                        /**

                         * @author Konstantin Mishin

                         * @author Nick Belaevski

                         * @modified by Simone Cinti

                         */      

                     

                        public class MyFileUploadRendererBase extends RendererBase {

                     

                        protected void doDecode(FacesContext context, UIComponent component) {

                            ExternalContext externalContext = context.getExternalContext();

                            MultipartRequest multipartRequest = (MultipartRequest) externalContext.getRequestMap().get(

                                MultipartRequest.REQUEST_ATTRIBUTE_NAME);

                            if (multipartRequest != null) {

                                String clientId = component.getClientId(context);

                     

                                for (UploadedFile file : multipartRequest.getUploadedFiles()) {

                                    if (clientId.equals(file.getParameterName())) {

                                        component.queueEvent(new FileUploadEvent(component, file));

                                        //    break;

                                    }

                                }

                            }

                        }

                        }

                     

                    *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

                    with this workaround all works by backing-bean side.

                    The only issue now is that the component lists only one file in list, but it really does upload all the files

                    that you've selected, calling the bean listener...

                     

                     

                         <rich:fileUpload

                                                id="upload"

                                    ....

                                              fileUploadListener="#{fileUploadBean.listener}">

                     

                            ....

                         </rich:fileUpload>

                     

                     

                     

                    here's a bean listener example:

                     

                    @ManagedBean

                    @SessionScoped

                    public class FileUploadBean implements Serializable {

                        private List<File> files = new ArrayList<File>();

                     

                        public void listener(FileUploadEvent event) throws Exception {

                              System.out.println("Sono il listener invocato dall'event FileUploadEvent - UploadedFile.getName()= "+ event.getUploadedFile().getName());

                     

                            UploadedFile item = event.getUploadedFile();

                            File file = new File(item.getName());

                     

                            files.add(file);

                        }

                        public List<File> getFiles() {

                           return this.files;

                        }

                        public void setFiles(List<File> files) {

                           this.files=files;

                        }

                    }

                     

                     

                     

                    If you want to hack the uploaded files list visualization and view all uploaded files correctly, a way is to use javascript.

                    Browse inside "resources/js/updateFUList.js" file in RF4MultipleUpload_Simone.zip attachment. For more informations about implementation please send

                    me a pvt message...

                     

                    goodbye!

                    Simone.

                    • 7. Re: workaround for multipleUpload capability in <rich:fileUpload>
                      agallo73

                      Great Simon, you really did a great work.

                       

                      I think that it would be nice if the rich team would give an advice as far as this solution, suggesting possible limitations or improvements,  and it would even be better if they might include these changes in an official release in order to have a stable code for all and thus avoid having to adjust the jar each time a new version is released.

                       

                      May the richfaces' team please reply to this post?

                       

                      I think that the community would promote and increase such collaborations.

                       

                      Please make alive....

                      • 8. Re: workaround for multipleUpload capability in <rich:fileUpload>
                        lfryc

                        Hey Simone, great job with investigations!

                         

                        Would you mind to contribute these changes to the RF4 codebase?

                        No changes in JavaScript scripts were needed?

                         

                        https://github.com/richfaces4/components/blob/master/input/ui/src/main/templates/fileupload.template.xml#L51

                        https://github.com/richfaces4/components/blob/master/input/ui/src/main/java/org/richfaces/renderkit/FileUploadRendererBase.java#L48

                         

                         

                        Have you done any testing of cross-browser support of this feature?

                         

                        I guess older browsers (which doesn't support attribute "multiple") will just allow you to select one file, right?

                        Seems all the current mainstram browsers works: http://www.wufoo.com/html5/attributes/08-multiple.html

                         

                        Anyway awesome job, that is exactly the kind of collaboration which helps the project grow!

                        • 9. Re: workaround for multipleUpload capability in <rich:fileUpload>
                          simone.83

                          Thanks, Lukáš 

                          I'm very happy to have found a solution for this problem. The code in zip archive in attachments contains some javascript code...now i'm working to a best jquery-based .js file

                          for best support in Firefox and IE, and hopefully other main browsers...(i'm not very good in jquery...so my firends helps me to find a right and clean solution for the jquery code in .js).

                           

                          Yes, older browsers (like IE7) will allow you to select only one file, but this works fine by the managed bean side.

                          The only opened issue now is about the items loaded in the recently uploaded history and i'm working on a client-side javascript/jquery code for the correct visualization inside the list (the html element with class="rf-fu-lst").

                           

                          As you can see, the problem here was only a "break" instruction inside the for loop...i'm sure this "break" instruction is an intentionally choice of the two authors Konstantin Mishin

                          and Nick Belaevski of the class org.richfaces.renderkit.FileUploadRendererBase, perhaps because not all browsers supports the "multiple" attribute inside the html <input type="file"> element.

                          So I think this is not we can call a "bug" but i've only found a way to resolve a problem, changing some lines inside the source code...I'm not sure the RichFaces development team and the authors will appreciate the work I have  done (because they intentionally wrote the "break" instruction on that code). If they do, i'm proud the be part of this community as far as I can do.

                           

                          Can anyone help me writing a decent and clean javascript code ? I've post in attachments the last development state of updateFUList.js code if someone wants to work with.

                           

                          (Thanks to our development team members: Enrico Colatosti and Daniele Favini for suggestions and [javascript -> javascript with jquery] migration process).

                           

                          Answer to your question: Would you mind to contribute these changes to the RF4 codebase? 

                           

                          >>> "I'm proud  and happy to contribute these changes to the RF4 codebase (the src are inside the archive .zip in attachment) but I'm not sure at 100%, as I wrote in last three rows up, that

                                 the RichFaces Development Team agrees because they intentionally decided the only-one-file-at-a-time implementation in RichFaces 4.x releases.

                           

                           

                          Regards,

                          Simone

                          • 10. Re: workaround for multipleUpload capability in <rich:fileUpload>
                            lfryc

                            Hey Simone,

                             

                            I can't speak for intentions of original authors of this code, but for myself -> we want to fix the code here, so let's change it and make sure it doesn't break anything. ;-)

                             

                            You are right that changing removing the break doesn't have to be completely correct - I'm not sure whether the FileUpload should be fired just once (including several files) or multiple times (for each file separately).

                             

                            I also think that the JavaScript code you put together with colleagues is not heading in a right direction:

                            I guess they actually should rather change original fileupload.js: https://github.com/richfaces/richfaces/blob/master/framework/src/main/resources/META-INF/resources/org.richfaces/input/fileUpload/fileupload.js

                            As you can see, when input changes, an __addItem method is fired - which is exactly where we need to investigate.

                            • 11. Re: workaround for multipleUpload capability in <rich:fileUpload>
                              simone.83

                              Yes Lukáš. I've browsed so many times inside fileupload.js but for other external reasons than the community ethic (which is an important thing too, please do not misunderstand what i've trying to explain with my poor english) we've planned to work in an other .js file and make the things works asap (and unfortunately its is a synonymous of as poorly as we can).

                              Now I've all the time to spend for work in a best solution for the community and integration with the richfaces sources, i'm very happy and proud to do that--and I promise you I will do soon!.

                               

                              For the "break" question, I think the removing of this instruction it's logically correct and works perfectly at server side. In fact, if you look at code inside FileUploadRendererBase class you can see a for loop that iterates for each UploadedFile object obtained from the Multipart Request parsing.  The "break" I think was inserted intentionally with the intent of limit the functionality of multiple upload in one upload-at-a-time, coherently with the implementation of the renderer for html component. So to provide a complete support of multiple upload we have to work only by html/javascript side (as you have rightly mentioned before : fileupload.js is where component logic is implemented, I agree!).

                               

                              At the bean side, when the upload event is fired from the html component, a new FileUploadEvent is fired for each uploaded file, so the listener registered within the <rich:fileUpload> "fileUploadListener" attribute, is awaked so much times than the number of files uploaded. Inside the listener code we can create a new java.io.File from the UploadedFile object returned by the getUploadedFile() event method, and then we can do a "list.add()" operation on a  "List<File> list" class-object initialized from the constructor at bean creation.

                               

                              So that's ok...we have to work only inside the code of fileupload.js and all will work perfectly, in particular (as you can see in my .js file, that surely wins the "worst-code-ever-wrote" millennium prize) all we need to do is to manage correctly the upload history list, inserting ALL the uploaded files (not only one of them), and as you suggest inside the __addItem function.

                              If you look inside the __addItem function you can see this row:

                               

                              __addItem: function() {

                                              var fileName = this.input.val();

                              the val() in jquery means the input.value if I'm not going wrong. That it's right for the single-upload implementation but in the <input type="file"> with multiple attribute we have to manage the HTML5 "files" property that it is an array of file objects. I'll try to wrote the patch tomorrow ok? I need your help with github I think...but now I'm going to sleep 'cause in Italy the midnight is over , and my brain too...

                               

                              Thanks for your help!

                               

                               

                               

                               

                               

                               

                               

                               

                               

                               

                               

                               

                              • 12. Re: workaround for multipleUpload capability in <rich:fileUpload>
                                lfryc

                                Hehe, definitely!

                                 

                                +1 I agree, the client-side code is the done which needs to be changed + it doesn't have to be complex at all, just as you said: you need to iterate through the files and call an appropriate methods to populate model and create UIs.

                                 

                                If you need an immediate help, you can always seek us at #richfaces @ irc.freenode.net.

                                Ah, and you don't need to care about GitHub at this point. ;-)

                                 

                                P.S: we can share the code changes using e.g. gists and discuss them there: https://gist.github.com/lfryc/5727956

                                After logging into github, you can edit the source right there. :-)

                                • 13. Re: workaround for multipleUpload capability in <rich:fileUpload>
                                  simone.83

                                  >>>>P.S: we can share the code changes using e.g. gists and discuss them there: https://gist.github.com/lfryc/5727956

                                  >>>>After logging into github, you can edit the source right there. :-)

                                   

                                  All done Lukáš

                                   

                                  1) forked the gist with my version of fileupoad.js that enables the support of multiple upload here:   https://gist.github.com/simone83/5728231/revisions

                                  the .js contains a comment, I don't know if this can be a problem or not, so please tell me and I will fix asap...

                                   

                                  2) updated the fileupload.template.xml with the <input type="file" .... multiple="multiple"> tag , here:https://github.com/richfaces4/components/pull/75http://

                                   

                                  3) updated the FileUploadRendererBase.java, I've just commented the break instruction. I'm not sure if you agree with the comment, if not please tell me

                                     (for respect I've not added my name in the @author tag because I'm not the author but only a modifier....that's right? or wrong??) , here: https://github.com/richfaces4/components/pull/76

                                   

                                  4)...I need the github link for the org.richfaces.renderkit.html.FileUploadRenderer.java, because I need to modify the method doEncodeEnd()

                                       adding this row

                                   


                                  responseWriter.writeAttribute("multiple","multiple",null);

                                   

                                       can you discover this file and send me the link please, meanwhile I try to discover it inside the git sources??

                                   

                                   

                                  Thanks,

                                  Simone

                                  • 14. Re: workaround for multipleUpload capability in <rich:fileUpload>
                                    lfryc

                                    Awesome, Simone!

                                     

                                    1) Great job, seems quite clean (just formatting doesn't apply as you can see from a diff - seems original file use spaces and you used tabs)

                                     

                                    2, 3) perfect, you could use just one pull request, but I guess you used GitHub's edit mode, which doesn't allow modifications in multiple files at once :-)

                                     

                                    4) this file will be actually generated from what you have already patched: https://github.com/richfaces4/components/pull/75/files

                                     

                                     

                                    Otherwise looks fairly good, you are awesome!

                                     

                                    About the author comments - basically you can act here how you find appropriate :-) - you are working on a new feature for FileUpload component so you deserve to be mentioned there if you want!

                                    Just please do not do that in inline comments - file headers are better approach.

                                     

                                    I will also need you to sign Contributor License Agreement so we could merge it into master.

                                    The detailed instructions for whole process is here, but you are interested now just in Submitting Changes part:

                                    https://github.com/richfaces/richfaces/blob/master/CONTRIBUTING.md

                                     

                                     

                                    Thanks for whole community,

                                     

                                    ~ Lukas

                                    1 2 3 4 Previous Next