JavaScript/IFrame/Form woes.
May 14, 2007 4:32 PM   Subscribe

Help me solve my seems-like-it-should-be-easy-but-I-can't-figure-it-out JavaScript/Greasemonkey problem!

OK, Here goes: I have a list of many thousands of ID numbers that refer to records in a database. I need to submit each one to a form in the URL (i.e. form.php?id=12345), change the value of one measly pulldown menu on the form, and then submit it. I can't do anything spiffy with AJAX or modify the form somehow, because it's hosted/controlled by another entity. It seemed stupid to me to do these all by hand, so I thought I would try to write a Greasemonkey script that would loop through each ID number, load the form in an IFRAME, change the value, and submit the form. It seemed simple enough at the time...

To test it out, I made a basic mock-up page that loads a form in an IFRAME with the same relevant form information and field name, and then tried to write a script that would change the form. The problem is, nothing works! I know there are a lot of different syntax and browser considerations for how to refer to different objects, and I've pored over dozens of code examples but am clearly still missing something. I can get the script to acknowledge the existence of the form using getElementsByTagName(), but I can't get it to do anything with the form or the SELECT element in it. It always either doesn't find anything at all, or it says the object has no properties. It seems like it should only require a few lines of code to:

1. Find the SELECT object with the name "right.a" in the form that's inside the IFRAME with the id "myframe"
2. Change the value and selectedIndex of that form item
3. Submit the form

But I can't get the element by name, nor can I get it through an array (i.e. forms[0]). Using contentDocument to get to what's inside the frame after I've changed the src seems to be a step in the right direction, but I can't get any positive result after that.

The relevant pages are here:
The test mock-up
The form
The Greasemonkey script


And the source code snippets are here.


Any insight would be much, much appreciated so I don't give myself carpal tunnel clicking through all these...
posted by TunnelArmr to Computers & Internet (5 answers total)
 
The document you get from doing myiframe.contentDocument; is just like the document you're familiar with from document.getElementById, except that it's the document object associated with the document in the iframe.

That means you can operate on its forms array, just like you would do document.forms. Like this:

//put code to find the id here instead.
id='25542';

//get the document within the iframe
ifDoc=document.getElementById('myframe').contentDocument;

//access the first element of the first form (the select, you can also use the name I think)
ifDoc.forms[0].elements[0].value='20';

//change the action to use the id you specified
ifDoc.forms[0].action=ifDoc.forms[0].action+'?id='+id;

//submit the form
ifDoc.forms[0].submit();

Hopefully that makes some sense.
posted by !Jim at 5:01 PM on May 14, 2007


Response by poster: Hey Jim, thanks for the response. I've tried the forms[0].elements[0].value syntax and never gotten a result.

I tried using your code and got 'ifDoc.forms[0] has no properties' in my error console. I also stuck an alert(ifDoc.forms[0].elements[0].value) as a test and it didn't get executed. Any idea why that is?
posted by TunnelArmr at 5:11 PM on May 14, 2007


Hmm... could it be something like greasemonkey isn't set to run on the site in question? I did all the work using Firebug, so that may be a source of deviations. Maybe poke around in its settings?

Also, try going up a level and doing the alert, until you get one that's set. So do

alert(ifDoc.forms[0].elements[0]); then
alert(ifDoc.forms[0]); then
alert(ifDoc)

etc. until you find one that isn't empty. You might also check the lengths of the various arrays.
posted by !Jim at 5:23 PM on May 14, 2007


It may have something to do with how firefox loads the iframe. It looks kind of like the frame doesn't actually load until the greasemonkey script ends, so it could be that Firefox loads the iframe content synchronously. Since the document hasn't loaded, it doesn't have any forms yet.
posted by !Jim at 5:38 PM on May 14, 2007


can't do anything spiffy with AJAX or modify the form somehow, because it's hosted/controlled by another entity

Huh? If the form is ever loaded in your browser, you control the form, or at least that local copy of it. Your script can extract any value out of there, change a selection as would happen manually, and resubmit to the controlling entity without the entity being any the wiser. A submitted form isn't going to an Evil Form Minder which interrogates the browser to ensure there was no nefarious JavaScript code automating the process. Absent further restrictions (e.g. running in a Java applet), it sounds like you might be making things overcomplicated and causing yourself unnecessary grief.

I'm unclear on why the following scenario doesn't work: Go to the form URL as you would for manual input. Have a GM script for that page pick your topmost ID number and submit the number via the URL by changing window.location.href. The form loads for that ID number. Your GM script activates again on the new form load, modifies the drop down to your desired value, and triggers the update. Form goes to a"thank you very much page" or whatever it normally does. GM script activates on page load again to navigate back to the original form URL, submits the next ID number, rinse and repeat.

All the script need do across page loads is track the remaining list of IDs and where you are in the process, i.e. the phase of the ID submission, which it can do via the local GM/browser store. The script can hold the ID list or, since there are a lot of numbers, you could have the script read the ID list from a web page or web-readable e-mail. Then local store need only track the index of the last submitted number on the list.

I don't see anything special about your iframe that couldn't be done easier directly on the page, bypassing all the explicit frame reference hoodoo. Avoid shoehorning in another frame to add to the headache unless there's a real need for it. This process sounds, at least to me right now, like a basic automation task that GM is well-equipped to manage.
posted by mdevore at 7:20 PM on May 14, 2007


« Older Book about Rock Music   |   How to cook delicious beans? Newer »
This thread is closed to new comments.