11 Replies Latest reply: Sep 27, 2013 1:40 AM by scott.wesley RSS

    Send BLOB from browser to APEX using AJAX

    scott.wesley

      Hi,

       

      I'm trying to upload multiple files using drag/drop. I think I have most of the infrastructure prepared, but I'm falling over at a certain point.

       

      I'm using the following jQuery library for the file upload

      https://github.com/blueimp/jQuery-File-Upload/wiki

       

      And I'm hijacking the submit callback to call some APEX related stuff, using the concept Martin Giffy D'Souza describes here.

      Martin Giffy D'Souza on Oracle APEX: How to Send/Upload a CLOB from the Browser to APEX via AJAX

       

      The part I'm strugging with is identifying the file data component from the blueimp library.

      I've got the file name, file type, but the data either fails with

      Object #<File> has no method 'substr'

      or loads junk into the collection (before and after base64 conversion) - regardless of file type.

       

      My callback is

      submit: function (e, data) {loadFile(data); return false;}
      

       

      function loadFile(data){
      $.each(data.files, function (index, file) {
      // ...
      // htmldb_Get etc .
      // ...
      clobObj._set(file); // or variation, eg: clobObj._set(data) when not using $.each
      

       

      Note the collection populates successfully if I just hardcode some text in the clobObj call.

       

      I'd be happy with a reference to a working model sending BLOB to collection, without the blueimp library overhead.

       

      Cheers.

       

      Scott.

        • 2. Re: Send BLOB from browser to APEX using AJAX
          scott.wesley

          That's a superb link, describing a combination of a brilliant plugin with some clever javascript.

           

          However I could only recreate that example to work with .csv, not .xlsx or any other binary file.

          I tried adopting some of the code to fit with the multi-file jquery I was using, but it either just downloaded the file again after I dragged, or give other errors stating method not relevant for variable.

           

          I also found this example from Trent

          http://apextips.blogspot.com.au/2011/03/ajax-file-upload.html

          but his demo is not working and I couldn't adopt his javascript either.

           

          I still think I'm close with this call, but I can't work out how to refer to the relevant part of the object

          clobObj._set(file)

           

          // data object
          Object {files: Array[1], originalFiles: Array[1], paramName: "files[]", _response: Object, _progress: Object…}
          _progress: Object
          _response: Object
          abort: function () {
          files: Array[1]
          originalFiles: Array[1]
          paramName: "files[]"
          process: function (resolveFunc, rejectFunc) {
          progress: function () {
          response: function () {
          state: function () {
          submit: function () {
          __proto__: Object
          
          // file object
          File {webkitRelativePath: "", lastModifiedDate: Fri Sep 13 2013 10:33:54 GMT+0800 (W. Australia Standard Time), name: "rollup.png", type: "image/png", size: 12811…}
          lastModifiedDate: Fri Sep 13 2013 10:33:54 GMT+0800 (W. Australia Standard Time)
          name: "rollup.png"
          relativePath: ""
          size: 12811
          type: "image/png"
          webkitRelativePath: ""
          __proto__: File
          

           

          Scott

          • 3. Re: Send BLOB from browser to APEX using AJAX
            ascheffer

            The example I mentioned fails for xlsx and other binary files because he used dbms_lob.substr(col.clob001,dbms_lob.getlength(col.clob001),14) to decode the dataurl.

            But, depending on your browser and file type, the dataurl will have different "headers"

            data:;base64,UEsDBBQAAAA

            data:application/octet-stream;base64,c2VsZWN

            data:text/plain;base64,Q1JFQVRF

            data:text/xml;base64,PFFDVE9fR

            • 4. Re: Send BLOB from browser to APEX using AJAX
              scott.wesley

              I noticed that - Edwin has since published my comment stating I used this instead:

               

              dbms_lob.substr(col.clob001,dbms_lob.getlength(col.clob001),dbms_lob.instr(col.clob001,’,',1,1)+1)
              

              which returns anything after the comma.

               

              That's why I'm sure I'm close / getting the right content, but something's not quite right.

               

              I'm working towards a sample app that shows my various attempts.

              • 5. Re: Send BLOB from browser to APEX using AJAX
                jrimblas

                I'm just following along for the ride. 

                I haven't put a lot of effort into understanding the blueimp plugin, but I was just wondering, is it doing a base64 encoding of your content?

                 

                Thanks

                -Jorge

                • 6. Re: Send BLOB from browser to APEX using AJAX
                  scott.wesley

                  I'm not sure that it is, something I'll look into when I get a chance to get back onto this particular problem - it makes sense.

                   

                  Thanks.

                  • 7. Re: Send BLOB from browser to APEX using AJAX
                    TexasApexDeveloper

                    Scott,

                      Didn't know if you had seen this plugin: - Item Plugin - Multiple File Upload

                     

                    It is NOT free but the license is not too bad..

                     

                    Thank you,

                     

                    Tony Miller

                    LuvMuffin Software

                    • 8. Re: Send BLOB from browser to APEX using AJAX
                      scott.wesley

                      I've defined application 74054 on apex.oracle.com

                       

                      Workspace : SWESLEY

                      User : OTN

                      Pwd : apex

                       

                      There are 5 tabs showing different solutions I've explored - I'd love the "blueimp" one to work (p5).

                      The excel2collection example is close - it appears to work (sometimes) for smaller images.

                       

                      I'm sure I'm close, I did see differences in behaviour when encoding base64 on the way to the collection, but I still can't quite get it. I think my javascript is letting me down (found on each page's attributes)

                       

                      I've been using Chrome to test.

                       

                      ps - Tony, I've seen Matt's plug-in, but at this point we're hoping to succeed ourselves.

                      • 10. Re: Send BLOB from browser to APEX using AJAX
                        scott.wesley

                        Hi Jari,

                         

                        I found a similar post using APEX listener here, but we're not using the listener (at the moment)

                        Monkey on Oracle: Multiple File Upload with jQuery and APEX Listener

                        I referred to Trent's link earlier - but the add_file function doesn't get called.

                         

                        I have now succeeded with loading a file - Edwin (link from Anton's initial response) noted a file size constraint with dbms_lob.substr, so I've modified the application process accordingly.

                         

                        However if I attempt to transform the solution to process multiple files, it loads the same blob content for each record inserted.

                         

                        My handle files function now looks like

                        function handleFiles(files) {
                        
                          $.each(files, function (index, file) {
                        
                            $("#droplabel").html("Processing " + file.name);
                            var filename = file.name;
                            var filetype = file.type;
                            var filesize = file.size;
                            console.log('file:'+filename);
                        
                            var reader = new FileReader();
                            reader.readAsDataURL(file);
                            reader.onloadend = function(evt) {
                                  var clobObj = new apex.ajax.clob( function(p){
                                    if (p.readyState == 4){
                                      var get = new htmldb_Get(null,$v('pFlowId'),'APPLICATION_PROCESS=SWMULTI',$v('pFlowStepId'));
                                       console.log('load:'+filename); // last to be logged
                                       get.addParam('x01',filename);
                                       get.addParam('x02',filetype);
                                       get.addParam('x03',filesize);
                                      gReturn = get.get();
                                    }
                                  });
                        console.log(evt.target.result); // this called twice before get()
                                  clobObj._set(evt.target.result);
                        
                              }; // cb event
                        
                          }); // each file
                        } // handle files
                        
                        

                         

                        but the console log reports in this order:

                        file:phantom_dblclick.png
                        file:sphere_area.png
                        data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAf4AAAHSCAIAAACCYz4/A...
                        data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAhgAAAJpCAIAAABgmNwjA...
                        load:phantom_dblclick.png
                        load:sphere_area.png
                        
                        

                        Correlation or causation?

                         

                        I get 2 records with the correct filename/type/size, but the blob content is the same.

                        • 11. Re: Send BLOB from browser to APEX using AJAX
                          scott.wesley

                          I suspected Trent's plug-in addressed this problem - I fitted his code into what I had and the problem is now solved.

                           

                          I'm still not sure why his plug-in did not work, but as raw code on the page - mine now accepts & loads multiple files in a drop zone - and loads the correct blob content.

                           

                          Happy friday!

                           

                          Now to clean & dress it...