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.

        I'm sorry that my phrasing offended you. If you still want help, you can continue reading, and try the experiments I recommend. If you don't want help, then sorry for wasting your time.

        edit: The further revelations in Re: is there anything more VEXING than checking the $cgi->checkbox ? change my interpretation. Moved this answer into a spoiler, as it's not likely relevant anymore.

        We're on CGI 4.51 perhaps an update is required.

        I just installed a copy of CGI 4.51 and ran my exact code from my last post. It behaved exactly as I expected:

        % perl -Mlocal::lib=./locallib pm11155672.pl CGI.pm Version: 4.51 <label><input type="checkbox" name="cb-1" value="1" checked="checked" +/></label>

        Thus, based on my experiments, I conclude that the difference in CGI.pm version between your 4.51 and the more-recent 4.60 does not appear to be what's causing the difference in output, because the two different versions both produce the same output with the same script for me.

        Im passing "on" and it's not there.

        That's not what you said you were doing in is there anything more VEXING than checking the $cgi->checkbox ? . Which are you actually doing? Can you post actual runnable code, rather than just a one-line approximation of your code?

        That said, I changed the script I showed, using CGI.pm 4.51, to use -checked => 'on' instead of -checked => 'checked', and it still gave the HTML output that I showed above in this post. So it's not the difference between checked and on , as far as I can tell, either.

        I edited the perl lib module CGI.pm .

        Editing the module is probably the last thing I would have tried. And my experiments are still showing that given a specific call to CGI.pm's ->checkbox() method, CGI.pm outputs the correct HTML, so I cannot see a need for modifying it yet.

        The results of your editing experiment don't match with what I would expect, based on the runnable code I've provided. But since you don't show us the code that you used to run your experiments, there's nothing I can do to try to reproduce those results.

        Could you please return CGI.pm to its original state (in 4.51, or upgrade to a correct copy of 4.60 -- I don't care which, as long as you say which you chose in your reply), and try to run the exact code I posted, and see whether it works for you on your setup? If my exact script with the original CGI.pm (whether 4.51 or 4.60) behaves differently for you than it does for me, then could you please share perl -V results -- maybe you've got something different in your perl setup, which is causing behavior to change. On the other hand, if my exact script with the original CGI.pm behaves the same for you as it did for me, then you will need to investigate the difference between how my script calls things and how your script calls things, and see if you can narrow down the differences; if you need help with that, you will have to show short actually-runnable code (the SSCCE = "Short, Self-Contained, Correct Example" that I mentioned above) that shows the behavior that you see, in contrast to my short script which is working.

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