0

The crux of my problem is: How can I tell if a window launched via a form submit was actually launched?

I inherited a messy old web site that uses CGI & Perl on an Apache server. It was written decades ago and the code is really terrible even for Perl so I want to avoid changing too much as we have hundreds of reports used by hundreds of customers.
The initial problem was that when an 'Ok' button was pressed, it sometimes appeared that nothing happened because the process took a long time so a user would keep clicking it. This would spawn many new processes on the Unix box running Apache and cause problems. The way the 'programmer' designed the site, he put a name in the target attribute of the form tag. This USUALLY opens a new window (eventually) with that name.

<form name="PARAMETERS"
  method="POST"
  action="reportsrv.cgi"
  onsubmit="watchChild('_REPORT1556723905', 'reportSubmit3', true);"
  target="_REPORT1556723905">

Another programmer tried to fix this by disabling the OK button using java script and then having the newly opened window find its parent and then enable the button. This did not work when, in our hosted environment, sometimes the new window simply did not open. So our customers think something is happening when it is not (because the window did not open and the javascript to enable the button never ran).
I wrote a simple function that uses setTimer to look for the window and see if it is open BUT the only way to find it is to use the window.open() function.

function watchChild(targetName, thebuttonname, disable) {
setTimeout( function()
{
    var child = window.open("", targetName); // opens new window if not found!
    if (!child) {
        child = window.frames[targetName];
    }
    var child = window.frames[targetName];
    if (child) {
        alert('child found');
        if (disable) {
            //disableButton(thebuttonname, disable);
        }
        watchChild(targetName, thebuttonname, false);
        return;
    }
    // frames are empty
    alert('child not found: ' + targetName + '; frame count = ' + window.frames.length);
    //disableButton(thebuttonname, false);
}, 3000 );

Now my problem is that the only reliable way to find the window (if it exists) if window.open("", Name) but that opens a blank window if the window does not exist.
The logic of the child window is that nothing is rendered until the process is finished (which may take a long time) so I can't add javascript to it until then.
Can anyone see a way to tell if the window is open without opening another window? I could keep a reference to it if it wasn't opened by a form submit event.

Belmiris
  • 2,741
  • 3
  • 25
  • 29

1 Answers1

1

I suspect you could adapt this technique to your situation.

If not, though, another approach comes to mind:

  • Don't disable the submit button (or do so only briefly).
  • In a submit handler, have JavaScript code open the window proactively in response to the form submission, and disable the form submission.
  • Have the page the JavaScript code loads say the process is running.
  • Have that page call back to its opener to say when it has loaded.
  • Respond to that by submitting the form programmatically (if you do this with the DOM's own HTMLFormElement#submit method, it won't trigger the submit handler; some tools like jQuery will, so beware of that).
    • That will make the form target the already-open window.
  • If you want the button disabled for the entire time the report takes, have code in the response page reach out to opener to tell it the response has arrived (so opener re-enables the button). Also put a timeout in the "loading" page that does the same (and shows a timeout error).
Asons
  • 84,923
  • 12
  • 110
  • 165
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I like your fifth option. The others rely on the opened form manipulating it's parent which was the original plan but the child window is never opening for some reason. So if I create the window BEFORE doing a form.post() call, will it open in that widow even though the window is rendered by Apache? I'll try it. – Belmiris May 01 '19 at 16:25
  • @Belmiris - Sorry, I guess I was unclear. The first set of bullet points are one option, meant to be taken together (e.g., they're different parts of a single solution). Re your window question: Yes, that's how the `target` attribute works, and it's done at the browser level, not Apache. If the target already exists, it will get reused by the browser. :-) – T.J. Crowder May 01 '19 at 16:28
  • Well, it worked really well in IE, Edge and Chrome. I even inserted a little loading h1 tag in the window while it waited. BUT, we launch this from a WebBrowser control in a .NET winform application and there is does not re-use the window. It makes 2 windows. Thanks very much for this. – Belmiris May 01 '19 at 20:37
  • I will try your idea of copying the form to the new window. I assume I will want to make the target = "_self". – Belmiris May 01 '19 at 20:57
  • I'm confused by the adding of the cloned form back to the parent of the form. Anyway, I keep getting an unspecified error when calling newWindow.appendChild(theForm). See my 'answer. below. – Belmiris May 01 '19 at 21:53
  • @Belmiris - I've removed that part of the answer. Copying elements between two different DOMs turns out to be a problem. (The reason for appending the clone to the parent of the original was that `appendChild` would *move* the original, taking it out of the page. So putting in the clone restores it. But that approach doesn't seem to work anyway, so...) – T.J. Crowder May 02 '19 at 06:09
  • I appreciate your time T.J. Crowder. As I said, your solution for launching a window with the same name as the target of the POST works well in all major browsers, just not in the stupid WebBrowser control in Winforms. I have marked your response as the answer. – Belmiris May 02 '19 at 14:59
  • @Belmiris - **Ouch**, that's unfortunate. Did you find a way to make things work? – T.J. Crowder May 02 '19 at 15:06
  • No. I may look into the WebBrowser control but I seriously doubt it's anything I can control. Maybe this will be the kick in the pants to get management to let me rewrite this using modern technology (and better design). – Belmiris May 03 '19 at 15:27