Sorry in advance for such a long post here...
I'm using select() to select an item from a 'select' list (duh! :-) - but I do not know ahead of time what the names of said items are.
So, I wrote something like this:
my $ans = 1; # or whatever.
while ($ans)
{
%pickme = ( n => 1 ); #yes, this should be outside the while. So s
+ue me ;-)
$ans = $mech->select( 'server', \%pickme );
if ($ans)
{
$inputobj = $mech->current_form()->find_input( 'remove', 'subm
+it');
die 'argh! Cannot find delete button on the iSCSI Access page!
+' unless $inputobj;
$ans = $mech->click_button( input => $inputobj );
}
}
print "Done! Now, accept the empty list\n";
# ok, now accept a (hopefully) empty list of allowed accessors
$inputobj = $mech->current_form()->find_input( 'accept', 'submit');
die 'argh! Cannot find Accept button on the iSCSI Access page!' unless
+ $inputobj;
$ans = $mech->click_button( input => $inputobj );
However, it turns out that select will ALWAYS think that it can select entry 1, even if the list is empty. In other words, even when the html looks like this:
<td>
<input type="hidden" name="serverList" value="">
<select size="10" name="server" style="width: 330px">
</select>
</td>
The above code will get '1' back from select and go running on forever. Not a good thing...
I discovered that if entry 2 didn't exist, and you tried to select THAT entry you'd get an appropriate error, so I ended up with this as a workaround:
while ($ans)
{
%pickme = ( n => 2 );
eval { $ans = $mech->select( 'server', \%pickme ); };
if ($ans eq 1)
{
$inputobj = $mech->current_form()->find_input( 'remove', 'subm
+it');
die 'argh! Cannot find delete button on the iSCSI Access page!
+' unless $inputobj;
$ans = $mech->click_button( input => $inputobj );
}
else
{
$ans = 0;
}
}
%pickme = ( n => 1 );
$ans = $mech->select( 'server', \%pickme );
$inputobj = $mech->current_form()->find_input( 'remove', 'submit');
die 'argh! Cannot find delete button on the iSCSI Access page!' unless
+ $inputobj;
$ans = $mech->click_button( input => $inputobj );
print "Done! Now, accept the empty list\n";
# ok, now accept a (hopefully) empty list of allowed accessors
$inputobj = $mech->current_form()->find_input( 'accept', 'submit');
die 'argh! Cannot find Accept button on the iSCSI Access page!' unless
+ $inputobj;
$ans = $mech->click_button( input => $inputobj );
It seems to me that the first form should have worked (see the
Mechanize page under select() for details of why - won't bore everyone here with that), so I'm looking at the Mechanize and Form code to see why it allows a 'select' of 1 when there are no items.
I've looked at WWW::Mechanize, and the issue seems to be in Form instead. Here is the section that seems to be involved here:
for (@{$self->{menu}}) {
if ((defined($val) && defined($_->{value}) && $val eq $_->
+{value}) ||
(!defined($val) && !defined($_->{value}))
)
{
$cur = $i;
$disabled = $_->{disabled};
last unless $disabled;
}
$i++;
}
When there is nothing in the select list, the above test still passes! I note, when stepping through the code, that if I print $val when I'm looking at the 'big if' above, I get a blank line, BUT defined($val) is true!
So, am I just confused, is the above test wrong, is my code wrong, or ???
(
Conclusion: the HTML is wrong - its illegal to have a select with no option. You should have a single empty option, and detect that its an empty option (I'll have to RTFM for how to do that, but that's just Fine :-)
Thanks!
Final comment - thanks to Hermit (
psini for his/her help - and sorry for not thinking to RTFM on how HTTP select fields work, once the comment was made (too focussed on Mechanize::select and figuring out how to get around having no (obvious) way to tell when there's nothing there....
Anyway, I consider this thread finished (and now I know what bug to file with the authors). I've modified the subject, at the suggestion of ambrus, to make it better. Thanks again!
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.