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

Beating my brow I ask the breathren the following: I have remade my news page script so that the text file no longer contains table rows. This has simplified displaying individual posts (which are seperated by 3 newlines in the txt file) for my Delete_A_Post form.
However, I am having a heck of a time making $_ the value of the checkboxes since $_ contains double quotes. If I clean out the quotes with a regex, I screw the html contained in $_. I could ditch the ability to set font face for each post which would let me rid the posts of the double quotes but I have been scolded for not quoting my values and so I wish to be good.The code I am currently using to create the text boxes follows, but I think the problem is not there so much as it is with my txt file contents.
Advice will be greeted with knishes!
TIA
jg
print qq|Delete This Post? \n <input type=checkbox name="box$post_number" value=" $_ "<p +> $_<hr>\n<p>\n<br><br><br>\n|;
_____________________________________________________
If it gets a little bit out of hand sometimes, don't let it fool you into thinkin' you don't care.TvZ
  • Comment on Loading $_ as checkbox value when $_ has double quotes in its value
  • Download Code

Replies are listed 'Best First'.
(ar0n) Re: Loading $_ as checkbox value when $_ has double quotes in its value
by ar0n (Priest) on Dec 04, 2001 at 11:23 UTC
    s/"/&quot;/g; s/'/&apos;/g; print qq|<input type="checkbox" name="box$post_number" value="$_">|;

    This works for both double as well as single quotes.

    update: Err, no. It will render normally. Since &apos; and &quot; are simply entities browsers should render (as form values and as text), so dws' example where he assigns $_ to another variable isn't necessary at all.

    [ ar0n -- want job (boston) ]

      ar0n,
      Won't doing it that way screw the HTML? I mean it escapes the quotes around the font face for instance, no? Jeez it is too late for rational thought, I'll try it in the morning. Thx!
      jg
      _____________________________________________________
      If it gets a little bit out of hand sometimes, don't let it fool you into thinkin' you don't care.TvZ
        Won't doing it that way screw the HTML?

        In that case don't make $_ do double-duty. Instead, try

        my $dequoted = $_; $dequoted =~ s/"/&quot;/g; print qq|<input type="checkbox" name="box$post_number" value="$dequote +d">|;
Re: Loading $_ as checkbox value when $_ has double quotes in its value
by George_Sherston (Vicar) on Dec 04, 2001 at 17:17 UTC
    I'm surprised nobody has suggested using CGI.pm. CGI does the work so you have more time to drink beer! In this case, as well as catching typos like the one dws points out, it also handles the quoting problem. I think this does what you want:
    #!/usr/bin/perl -w use strict; use CGI qw(:standard); $_ = 'I am a "Perl" Monk'; my $post_number = 5; print header, start_html, 'Delete This Post?', checkbox( -name => 'box' . $post_number, -value => $_, -label =>'', ), '<p>',$_,hr, end_html;
    (You need the -label argument because the default is to print -name next to the box.)

    Produces the following html (headers deleted for clarity) (although, of course, automatic header generation is part of the fun):
    <head><title>Untitled Document</title></head><body> Delete This Post? <input type="checkbox" name="box5" value="I am a &quot;Perl&quot; Monk +" /> <p>I am a "Perl" Monk<hr></body></html></hr>


    § George Sherston

      Definitely. Reason #1551 to use CGI or die;

      You can also consider putting the 'Delete This Post?' as the -label attribute for the checkbox. That's kind of what it's for.

Re: Loading $_ as checkbox value when $_ has double quotes in its value
by dws (Chancellor) on Dec 04, 2001 at 11:14 UTC
    For starters, the fragment you posted won't produce valid HTML. The <input... tag isn't terminated.

    If you're reasonably sure $_ won't contain single quotes, you can try

    print qq|Delete This Post? \n <input type=checkbox name="box$post_number" value=' $_ ' +<p> $_<hr>\n<p>\n<br><br><br>\n|;
Re: Loading $_ as checkbox value when $_ has double quotes in its value
by hakkr (Chaplain) on Dec 04, 2001 at 16:01 UTC

    Don't quote your output at all print "stuff";

    Use a here document instead then you can put anything you fancy in it.

    print <<HTML; Delete This Post? \n <input type=checkbox name="box$post_number" value=" $_ "<p +> $_<hr>\n<p>\n<br><br><br>\n|; HTML
      hakkr, afaiui that isn't the problem. The problem is that, if $_ contains doublequotes, then this
      $_ = qq|sheep go "baaa"|; print qq|<input value="$_">|;
      will output this:
      <input value="sheep go "baaaa"">
      where the value attribute = "sheep go" and "baaa"" is disregarded.

      That's my understanding - I could have the wrong end of the stick.
      andy.

        That's exactly the problem BUT it can be over come by simply using the regex solution twice, once to prepare the var for being a checkbox value and then reversing it to print the HTML back to the txt file. Dumpdadah! Yay!
        Thanks again and again guys! Where would I be without ya?
        jg
        _____________________________________________________
        If it gets a little bit out of hand sometimes, don't let it fool you into thinkin' you don't care.TvZ
Re: Loading $_ as checkbox value when $_ has double quotes in its value
by jerrygarciuh (Curate) on Dec 05, 2001 at 09:16 UTC
    OK, Now I got a beautiful form with appropriate checkbox values. To those who have re-asserted my need to understand CGI.pm I agree and the Mouse is in the mail to me now, the Rat was less than helpful.
    Problem is that I can't seem to figure why I end up with an empty array no matter whether boxes are checked or not. I am assuming the array is empty cause I always end up with an empty txt file after I submit the form. 0 bytes in size it is. Have I made yet another dopey neophyte error?
    Thanks again, and again, and.....
    jg
    #!/usr/bin/perl -w use strict; use CGI; use CGI ':standard'; use CGI::Carp qw/fatalsToBrowser /; my $q = CGI->new(); my $url="http://www.xxxxx.com/xxx/xxx/"; my $path_to_text="/home/xxxxx/www/xxx/xxx/body.txt"; my $this_script_url="http://www.xxxxxx.com/cgi-bin/xxxxx.cgi"; my $post_number; my @updated_text; $/="\n\n\n"; #set the input Record seperator to a tri +ple newline if ( $q->param() ) { #if params are not undef # ignore deleted next if ( $q->param("box$post_number") ); # keep the rest s/&quot;/"/g; s/&apos;/'/g; push @updated_text, $_; # now update file open(FH,">$path_to_text") || die $!; print FH join "\n\n\n", @updated_text; close(FH); print "Location: $url\n\n"; } else { #if params are undef open (FH, "$path_to_text") or die "where's the damn file? : $!"; print "Content-type: text/html\n\n"; print qq|<HTML><BODY><center><form method="post" action="$this_scr +ipt_url">\n <TABLE width=600><TR bgcolor=#000066><TD colspan=2 align=c +enter> <font color=#ffffff><h2>Edit Your Posts</h2></font></TD><T +R><TD>|; while (<FH>) { next if /^\n+$/; #ignore lines which contains + only newlines $post_number++; chomp; s/"/&quot;/g; s/'/&apos;/g; print qq|Delete This Post? \n <input type=checkbox name="box$post_number" value=" $_ " c +hecked><p> $_<hr>\n<p>\n<br><br><br>\n|; } close FH; print "</TD></TR><TR bgcolor=#333333><TD align=center colspan=2> +\n"; print "<input type=submit name=Submit value=\"Delete Checked Pos +ts\"></TD>"; print "</form></center></table></body></html>"; } exit;
    _____________________________________________________
    If it gets a little bit out of hand sometimes, don't let it fool you into thinkin' you don't care.TvZ
      From your program:
      if ( $q->param() ) { #if params are not undef # ignore deleted next if ( $q->param("box$post_number") );
      Here your code checks to see if there are any params, which is good, but the next line is an out-of-place next. You don't have any logic in place to loop through the individual params themselves. $q->params() contains only the names of all the checkboxes which were selected (checked) along with your submit button value and anything else in the form. When you are at this point in the script (after submit), you don't know which checkboxes are going to be in $q->params(), if any.

      Therefore you need to examine $q->params(), look at the checkbox values and associate them with the appropriate "post" text in your file. Here's a little bit of code that I hope will get you started:

      # Pull out the numbers of the checkboxes that were selected. # e.g. If box1, box3 and box12 were selected, @selected = (1, 3, 12) my @selected = grep { $_=$1 if /^box(\d+)/; } $q->params(); open FH, $filename or die "Can't read $filename, $!"; # open for read my @posts = <FH>; # This should delete the post text associated with each selected check +box # You have to use the @selected array in reverse. I leave the # explanation for this as an exercise for you. :) splice @posts, ($_ - 1), 1 for reverse @selected; # Now write the file back out again open FH, ">$filename" or die "Can't write to $filename, $!"; print FH @posts or die "Couldn't write to file, $!"; close FH or die "Can't close file etc, $!";

      BTW I think you need to use &#039; rather than ' when encoding single quotes. ' is an XML character entity.

      Having just written code for handling selections of things for a recent job, I was curious about your code when I saw the posting. I took a different tact, though, but a few thoughts that might help.

      First of all, my understanding of CGI.pm's handling of checkboxes is that if in your form you have a set of checkboxes named "boxes" such as <input type=checkbox name=boxes value="whatever" checked> , $q->param("boxes") returns a list of the values for the input boxes checked (including "whatever" for this one, unless unchecked). So you might do something like @todelete = $q->param("boxes"); then loop thru them.

      Also, you might consider testing if $q->param("submit") is defined, then go from there, rather than seeing if any parameters are defined.

      (I also posted a link to this response in your followup article, Shouldn't this return the named checkbox's value? )