How to use WebOpenDialog

I am confused. The following is from the Web Core documentation:

The TWebOpenDialog non-visual component allows to start a dialog to pick files from the local file system.

I want to do exactly that. Do you mean that I cannot do that? I cannot even get the file name. Is there any example with WebOpenDialog?

The "Upload" example is using a WebFilepicker. Not exactly the workflow I am looking for.

Can I put an ElectronOpenDialog and use it on Web application project? I get the following error If I do run the application:

Uncaught TypeError: Cannot read property 'ipcRenderer' of null | TypeError: Cannot read property 'ipcRenderer' of null at Object.InitPaths (http://localhost:8000/Tina_FNC/Tina_FNC.js:142121:35) at Object.ElectronPath (http://localhost:8000/Tina_FNC/Tina_FNC.js:142626:19) at Object.$mod.$init (http://localhost:8000/Tina_FNC/Tina_FNC.js:142689:10) at loadimpl (http://localhost:8000/Tina_FNC/Tina_FNC.js:213:46) at Object.loaduseslist (http://localhost:8000/Tina_FNC/Tina_FNC.js:189:7) at loadimpl (http://localhost:8000/Tina_FNC/Tina_FNC.js:201:9) at Object.loaduseslist (http://localhost:8000/Tina_FNC/Tina_FNC.js:189:7) at loadimpl (http://localhost:8000/Tina_FNC/Tina_FNC.js:201:9) at Object.loaduseslist (http://localhost:8000/Tina_FNC/Tina_FNC.js:189:7) at Object.loadimpl (http://localhost:8000/Tina_FNC/Tina_FNC.js:201:9)
at http://localhost:8000/Tina_FNC/Tina_FNC.js [142121:35]


Sorry for causing confusion. That was not my intent.

First, no, you cannot use Electron components in a ‘normal’ web application. Electron applications are special.

The file picker also allows you to select files and get the list of files the user selected. There is no need for an upload.

However, I will look at TWebOpenDialog asap and will give you an answer asap. I apologize, but TMS WEB Core is offering so much that I mixed things up. My mistake, I will look into it.

Place a TWebButton and TWebOpenDialog on the form. Also, drop a TWebMemo.


The call to Execute is non-blocking. That means, the event OnChange has to be used to determine when the dialog has been closed and files have been selected. If the user clicks cancel, no files are added to the Files property of the dialog and the event is not triggered.

Here's a possible implementation to list all selected files in the memo control.

procedure TForm1.DialogChange(Sender: TObject);
 i : Integer;

  for i := 0 to  Dialog.Files.Count - 1 do
    WebMemo1.Lines.Add( Dialog.Files[i].Name) ;

procedure TForm1.WebButton1Click(Sender: TObject);

Hello Holger,

I have the same question about this component. I don't understand what exactly is its purpose.

Yes, I realize that you can use it to select a file and then you can display the file name that you selected.

Okay, fine. And then what happens after that?

How can I do something useful after I've selected a file with TWebOpenDialog?

In TMS WEB Core Demos\Fnc\Blox\ it is used twice, as for opening a Blox file, and for opening a picture into an image object.

procedure TForm5.DoOpenFile(Sender: TObject);
  w: TWebOpenDialog;
  w := TWebOpenDialog.Create(Self);
  w.Accept := '.blx';
  w.OnChange := DoOpenFileChanged;

procedure TForm5.DoOpenFileChanged(Sender: TObject);
  TMSFNCBloxControl1.LoadFromFile((Sender as TWebOpenDialog).Files[0].FileObject);

procedure TForm5.DoOpenPicture(Sender: TObject; AElement: TTMSFNCBloxElement);
  w: TWebOpenDialog;
  w := TWebOpenDialog.Create(Self);
  w.Accept := '.svg,image/*';
  w.OnChange := DoOpenPictureChanged;

procedure TForm5.DoOpenPictureChanged(Sender: TObject);
  TTMSFNCUtils.LoadFile((Sender as TWebOpenDialog).Files[0].FileObject, @DoFileLoaded);

procedure TForm5.DoFileLoaded(const AFile: TTMSFNCUtilsFile);
  b: TTMSFNCBloxElement;
  base64: string;
  base64 := TTMSFNCUtils.FileToBase64(AFile);

  if TMSFNCBloxControl1.Presenter.SelectedCount > 0 then
    b := TMSFNCBloxControl1.Presenter.Selecteds[0];
    if b.isBlock then
      (b as TTMSFNCBloxBlock).Picture.Stream.OnChange := DoPictureChanged;
      (b as TTMSFNCBloxBlock).Picture.LoadFromFile('data:image/svg+xml;base64,' + base64);


Thanks for pointing to the Blox demo.

Unfortunately, that particular example doesn't work for my situation. In the Blox demo, they're calling:

TMSFNCBloxControl1.LoadFromFile((Sender as TWebOpenDialog).Files[0].FileObject);

And in that particular case, the LoadFromFile procedure is expecting a TJSHTMLFile parameter.

When I try to adapt that code to my own program using:

WebMemo1.Lines.LoadFromFile((Sender as TWebOpenDialog).Files[0].FileObject);

I get a compiler error:

[Error] WebOpenDialogTestUnit.pas(131): Incompatible type arg no. 1: Got "TJSHTMLFile", expected "String"

This whole thing is incredibly frustrating. I'm trying to do something which (I believe) should be very simple, and yet it's proving to be impossible.

I simply want to use a WebOpenDialog to select a text file and then display the contents of the text file in a memo.

If this is not possible, I wish somebody from TMS would just reply and say "Sorry, that's not possible."

But so far my calls for help are being ignored. I originally tried posting this question in a different thread ten days ago, and received no responses. Now I tried this thread, and still getting no responses.

Instead of LoadFromFile, use:

    procedure (txt : string)
        webmemo1.Lines.Text := txt; 
1 Like

Thank you, Julio.

It works perfectly.

I wish TMS would create some more events in TWebOpenDialog to handle things like GetFileAsText, GetFileAsBase64, etc., so that we wouldn't have to use ugly anonymous methods.

The events at TWebOpenDialog level will be available in the next update.

Thank you - that would be an excellent update.

I'm stuck at the example in the manual (V1.9.7.0 Sentina) for TWebOpenDialog that won't compile.

All I'm trying to do is display a File Open dialog when the user clicks a button. I cannot find anything that compiles. The selected filenames need to be put into a TWebListBox. I'm guessing that I need to use GetFileAsURL event to get the filenames? But it's not clear how.

When the user clicks on one of the files in the listbox, I want that file (an .mp4 file) to be loaded into a TTMSFNCWXVideoPlayer that's on the form.

I have a TWebButton and I pasted the sample code into the OnClick handler, and I get an error on the line fn := await(string, WebOpenDialog1.Perform); saying:

[Error] frmMain.pas(42): await only available in async procedure

I'm not sure where this sample code belongs.

I've tried other approaches, but nothing compiles.

The Methods chart shows an option for Execute as:

Execute(AProc: TOpenDialogProc);

but Delphi won't recognize it.

The example is inadequate. It needs more context and how different properties and methods work together, because it seems that some are for sync uses while others are for asynch uses.

Also, the Events other than OnChange are not documented in the manual.

I'm working with D10.4.2 and I have WebCore V1.9.7.0 installed.

Ignore my post above. I can no longer edit it.

It appears that Holger made a video on this topic here:

However, it's from before the new events were added.

It would be nice if the manual showed a more complete example, including at least one of the new events.

As an aside, if I want to load one or more *.mp4 files into a list, do I want to save the names as a URL if they're going to be loaded into the FNC media player component?

Also, the manual shows a version of Execute that takes a Proc parameter, but the compiler does not recognize it as far as I could tell.

Basically it is a 2 step process:

  1. You get the OnChange event triggered when one or more files were selected
  2. To get the file, call WebOpenDialog.Files[x].GetFileAs* and the equivalent event OnGetFileAs* will be triggered.

If you want to load a local file in an FNC media player, do a load as base64 and assign the media player URL to this base64 data URL.

WebOpenDialog.Execute has no proc param.

How would one go about selecting a relatively large local (MP3) file on a desktop / laptop via TWebOpenDialog, then upload it to a server via a php script using TWebHttpRequest? Is this even possible in WEB Core?

TWebOpenDialog apparently won't return a full pathname. Instead, it uses a pass-by-value model, so it must inhale the entire file into memory, then pass it along to the next thing, which in this case would be a TWebHttpRequest object. I'm not sure what it wants if not a filename; but if you can give it the entire file (in memory) then how do you ensure it's in the expected format? And how do you pass it in?

It's OK to restrict this to running on a desktop or laptop where the user has access to the entire file system.

BTW, why does this dialog have three different properties to get returned: Name, DisplayName, and GetNamePath, which all return the same thing? (Actually, iterating through the TFiles collection, DisplayName and GetNamePath both return "TFile".)

Get the file as ArrayBuffer with TWebOpenDialog.
Then you have in the event OnGetFileAsArrayBuffer the entire file in memory accessible per byte.
If you want to check the format, you'd need to check the file header here.
Then you can use a TWebHttpRequst to post this data (in the format the server expects) to the server to upload.

Thanks. Again, a code example would be greatly appreciated because the TWebHTTPRequest component is very different from most others I've seen, and I haven't seen a single example of a POST request that uploads data. It does not need to be a fully-working project, just something that shows all of the pieces you need to plug-in to make it work.

As I explained in another thread, it depends on the backend and how you handle POST at the backend and expect data there. What do you have at the backend? How does your backend expect the POST data?

Hi David..

If you still need an example for POST, let me know.

I have several projects where the back end is an Indy web server. In some cases, the client side is POSTing a file, and other cases it's POSTing the values of a TStringList.

Thanks, Steve, but I've gotten this sorted out for the most part. It seems like if you're working with Delphi on both sides of a connection, and you can count on that forever going forward, then things can work fairly smoothly. Bruno has made clear that's all TMS is really interested in. But in the world of web apps, I'm not convinced that's a smart strategy. In particular, I use both a Windows host and a Linux host, mainly b/c I don't find building Delphi apps that run on Linux to be a very straightforward process. PHP is the language used on most Linux hosts for back-end activities; if you know C, C++, and javascript, then you know about 80% of PHP, although PHP has been diverging over time. The environmental stuff is different, but that's going to be the case anyway switching platforms -- just look at how quirky using WEB Core can be than using the VCL to accomplish the exact same tasks with the same components! I mean ... it comes with the territory, and is expected.

Anyway, I love TMS; I love their products; I love the fact that they're doing stuff that Embt should have been doing 10+ years ago; I realize they're just as resource constrained as anybody else today (except maybe Google, MS, Amazon, and IBM); and I can't fault them for sticking to their guns. I just wish the use of Linux wasn't such a stretch to do in Delphi or that it's only limited to people with bigger budgets. And that includes working with the most common back-end scripting language in the world today that's used on Linux platforms. Hint: it's NOT Delphi! Building web app clients in Delphi should not require the use of Delphi on the back-end. But that's just my opinion, and it's the source of a lot of my questions here. That's all.

If you're not already familiar with it, do yourself a favor and look into CodeTyphon. If you enjoy Pascal as your primary language of choice, and if you want to go where Delphi simply doesn't allow you to always go, then it's definitely worth a look. I discovered it back in 2015, and I've been using it to build all of my back-end stuff that runs on Linux x86 (traditional servers) and Linux ARM (Raspberry Pi).

I use Delphi for all of my desktop/mobile applications, and TMS Web for all of my web-based projects. Whenever I need to use Linux (either GUI or command line), I go straight to CodeTyphon.

1 Like