Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 14 total
Thread File Upload Thoughts
Thu, May 17 2012 4:52 AMPermanent Link

Mark Brooks

Slikware

Avatar

Following a recent thread I wanted to summarise where I'm at in respect of file upload capabilities. To summarise, my app talks to a REST API using TServerRequest. The REST API supports GET, POST, PUT and DELETE, all of which work well with TServerRequest. The REST API also supports file upload to specific URLs. This has been a challenge with EWB.

At a top-level, my requirement is to have the user click a button to select a file then click a second button to upload this file, potentially with some additional work behind the click of the second button.

To achieve the first button requirement (i.e. a file-picker) I used a tip from Rick in an earlier post. This involves dropping a TPage onto a form and having it load some HTML from the server. The HTML looks like this:

<form id='UploadForm' action='' method='post' enctype='multipart/form-data'>
 <input type='file' name='FilePicker' accept='image/*'>
</form>

Essentially the end result is a button which, when clicked, throws up a file picker via the browser. On some browsers the 'accept' attribute serves to limit file selection to image types (which is what I need). Also note that the 'action' attribute is currently blank. This is the URL to upload the file to and I'll fill that in a little later.

The next step is to write some Object Pascal behind the OnClick handler of an EWB button. That code looks like this:

for I := 0 to Window.Frames.Length - 1 do
 begin
   E := Window.Frames.Items[I].Document.GetElementById('UploadForm');
   if E <> nil then
     begin
       E.SetAttribute('action','<Desired URL>');
       THTMLFormElement(E).Submit;
       break;
     end;
 end;

This uses the fact that the TPage is held within an iFrame. It searches through the iFrames until it finds one that contains an element called 'UploadForm'. It then modifies the 'action' attribute of this element to reflect the desired URL for upload. Finally it typecasts as a THTMLFormElement so that it can access the Submit method of the form, thereby executing the upload.

Clearly this is clunky and a dedicated mechanism within EWB would be preferable. In particular the requirement for the TPage versus an EWB 'file-picker-button' makes the UI hard to keep consistent.

Also, can anybody tell me how the Object Pascal code can check to see if a file has been selected?

Cheers
Mark
Thu, May 17 2012 7:32 AMPermanent Link

Rick

<Mark Brooks> wrote in message
news:E580D573-8FA3-4000-A1CC-BEC43E3D4125@news.elevatesoft.com...
>
> Also, can anybody tell me how the Object Pascal code can check to see if a
> file has been selected?
>
>

Hi Mark.

Good work on your solution so far.

Perhaps you could check the contents of the file name edit control by adding
an 'id' attribute to the input tag. Something like the following:

<input type='file' name='FilePicker' id='FilePickerID' ... >

Then you could include the following code in your button click event:

for i:=0 to Window.Frames.Length-1 do
begin
   E:=Window.Frames.Items[I].Document.getElementById('FilePickerID');
   if E<>nil then
    window.alert(THTMLInputElement(e).value);
end;

Unfortunately I can't seem to get any of this to work because
Window.Frames.Length contains NaN so none of the elements are found. Tried
in both IE and Firefox.

--
Rick

Thu, May 17 2012 9:00 AMPermanent Link

Mark Brooks

Slikware

Avatar

>>Perhaps you could check the contents of the file name edit control by adding
>>an 'id' attribute to the input tag. Something like the following:

>><input type='file' name='FilePicker' id='FilePickerID' ... >

>>Then you could include the following code in your button click event:

>>for i:=0 to Window.Frames.Length-1 do
>> begin
>>    E:=Window.Frames.Items[I].Document.getElementById('FilePickerID');
>>    if E<>nil then
>>     window.alert(THTMLInputElement(e).value);
>> end;

Rick, I have tried this approach but always see '' as the return value. Unfortunately whilst I have used Object Pascal forever I'm new to HTML and JS. However, some Googling suggests that viewing the 'value' attribute might be a JS security breach?

>>Unfortunately I can't seem to get any of this to work because
>>Window.Frames.Length contains NaN so none of the elements are found. Tried
>>in both IE and Firefox.

That's funny. It works for me. What versions of the browsers are you using and what OS?


--
Rick
Thu, May 17 2012 7:36 PMPermanent Link

Rick

<Mark Brooks> wrote in message
news:5C95801D-2D1A-4DA2-AFE6-1ECB09B92643@news.elevatesoft.com...
>
> Rick, I have tried this approach but always see '' as the return value.
> Unfortunately whilst I have used Object Pascal forever I'm new to HTML and
> JS. However, some Googling suggests that viewing the 'value' attribute
> might be a JS security breach?
>

Yeah, I find the whole browser/javascript thing a bit unfortunate in its
design and standards approach. Instead of returning a blank it would be nice
if it threw an exception so you knew what was going on (if it is in fact a
security issue). Perhaps the browser's error log contains further
information.

The differences between browsers is very disconcerting. For example, you can
use setAttribute in Firefox to change the type of an input control but you
get an exception (command not supported) if you attempt the same in IE. This
is where I think EWB will really come into its own. The more controls and
browsers it supports natively, the less "hacking" will be required.

>
> That's funny. It works for me. What versions of the browsers are you using
> and what OS?
>

I'm using IE8 (8.0.6001.18702CO) and Firefox 12.0. Running on Windows XP
SP3. Neither browser appears to return a valid integer from
window.frames.length. In fact, it's a bit strange because I would have
thought the FOR loop would fail causing an error but it just continues as
though the exit condition has been met.

I see "NaN" displayed if I do window.alert(IntToStr(window.Frames.Length)).

--
Rick

Fri, May 18 2012 4:35 AMPermanent Link

Mark Brooks

Slikware

Avatar

>>The differences between browsers is very disconcerting. For example, you can
>>use setAttribute in Firefox to change the type of an input control but you
>>get an exception (command not supported) if you attempt the same in IE. This
>>is where I think EWB will really come into its own. The more controls and
>>browsers it supports natively, the less "hacking" will be required.

Totally agree. EWB is panning out really nicely in this respect. Need a TTreeView soon (Tim are you listening?)

>>I'm using IE8 (8.0.6001.18702CO) and Firefox 12.0. Running on Windows XP
>>SP3. Neither browser appears to return a valid integer from
>>window.frames.length. In fact, it's a bit strange because I would have
>>thought the FOR loop would fail causing an error but it just continues as
>>though the exit condition has been met.

Strange. Works for me with IE8 on Win7. No access to Firefox so can't confirm either way. Out of interest, assuming that you only have one TPage and therefore one iFrame, have you just tried this:

E := Window.Frames.Items[0]

Does it give you a valid TElement reference? If so then you're up and away.

Mark
Sun, May 20 2012 7:44 AMPermanent Link

Rick

<Mark Brooks> wrote in message
news:1C096A5B-6674-44B8-B923-74DC95BE5B3A@news.elevatesoft.com...
>
> Strange. Works for me with IE8 on Win7. No access to Firefox so can't
> confirm either way. Out of interest, assuming that you only have one TPage
> and therefore one iFrame, have you just tried this:
>
> E := Window.Frames.Items[0]
>
> Does it give you a valid TElement reference? If so then you're up and
> away.
>
>

Hi Mark.

It seems that Window.Frames.Length always returns NaN. The following code
correctly submits the form for me:

E := Window.Frames.Items[0].Document.getElementById('UploadForm');
if E <> nil then
begin
  E.SetAttribute('action','file_upload.php');
  THTMLFormElement(E).Submit;
end;

Thanks.

--
Rick

Sun, May 20 2012 7:48 AMPermanent Link

Rick

<Mark Brooks> wrote in message
news:5C95801D-2D1A-4DA2-AFE6-1ECB09B92643@news.elevatesoft.com...
>
> Rick, I have tried this approach but always see '' as the return value.
> Unfortunately whilst I have used Object Pascal forever I'm new to HTML and
> JS. However, some Googling suggests that viewing the 'value' attribute
> might be a JS security breach?
>
>

Mark, as long as the file picker html is in the same output directly along
with the EWB application then the following code correctly displays the
value of the edit box for me (assumes that the ID of the file input control
is "FilePicker"):

E := Window.Frames.Items[0].Document.getElementById('FilePicker');
if E <> nil then
window.alert(THTMLInputElement(E).value);

--
Rick

Mon, May 21 2012 9:46 AMPermanent Link

Mark Brooks

Slikware

Avatar

>>Mark, as long as the file picker html is in the same output directly along
>>with the EWB application then the following code correctly displays the
>>value of the edit box for me (assumes that the ID of the file input control
>>is "FilePicker"):

>>E := Window.Frames.Items[0].Document.getElementById('FilePicker');
>>if E <> nil then
>> window.alert(THTMLInputElement(E).value);

Rick.
Will give this a shot tomorrow (out of town today).
Appreciated.
Mark.
Mon, May 21 2012 2:33 PMPermanent Link

Mark Brooks

Slikware

Avatar

Mark Brooks wrote:

>>Mark, as long as the file picker html is in the same output directly along
>>with the EWB application then the following code correctly displays the
>>value of the edit box for me (assumes that the ID of the file input control
>>is "FilePicker"):

>>E := Window.Frames.Items[0].Document.getElementById('FilePicker');
>>if E <> nil then
>> window.alert(THTMLInputElement(E).value);

>>Rick.
>>Will give this a shot tomorrow (out of town today).
>>Appreciated.
>>Mark.

Rick
Had a chance to test this earlier. Also works for me. Many thanks.
Out of interest you can also get a handle on when the input value changes like this:

E := Window.Frames.Items[0].Document.getElementById('FilePicker');
THTMLInputElement(E).OnChange := MyOnChangeHandler;

Cheers
Mark
Mon, May 21 2012 8:44 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Mark,

<< Totally agree. EWB is panning out really nicely in this respect. Need a
TTreeView soon (Tim are you listening?) >>

Yes. Smile

Tim Young
Elevate Software
www.elevatesoft.com
Page 1 of 2Next Page »
Jump to Page:  1 2
Image