views:

1301

answers:

3

So, in pure HTML, I can create a form that loads its results into an iframe (instead of moving the user to the result url).

<html>
  <head>
    <title>Google Preview</title>
    <style>iframe { width: 800px; height: 600px }</style>
  </head>
  <body>
    <form method='get' action='http://www.google.com/search' target='results'>
      <label for='q'>Google Search:</label>
      <input name='q'/>
    </form>
    <!-- form result loads in this iframe -->
    <iframe name='results'></iframe>
  </body>
</html>

I'm trying to do a similar thing in Greasemonkey, and running into issues.

I have a page with a form that I'd rather have load its results into an iframe, so I create an iframe, and change the form target to match the iframe's name. However, this doesn't load the result page in the iframe, but instead opens the result page in a new tab.

I've traced the problem down to using Javascript to create the iframe. It seems to insert the iframe into the DOM just fine (and looking at firebug, the source generated is nearly identical to that above, except for an extra <script> tag). But when I create the iframe in Javascript, I get the 'open results in a new tab' behaviour.

<html>
  <head>
    <title>Google Preview</title>
    <style>iframe { width: 800px; height: 600px }</style>
  </head>
  <body>
    <form method='get' action='http://www.google.com/search' target='results'>
      <label for='q'>Google Search:</label>
      <input name='q'/>
    </form>
    <script>
      try {
        // form result doesn't load in this iframe, for some reason
        const iframe = document.body.appendChild( document.createElement('iframe') );
        iframe.name = 'results';
      } catch (e) {
        alert(e);
      }
    </script>
  </body>
</html>

What do I need to do to get the results to load in a iframe created by Javascript? (I haven't tried document.write() yet, but I'm not sure that would be very useful from Greasemonkey).

update: So I got around to trying document.write(), and it works. So maybe I'll just have to figure out how to use that from GreaseMonkey (without messing up my multitude of DOM elements I have handles to)

<html>
  <head>
    <title>Google Preview</title>
    <style>iframe { width: 800px; height: 600px }</style>
  </head>
  <body>
    <form method='get' action='http://www.google.com/search' target='results'>
      <label for='q'>Google Search:</label>
      <input name='q'/>
    </form>
    <script>
      try {
        // but form result will load in this iframe
        document.write('<iframe name="results"></iframe>');
      } catch (e) {
        alert(e);
      }
    </script>
  </body>
</html>

I'm still want to know why document.body.appendChild() doesn't work, but document.write() does.

update2: it doesn't seem to be just forms, I can substitute a link in instead of the <form>...</form> and get the same results for all three cases

<div><a target="results" href="http://www.google.com"&gt;test&lt;/a&gt;&lt;/div&gt;
A: 

hmmm i'm thinking because it's still posting back to itself so the frame is never created (because the form is created and rendered on page on every postback)

jonezy
If it was posting back to itself, shouldn't the pre-postback version (the one where I submitted the form, that already had an iframe) be in the browser history? Nothing's getting added to the browser history, which makes me think this isn't it.
rampion
I just checked this by inserting an `alert()` into the script tag. The alert only shows up once (when I load the page), not after I submit the form, which makes me fairly certain there's no postback going on.
rampion
A: 

Did you try var instead of const?

var iframe = document.body.appendChild( document.createElement('iframe') );

Seems like const objects can't be changed, so maybe the iframe.name is not taking.

Also consider a different variable name-- "myIframe" instead of "iframe" in case of reserved word issues. Could also try the myIframe.setAttribute('name','results') syntax instead of myIframe.name='results'.

Seth
`const` in Javascript just means the variable isn't going to be reassigned to a different object, not that the object can't be modified. The iframe name still takes.
rampion
I tried the setAttribute method originally (since .name= doesn't work in GreaseMonkey) and the same behaviour results.
rampion
'iframe' isn't a reserved word in Javascript, I believe. I did try changing the variable name anyway, but no change in behaviour.
rampion
+1  A: 

Okay, I figured out a satisfactory solution. I need to define the iframe name before I call appendChild().

<html>
  <head>
    <title>Google Preview</title>
    <style>iframe { width: 800px; height: 600px }</style>
  </head>
  <body>
    <div><a target="results" href="http://www.google.com"&gt;test&lt;/a&gt;&lt;/div&gt;
    <script>
      try {
        // this works
        const iframe = document.createElement('iframe');
        iframe.name = 'results';
        document.body.appendChild( iframe );
      } catch (e) {
        alert(e);
      }
    </script>
  </body>
</html>

I'm not sure why setting the name after appending it to the document didn't work (and I'd still like to know if anyone out there wants 15pts), but this lets me get on with my GreaseMonkeying, so it's good enough.

rampion