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

I just wasted another 1/2 day trying to coerce this to work. It worked earlier today, and after a few cosmetic edits, it stopped working. Like:

$cgi->checkbox( { -name => 'cb-1', -value => 1, -label => "", -checked + => 'checked' } );

And the result is the same as when I leave out the -checked part: the html does NOT say checked. I inspected the actual HTML and its inexplicably missing. I added a debug point to print the HTML right after the checkbox ; its decidedly not there. The most vexing part- earlier today it worked. I've run the usual gauntlet of trying "checked", 1, "on" etc , recommended by various Perl sites; none cooperate today.

So being the end of the day Friday, I hate to be defeated, but I just added:

$cb = $cgi->checkbox( { -name => 'cb-1', -value => 1, -label => "" } ) +; $cb =~ s/(value)/checked $1/;

Which is really undesirable, and FUGLY, since the preference is to let the Perl CGI do the work. But unlike the CGI, THIS WORKS!

I'll review this Monday for suggestions but note to whoever wrote the Perl CGI- checkbox is a HOT MESS! Everytime I write code that has to check a checkbox it's like i DREAD it! Pretty much everything else in the CGI works as stated, but since this setting is stated like 6 different ways, maybe its not amazing it seldom works.

This was so frustrating that Monday I plan to look at the actual checkbox code IN the Perl CGI, but I just know it'll be like a switch with 3 globs, 2 closures, and 3 evals!!

Replies are listed 'Best First'.
Re: is there anything more VEXING than checking the $cgi->checkbox ?
by pryrt (Abbot) on Nov 17, 2023 at 21:57 UTC
    In CGI.pm 4.60, the code you showed works as advertised. Here's an SSCCE:
    use warnings; use strict; use CGI; my $cgi = CGI->new(); print "CGI.pm Version: $CGI::VERSION\n"; print $cgi->checkbox( { -name => 'cb-1', -value => 1, -label => "", -c +hecked => 'checked' } ); print "\n\n"; __END__ CGI.pm Version: 4.60 <label><input type="checkbox" name="cb-1" value="1" checked="checked" +/></label>

    So I don't know what you're doing wrong, but it should work.

    Aside: I don't know whether you've read the documentation in the last few years, but CGI.pm makes it pretty clear that its HTML Generation functions should no longer be used, and explains the reasons. (That note has been there since 4.04 released in September 2014.) As it explains, though it's recommended to use a full framework when possible, it is still reasonable to use CGI.pm for handling the input parameters and otherwise handling the Common Gateway Interface requests and responses (though CGI::Fast or others give the same hooks in a smaller package), but you should definitely use a templating toolkit of some sort for actually generating your HTML.

      We're on CGI 4.51 perhaps an update is required. This is an odd presumption: I don't know what you're doing wrong. Perhaps it's more accurate to suggest I don't know what the CGI checkbox sub author was smoking that day!

      CGI.pm sub checkbox states "$checked -> (optional) turned on by default if true

      Suggested that any value other than 0, '', or undef, should "turn on" checked. What "turned on" means is unspecified. It should result in the word "checked" in the HTML . Im passing "on" and it's not there.

      I edited the perl lib module CGI.pm .

      First I added die $checked; and it said "on". So far so good.

      Then I removed that, and at the end where it "returned", I changed that to die. And I get:

      <label><input type="checkbox" name="dev" value="on" class="readonly" / +></label>

      proving my checked is set to "on",and its missing in the result.

Re: is there anything more VEXING than checking the $cgi->checkbox ?
by misterperl (Friar) on Nov 20, 2023 at 15:02 UTC
    OK, studying the CGI.pm sub , I see where the author seems to be evaluating "override" where in some circumstances, instead of honoring $checked, he uses $self->_checked() which seems to seek only the value "checked", inconsistent with the other comment, that it only needs to be TRUE.

    So I added override => 1 and now everything is working.

      This is explained in the documentation: Per default, CGI::HTML::Functions is state-preserving, that is, input from a previous requests overrides the defaults in the code. The simple example given by pryrt works because there is no previous request.

      You can use the -nosticky pragma to prevent that generally, or use override on a per-element basis, if you want a different behavior.

      So I added override => 1 and now everything is working.

      Ah, that makes sense. If you had previously submitted the form with that specific checkbox being unchecked, then the normal behavior of CGI.pm is to keep that existing state when it prints the new copy of the HTML -- that would explain why the results with no input using my code didn't match what you were seeing.

      To make sure that your form is always in the "pristine" state rather than inheriting from the input parameters it received, then you have to tell CGI.pm to do it that way.

      The CGI.pm documentation for 4.51 explains this in the CGI::HTML::Functions "CREATING FILL-OUT FORMS:" section (as does 4.60 in the equivalent section of the docs):

      Another note The default values that you specify for the forms are only used the first time the script is invoked (when there is no query string). On subsequent invocations of the script (when there is a query string), the former values are used even if they are blank.

      It then goes on to explain that you can either use the param() method to set the value for that parameter to what you want, or you can use the override flag to have the "default" values you supply in your code used even if there was an input value from the query string or post parameters.

      which seems to seek only the value "checked"

      "checked" is the value that HTML uses. Well, sort of, most of the time. The original specs of HTML are rather vague, and the modern ones backwards compatible. And there is the thing with XHTML, which needs to be valid XML as well as valid HTML.

      So a pre-checked checkbox can be specified like this in HTML

      <input type="checkbox" checked> <input type="checkbox" checked="checked"> <input type="checkbox" checked="">

      But in the stricter XHTML spec, only this one seems to be valid:

      <input type="checkbox" checked="checked">

      I dimly remember that the return value in a form for a checkbox is also a bit strange, i think it's "on" or something similar. Don't quote me on that, i never use those damn things in my web framework directly anymore sine i wrote a touch-friendly replacement (that also accepts custom values for the "on" and "off" states) about 15 years ago...

      PerlMonks XP is useless? Not anymore: XPD - Do more with your PerlMonks XP