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

I've been working on a script using CGI.pm for which I need the 'nosticky' option. That is:
-nosticky By default the CGI module implements a state-preserving behavior called "sticky" fields. The way this works is that if you are regenerating a form, the methods that generate the form field values will interrogate param() to see if similarly-named parameters are present in the query string. If they find a like-named parameter, they will use it to set their default values. Sometimes this isn't what you want. The -nosticky pragma prevents this behavior. You can also selectively change the sticky behavior in each element that you generate.
I've seen a number of posts here and elsewhere complaining about it, and after a few hours of frustration I finally decided to dig through the code to figure out what was going wrong. As far as I can tell, the nosticky option does almost nothing. It's only referenced by the submit method, and has no effect even there if you supply a label for the submit button. The override option, on the other hand, does work. Unfortunately, you have to pass it to every output method instead of setting it globally. I wrote up a small test script to demonstrate the problem, and I've hosted a copy here
#!/usr/bin/env perl use strict; use warnings; use CGI qw/-nosticky :standard/; print header, html( start_form, checkbox( -nosticky => 1, -name => "checkbox", -label => "Broken (using nosticky)", -checked => 0 ), br, checkbox( -override => 1, -name => "checkbox", -label => "Working (using override)", -checked => 0 ), br, submit, end_form );
If you check both boxes and click Submit, the second one will correctly be cleared, but the first one will stay checked. It seems really odd that a feature that's been around for so long in such a prominent module could have been broken all this time, so I still feel like I must be doing something wrong, but I can't see what it would be.

Replies are listed 'Best First'.
Re: CGI.pm nosticky option does not work
by ikegami (Patriarch) on Jun 01, 2008 at 10:28 UTC

    It's poorly documented, but the goal of sticky is to preserve fields from past requests. It allows things like multi page forms. It has nothing to do with whether CGI gets the value of fields from param or not. That's controlled by override.

    If you want to override everything in one go, you could use

    $cgi->delete_all();

    Just be sure grab what you need from param first.

    Update: While trying to construct an example, I realized I was wrong.

    nosticky is just plain buggy. It's behaviour is completely different than the one documented. After studying the source, I've come to the conclusion that nosticky's *only* goal is to prevent the hidden field .cgifields from being created. That field is used to help make check boxes, check box groups, radio buttons and select lists sticky. CGI never intends nosticky to prevent anything from being sticky, so it will try to make those fields sticky even if .cgifields isn't present. Anything else if sticky regardless of nosticky.

        It's documented to prevent the state-preserving behaviour of interrogating param() to see if similarly-named parameters are present in the query.

        That's actually what it *should* do as far as I'm concerned, so the documentation is correct from that point of view.

        The problem is that it doesn't do that. At all.

        If it is deemed useful to have a flag to disable .cgifields from being created while preserving as much stickyness as required, that's fine, but it shouldn't be called nosticky.

Re: CGI.pm nosticky option does not work
by Anonymous Monk on Jun 01, 2008 at 05:39 UTC
    Your copy here is broken. Just hitting submit generates a server error.

    -nosticky is only an option for import, not for any generator functions. You can turn it on/off with CGI->sticky(1);

Re: CGI.pm nosticky option does not work
by Herkum (Parson) on Jun 01, 2008 at 05:50 UTC

    It has been a while since I have worked with CGI, but could it have something to do with the your using the same name with two different checkboxes?