Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 10 total
Thread File upload with RemObjects backend
Mon, Mar 28 2016 8:29 AMPermanent Link

Andreas Blenk

Hello,

i want to upload Files from Client side via my RemObjects SDK Backend. In order to call my RemObjects Method i need a binary stream (?) for uploading.

So how can i handle this? Does someone have a example code for me?
Or do i have to use a different way for uploading?

Can http://www.dropzonejs.com help me? I like it to drop file on the browser and upload multiple files at once.

Thanks, Andreas
Mon, Mar 28 2016 10:58 AMPermanent Link

Matthew Jones

Andy23 wrote:

> Hello,
>
> i want to upload Files from Client side via my RemObjects SDK
> Backend. In order to call my RemObjects Method i need a binary stream
> (?) for uploading.
>
> So how can i handle this? Does someone have a example code for me?
> Or do i have to use a different way for uploading?
>
> Can http://www.dropzonejs.com help me? I like it to drop file on the
> browser and upload multiple files at once.

I don't know about the dropzone thing, but EWB is basically javascript
so anything one application can do EWB can probably do, with some
tweaking. Depends on whether it will fight the EWB code or not.
However, I got file uploading working just fine by hacking the
RemObjects SDK web server code, intercepting the call where it
interprets the path and when it sees a POST to /upload/ it calls a
suitable routine which returns a GUID in the JSON response. This way
the upload code can then link the file uploaded to the current client
with a call to the server. This way was easiest for me. However, if you
want to get clever, they gave me the official answer on their forum:

https://talk.remobjects.com/t/file-upload-using-http-post/6116



--

Matthew Jones
Tue, Mar 29 2016 2:12 AMPermanent Link

Andreas Blenk

Thanks for this information!

I spent a few hours yesterday and i am thinking i can handle it with Javascript and ROSDK "Standard". But don't know it yet. If i have a working solution i will post it here.

I would prefer to just call my ROSDK Methods in the standard way.

btw: It would be helpful if TFileComboBox would able to select multiple files? Is there a way to do so?

Another question about TFileComboBox:
Is it possible to get the "native File Object" From TFileComboBox?
This one: https://developer.mozilla.org/en-US/docs/Web/API/File

Thanks, Andreas



"Matthew Jones" wrote:

Andy23 wrote:

> Hello,
>
> i want to upload Files from Client side via my RemObjects SDK
> Backend. In order to call my RemObjects Method i need a binary stream
> (?) for uploading.
>
> So how can i handle this? Does someone have a example code for me?
> Or do i have to use a different way for uploading?
>
> Can http://www.dropzonejs.com help me? I like it to drop file on the
> browser and upload multiple files at once.

I don't know about the dropzone thing, but EWB is basically javascript
so anything one application can do EWB can probably do, with some
tweaking. Depends on whether it will fight the EWB code or not.
However, I got file uploading working just fine by hacking the
RemObjects SDK web server code, intercepting the call where it
interprets the path and when it sees a POST to /upload/ it calls a
suitable routine which returns a GUID in the JSON response. This way
the upload code can then link the file uploaded to the current client
with a call to the server. This way was easiest for me. However, if you
want to get clever, they gave me the official answer on their forum:

https://talk.remobjects.com/t/file-upload-using-http-post/6116



--

Matthew Jones
Tue, Mar 29 2016 4:16 AMPermanent Link

Andreas Blenk

Ok, i think i have found a working solution for me.

Generally:
I wanted to have a Panel to Drag&Drop Files on to and transfer it to my server or display them in a TImage.

Attention: I am absolutely new to JavaScript. I am not sure if this is nice JavaScript code. Smile

What i am sill missing: I want to have a TFileComboBox like control to manually select multiple files for uploading. Currently i only have the Drag&Drop way...


//==============
// JavaScript
//==============

function ArrayBufferToBase64(buffer) {
   var binary = '';
   var bytes = new Uint8Array( buffer );
   var len = bytes.byteLength;
   for (var i = 0; i < len; i++) {
       binary += String.fromCharCode( bytes[ i ] );
   }
   return window.btoa( binary );
}

function UploadDropZone(__DropZoneName, __OnFileLoadedCallback) {
   
   //signature: procedure(AFileName: String; const AFileSize: Integer; ALastModifiedDate: DateTime; AFileDataBase64: String) of object;
   var OnFileLoaded = __OnFileLoadedCallback;

   this.handleFileSelect = function(evt) {
      evt.stopPropagation();
      evt.preventDefault();

      var files = evt.dataTransfer.files; // get the FileList object.

      for (var i = 0, f; f = files[i]; i++) {
         
         var reader = new FileReader();

         reader.onload = (function(theFile) {
         return function(e) {
            OnFileLoaded(theFile.name,theFile.size,theFile.lastModifiedDate,ArrayBufferToBase64(e.target.result));
         };
         })(f);

         reader.readAsArrayBuffer(f);
      }
   }

   this.handleDragOver = function(evt) {
      evt.stopPropagation();
      evt.preventDefault();
      evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
   }   

   var dropZone = document.getElementById(__DropZoneName);
   dropZone.addEventListener('dragover', this.handleDragOver, false);
   dropZone.addEventListener('drop', this.handleFileSelect, false);   
}



//==============
// EWB Code
//==============

type
  external TOnFileLoaded = procedure(AFileName: String; const AFileSize: Integer; ALastModifiedDate: DateTime; AFileDataBase64: String) of object;

  external TUploadDropZone emit 'UploadDropZone' = class
  public
     constructor Create(const ADropZoneName: String; const AOnFileLoadedCallback: TOnFileLoaded);
  end;

...

procedure TFrmMain.FrmMainCreate(Sender: TObject);
begin                                                                 
  pnlDropZone.ClientID := 'MyDropZone'; // pnlDropZone == TBasicPanel
  FDropZone := TUploadDropZone.Create(pnlDropZone.ClientID,OnFileLoaded);
end;

procedure TFrmMain.OnFileLoaded(AFileName: String; const AFileSize: Integer; ALastModifiedDate: DateTime; AFileDataBase64: String);
begin                                                    
  //Images can be placed in a TImage...
  imgBild.URL := 'data:image;base64,' + AFileDataBase64;

  //.... or do whatever you want with this Base64-String... (e.g. send it to Server).

  ShowMessage('Data received!');
end;
Tue, Mar 29 2016 4:17 AMPermanent Link

Andreas Blenk

@Matthew: What do you think about this solution? I know you also using EWB with ROSDK.
Tue, Mar 29 2016 5:02 AMPermanent Link

Matthew Jones

Andy23 wrote:

> @Matthew: What do you think about this solution? I know you also
> using EWB with ROSDK.

It looks very clever! I suspect there are bits missing - the emit
indicates that - but if it is all working please zip a demo for all to
consume... I don't need it right now, but I may well do in the coming
months.

--

Matthew Jones
Tue, Mar 29 2016 5:12 AMPermanent Link

Andreas Blenk

Thanks for your reply. What do you mean with "... bits missing..."? Do i am using the "emit" the wrong way?

Do you have any idea how i can place a button which triggers the file open dialog? I could use the TFileComboBox but i want to get the JavaScript "File" Object and don't know how. Also multi-select in the file open Dialog would be great (= results in JavaScript "FileList" object).

The goal is to get the JavaScript "File" objects in order to use my functions to get the Base64-String.

File: https://developer.mozilla.org/en-US/docs/Web/API/File
FileList: https://developer.mozilla.org/en-US/docs/Web/API/FileList

I am going to make a zip-file of my example as soon as i am finished it.



"Matthew Jones" wrote:

Andy23 wrote:

> @Matthew: What do you think about this solution? I know you also
> using EWB with ROSDK.

It looks very clever! I suspect there are bits missing - the emit
indicates that - but if it is all working please zip a demo for all to
consume... I don't need it right now, but I may well do in the coming
months.

--

Matthew Jones
--

Andreas Blenk
Tue, Mar 29 2016 5:36 AMPermanent Link

Matthew Jones

Andy23 wrote:

> What do you mean with "... bits missing..."? Do i am using the "emit"
> the wrong way?

No, just that I'm not sure what is being emitted, it being a chunk out
of an incomplete file. I'm sure you kknow this stuff better than I
though - I tend to dig, learn, make it work, and forget. 8-)


> Do you have any idea how i can place a button which triggers the file
> open dialog?

I think Tim has said that the multi-file selector is not available as
it is not supported by the lowest-common-denominator browser supported.
That doesn't stop you digging in and changing the source to make it
work, but you would have to re-apply the change for any updates (you
can put them into a custom updates path, and that works nicely). So,
find out how to do it in Javascript, then dig into the code to find
where EWB does it, and apply adjustments.


--

Matthew Jones
Tue, Mar 29 2016 5:00 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Andy,

<< Thanks for your reply. What do you mean with "... bits missing..."? Do i am using the "emit" the wrong way? >>

Yes.  If you create the class the way that you're doing so, you'll end up with something different than you think because your class declaration doesn't accurately represent what's in the JS.

For what you've got in the JS code, you should just use this:

external procedure UploadDropZone(const ADropZoneName: String; const AOnFileLoadedCallback: TOnFileLoaded);

procedure TFrmMain.FrmMainCreate(Sender: TObject);
begin                                                                 
 pnlDropZone.ClientID := 'MyDropZone'; // pnlDropZone == TBasicPanel
 UploadDropZone(pnlDropZone.ClientID,OnFileLoaded);
end;

<< Do you have any idea how i can place a button which triggers the file open dialog? I could use the TFileComboBox but i want to get the JavaScript "File" Object and don't know how. Also multi-select in the file open Dialog would be great (= results in JavaScript "FileList" object).

The goal is to get the JavaScript "File" objects in order to use my functions to get the Base64-String. >>

The problem with this is that it isn't supported in IE9, which is why EWB doesn't support it right now.  We'll be incrementing the supported IE version to 11 later on this year.

http://caniuse.com/#feat=fileapi

Tim Young
Elevate Software
www.elevatesoft.com
Wed, Mar 30 2016 1:52 PMPermanent Link

Andreas Blenk

No i have solved all my wishes. Wink

I am now able to drag&drop and select files by clicking!

You can find the example project there:

http://www.elevatesoft.com/forums?action=view&category=ewb&id=ewb_demos&page=1&msg=210#210
--

Andreas Blenk
Image