http://qs321.pair.com?node_id=143541

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

I am using
print $q->checkbox_group ( -name=>'predefined', -values=>@predefined, );
to print a list of checkboxes.
However, it is mushing everything on to one line, and I now it is designed to act like that but it is really ugly.
The array elements are strings.
The only way I could think of is to change $, to "<br>\n"
Is there a better way? (without adding junk to the end of the elements themselves or the obvious route of not using OO CGI.pm)

Also, the funny part, the html that CGI.pm is outputing looks like this:
<input type="text" name="something" size="15" maxlength="15" /> <input type="checkbox" name="predefined" value="a line of text." />a l +ine of text <input type="submit" name="submit" value="Preview" /> <input type="hidden" name=".cgifields" value="predefined" />
I have never seen CGI.pm end every form field with />
And why is it creating this hidden field?
This is the latest version of CGI.pm from cpan.
I think.. no, it is what came bundled with the perl5.6.1 code.... 2.752 I guess that is.
Is this new in the latest CGI.pm code because I have not had this happen before.
...or is it just me? Don't be afraid to tell me if you think I'm crazy.

-xtype

Replies are listed 'Best First'.
Re: CGI.pm being funny?
by Zaxo (Archbishop) on Feb 06, 2002 at 03:14 UTC

    Among the other properties of &CGI::checkbox_group is {linebreak=>'true'}. The list of @predefined should be an arrayref:

    print $q->checkbox_group ( -name=>'predefined', -values=>\@predefined, -linebreak=>'true' -default=>[ @predefined[@slicer] ], -labels=>\%predefined_labelhash, );
    Those are all documented in 'perldoc CGI'.

    Update: Corrected the omitted '-' in the arguments. Here is a working test:

    #!/usr/bin/perl -w use strict; use CGI; my $q = CGI->new(); my @predef = ( 'abba', 'dabba', 'doo'); my @slicer = ( 1 ); my %labels = ( abba => 'pop', dabba => 'amateur', doo => "don't go the +re" ); print $q->checkbox_group ( -name => 'predefined', -values => \@predef, -default => [@predef[@slicer]],  -linebreak => 'true', -labels => \%labels,); =pod comment $ perl ~/tcgi.pl <input type="checkbox" name="predefined" value="abba" />pop<br /><inpu +t type="checkbox" name="predefined" value="dabba" checked="checked" / +>amateur<br /><input type="checkbox" name="predefined" value="doo" /> +don&#39;t go there<br /> $ =cut
    xtype, maybe your @predefined array doesn't contain what you think it does.

    After Compline,
    Zaxo

      Actually,
      print $q->checkbox_group ( -name=>'predefined', -linebreak=>'true', -values=>\@predefined, -defaults=>param('predefined'), );
      does not appear to work. And instead fills the value and label of one checkbox with the arrayref. It returns something like:
      <input type="checkbox" name="predefined" value="ARRAY(0x833ced0)" />AR +RAY(0x833ced0)<br />
      Where as:
      print $q->checkbox_group ( -name=>'predefined', -linebreak=>'true', -values=>@predefined, -defaults=>param('predefined'), );
      Works perfectly well. And acts exactly the same as changing $, did. (except xhtml-ish br tag).
      <input type="checkbox" name="predefined" value="element content" />ele +ment content<br />
      The perldoc appears to say one thing and do another.
      Even in its' own examples...
      "...the second argument should be an array reference." and yet:
      print $query->checkbox_group(-name=>'group_name', -values=>['eenie','meenie','min +ie','moe'], -default=>['eenie','moe'], -linebreak=>'true', -labels=>\%labels);
      The perldoc also gives this example:
      @h = $query->checkbox_group(-name=>'group_name',-values=>\@values); &use_in_creative_way(@h);
      But this just fills @h with one element.
      print $h[0]; --- <input type="checkbox" name="group_name" value="ARRAY(0x833d000)" />AR +RAY(0x833d000)
      Very odd indeed.
        The reason for the behavior you are seeing is that @predefined contains an array reference, rather than a plain value. Since you don't show how you defined @predefined, it is impossible to say where you went wrong. Suffice it to say that:
        print $q->checkbox_group ( -name=>'predefined', -linebreak=>'true', -values=>@predefined, -defaults=>param('predefined'), );
        is not the right way to pass values to a CGI method. @predefined will be flattened into the argument list. If @predefined contains a single value, you've lucked out and it will work okay. If @predefined contains an odd number of values, the first will be taken as the value for the -values key, and the rest will be taken as separate key/value pairs. Worst case, if @predefined contains an even number of values, all the remaining explicit key/value pairs will be shifted by one, so that the keys are used as values and vice versa.
Re: CGI.pm being funny?
by CharlesClarkson (Curate) on Feb 06, 2002 at 03:19 UTC

    values is looking for a reference:

    print $q->checkbox_group ( -name=>'predefined', -values=>@predefined, );
    should be:
    print $q->checkbox_group ( -name=>'predefined', -values=> \@predefined, );

    I have never seen CGI.pm end every form field with />

    CGI.pm is xhtml compliant. Here's the header:

    <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd">

    The <code>/><code> is applied to any tags that don't have corresponding closing tags.




    HTH,
    Charles K. Clarkson
    Clarkson Energy Homes, Inc.
      Hmmmmmm... I have always passed -values an array. Either by =[‘blah,'blah'] or =@array.
      And...
      my $tmp = $,; $, = "<br>\n"; print $q->checkbox_group ( -name=>'predefined', -values=>@predefined, -defaults=>param('predefined'), ), $q->submit(-name=>'submit', -value=>'preview'), $q->end_form; $, = $tmp; # return output field separator to it's original value.
      Is working for me just fine. Perhaps it is only still working for backward compatibility?
      I just wanted to see if any of you more knowledgeable monks had a better way.
      ++Zaxo and talexb for the -linebreak=>'true' bit.
      When I started using CGI.pm, back in the day, I did actually read the manuals, perldoc.
      Also for me, up until now, header always returned
      <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
      For my past employer(s), upgrading software was never up to me (read: "everything had to be standard, and their standards were far behind" or "get slapped if you try to do something different/better").
      I suppose this is what I get for not keeping up on my perldoc readings anyway.
      I shall go now and read the latest perldoc:cgi since I am using an updated CGI.pm from what I am used to (xhtml, whoo, I wonder what else is changed!).

      Thanks everyone for your replies.
      Cheers, -xtype
        Hmmmmmm... I have always passed -values an array. Either by =[‘blah,'blah'] or =@array.

        ['blah','blah'] creates an array ref.. not an array.

        Rich

Re: CGI.pm being funny?
by talexb (Chancellor) on Feb 06, 2002 at 03:36 UTC
    Have a look at this page where it talks about "CREATING A GROUP OF RELATED CHECKBOXES". It will probably answer your the question (hint: see point 3., the one that relates to making the list look like a vertical list rather than a horizontal one.

    The " />" is XHTML .. if CGI.pm does it, it's probably OK.

    --t. alex

    "Of course, you realize that this means war." -- Bugs Bunny.

      XHTML is very ok. You can turn it off with use CGI qw(-no_xhtml);. If you put CGI.pm xhtml output into the middle of an HTML4 template it could cause the resulting HTML to cough up some minor validation errors but browsers should be able to handle them gracefully.
Re: CGI.pm being funny?
by Steve_p (Priest) on Feb 07, 2002 at 14:28 UTC
    You will only see the "/>" for tags where there is not a closing tag such as img, br, input, etc. This is to make CGI compliant for XHTML. If I remember right, CGI.pm has been XHTML compliant for quite a while now.