thekestrel has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,
I'm trying to traverse some links and forms which use javascript in the data =( and am using Win32::IE::Mechanize. The issue that I'm having is that I want to add one more value to a form before submitting it and can't seem to work out how???
Everything seems nicely geared towards getting and setting existing values, but I'm now sure on how to create a new one. Win32::IE::Input seems to have a 'new' method, but I'm not sure how to implement it.... Here is what I have....

Take one vanilla form...
<html> <body> <script language="JavaScript"> function fun() { document.form1.submit() } </script> <form name='form1' action="http://www.msn.com"> <input type=hidden name="Fruit" value="apple"> <input type=hidden name="Animal" value="dog"> <input type=hidden name="language" value="perl"> </form> <a href="javascript:fun()">A link</a> </body> </html>

Now to submit the form use something like...
use Win32::IE::Mechanize; use Win32::IE::Input; use warnings; use strict; #location of the html with the form my $url = "http://location.of.test.file/test.html"; my $ie = Win32::IE::Mechanize->new(visible => 1); #get the page $ie->get($url); #select the form my $form = $ie->form_name('form1'); #This is the bit I'm stuck on... #Its going to need a name, type and value my $new1 = Win32::IE::Input->new(); print "NEW : $new1 " . $new1->name . "\n"; #This should print out the existing list of inputs PLUS the one I just + added my @inputs = $form->inputs(); my $c = 1; foreach my $i ( @inputs ) { print "Input$c : " . $i->name . " : " . $i->value . " : " . $i +->type . "\n"; $c++; } #find the link and follow ...this works fine my $link = $ie->find_link( url_regex => qr/fun/i ); my $ll = $link->url; $ie->get($ll);
The output from the script shows the current inputs, but not the new one...half expected because I'm not sure how to put it together. I imagine you'll need to...

1. Create an input instance
2. Populate input with name,value,type
3. Add input to current form

Can someone point me in the right direction as to how this is done.
Regards Paul.

Replies are listed 'Best First'.
Re: Win32::IE::Input
by ikegami (Patriarch) on Jul 13, 2005 at 23:12 UTC

    Win32::IE::Form and Win32::IE::Input are Perl copies of IE objects, and they don't provide methods to modify their IE counterparts. You'll need to access the Document and add the field to it just as you would in JavaScript.

    # Select the form my $perl_form = $ie->form_name('form1'); # Get a pointer to IE's DOM object. my $form = ${$perl_form};

    $form is IE's object for the form. It's an instance of a DOM form.

    Untested example:

    my $doc = $ie->Document; my $form = ${$ie->form_name('...')}; my $field = $doc->createElement('<INPUT TYPE="hidden">'); $field->name = '...'; $field->value = '...'; $form->appendChild($field);

    $doc is a DOM document.
    $form is a DOM form.
    $field is a DOM hidden input.

    I'd love to hear how well this works.

    Updated: Added more info. Rephrased in order to intergrate new info.

      Ikegami,
      Thanks for the reply. A little bit of tweaking, but you were pretty much on the money =).
      my $doc = $ie->agent->Document; my $form = ${$perl_form}; my $field = $doc->createElement('<INPUT NAME="FLUFFY" VALUE="socks" TY +PE="hidden">'); $form->appendChild($field); my @inputs = $perl_form->inputs(); my $c = 1; foreach my $i ( @inputs ) { print "Input$c : " . $i->name . " : " . $i->value . " : " . $i +->type . "\n"; $c++; }

      The $doc just needed an agent slapped in the middle and with field I could only get it to work when I added all the data in one line, but I didn't tinker with it too much.
      Update: looked into it a bit more you can do the field definition with the following...
      ... my $field = $doc->createElement('<INPUT TYPE="hidden">'); %{$field}->{name} = "FLUFFY"; %{$field}->{value} = "socks";

      Which gives....
      Input1 : Fruit : apple : hidden Input2 : Animal : dog : hidden Input3 : language : perl : hidden Input4 : FLUFFY : socks : hidden
      Thanks for your help ++. =)

      Regards Paul