Checkboxes in polls may be given upper or lower limits. e.g., "choose 
your top five...", "choose at least...", "choose at most..."

        Patch by jportela. 

diffs (293 lines):

diff -r 740a768a0adc -r 248c0978b595 bin/upgrading/en.dat
--- a/bin/upgrading/en.dat      Wed Sep 08 19:55:24 2010 +0800
+++ b/bin/upgrading/en.dat      Wed Sep 08 20:13:40 2010 +0800
@@ -2333,6 +2333,14 @@ poll.error.cantview=Error: you don't hav
 
 poll.error.cantvote=Sorry, you don't have permission to vote in this 
particular poll.
 
+poll.error.checkfewoptions=You must select at least <b>[[options]]</b> options 
in question <b>#[[question]]</b>, or you can choose to skip it.
+
+poll.error.checkmaxtoolow=Checkmax attribute must be higher than Checkmin 
attribute.
+
+poll.error.checkmintoolow=Checkmin attribute must be positive.
+
+poll.error.checktoomuchoptions=You can only select up to <b>[[options]]</b> in 
question <b>#[[question]]</b>.
+
 poll.error.missingljpoll=All lj-pq tags must be nested inside an enclosing 
lj-poll tag.
 
 poll.error.missingljpq=All lj-pi tags must be nested inside an enclosing lj-pq 
tag.
diff -r 740a768a0adc -r 248c0978b595 cgi-bin/LJ/Poll.pm
--- a/cgi-bin/LJ/Poll.pm        Wed Sep 08 19:55:24 2010 +0800
+++ b/cgi-bin/LJ/Poll.pm        Wed Sep 08 20:13:40 2010 +0800
@@ -326,6 +326,26 @@ sub new_from_html {
                     }
 
                     $qopts{'opts'} = "$size/$max";
+                }
+                if ($qopts{'type'} eq "check") {
+                    my $checkmin = 0;
+                    my $checkmax = 255;
+                    
+                    if (defined $opts->{'checkmin'}) {
+                        $checkmin = int($opts->{'checkmin'});
+                    }
+                    if (defined $opts->{'checkmax'}) {
+                        $checkmax = int($opts->{'checkmax'});
+                    }
+                    if ($checkmin < 0) {
+                        return $err->('poll.error.checkmintoolow');
+                    }
+                    if ($checkmax < $checkmin) {
+                        return $err->('poll.error.checkmaxtoolow');
+                    }
+
+                    $qopts{'opts'} = "$checkmin/$checkmax";
+                    
                 }
                 if ($qopts{'type'} eq "scale")
                 {
@@ -942,7 +962,29 @@ sub render {
         my $qid = $q->pollqid;
         my $text = $q->text;
         LJ::Poll->clean_poll(\$text);
-        $results_table .= "<p>$text</p><div style='margin: 10px 0 10px 40px'>";
+        $results_table .= "<p>$text</p>";
+        
+        # shows how many options a user must/can choose if that restriction 
applies
+        if ($q->type eq 'check' && $do_form) {
+            my ($mincheck, $maxcheck) = split(m!/!, $q->opts);
+            $mincheck ||= 0;
+            $maxcheck ||= 255;
+            
+            if ($mincheck > 0 && $mincheck eq $maxcheck ) {
+                $results_table .= "<i>You must choose exactly <b>" . $mincheck 
. "</b> options</i><br />\n";
+            }
+            else {
+                if ($mincheck > 0) {
+                    $results_table .= "<i>You must choose at least <b>" . 
$mincheck . "</b> options</i><br />\n";
+                }
+            
+                if ($maxcheck < 255) {
+                    $results_table .= "<i>You can choose up to <b>" . 
$maxcheck . "</b> options</i><br />\n";
+                }
+            }
+        }
+        
+        $results_table .= "<div style='margin: 10px 0 10px 40px'>";
 
         ### get statistics, for scale questions
         my ($valcount, $valmean, $valstddev, $valmedian);
@@ -1303,6 +1345,8 @@ sub process_submission {
     my $error = shift;
     my $sth;
 
+    my $error_code = 1;
+
     my $remote = LJ::get_remote();
 
     unless ($remote) {
@@ -1369,6 +1413,22 @@ sub process_submission {
         if ($q->type eq "check") {
             ## multi-selected items are comma separated from 
htdocs/poll/index.bml
             $val = join(",", sort { $a <=> $b } split(/,/, $val));
+            if (length($val) > 0) { # if the user answered to this question
+                my $num_opts = split(/,/, $val);    # returns the number of 
options they answered
+                
+                my ($checkmin, $checkmax) = split(m!/!, $q->opts);
+            
+                if($num_opts < $checkmin) {
+                    $$error = LJ::Lang::ml('poll.error.checkfewoptions', 
{'question' => $qid, 'options' => $checkmin});
+                    $error_code = 2;
+                    $val = "";
+                }
+                if($num_opts > $checkmax) {
+                    $$error = LJ::Lang::ml('poll.error.checktoomuchoptions', 
{'question' => $qid, 'options' => $checkmax});
+                    $error_code = 2;
+                    $val = "";
+                }
+            }
         }
         if ($q->type eq "scale") {
             my ($from, $to, $by) = split(m!/!, $q->opts);
@@ -1399,7 +1459,7 @@ sub process_submission {
     LJ::Event::PollVote->new($poll->poster, $remote, $poll)->fire
         if $ct;
 
-    return 1;
+    return $error_code;
 }
 
 sub dump_poll {
diff -r 740a768a0adc -r 248c0978b595 cgi-bin/LJ/Poll/Question.pm
--- a/cgi-bin/LJ/Poll/Question.pm       Wed Sep 08 19:55:24 2010 +0800
+++ b/cgi-bin/LJ/Poll/Question.pm       Wed Sep 08 20:13:40 2010 +0800
@@ -78,6 +78,24 @@ sub preview_as_html {
         LJ::Poll->clean_poll(\$qtext);
           $ret .= "<p>$qtext</p>\n";
       }
+      if ($type eq 'check') {
+          my ($mincheck, $maxcheck) = split(m!/!, $opts);
+          $mincheck ||= 0;
+          $maxcheck ||= 255;
+          
+          if ($mincheck > 0 && $mincheck eq $maxcheck ) {
+              $ret .= "<i>You must choose exactly <b>" . $mincheck . "</b> 
options</i><br />\n";
+          }
+          else {
+              if ($mincheck > 0) {
+                  $ret .= "<i>You must choose at least <b>" . $mincheck . 
"</b> options</i><br />\n";
+              }
+
+              if ($maxcheck < 255) {
+                  $ret .= "<i>You can choose up to <b>" . $maxcheck . "</b> 
options</i><br />\n";
+              }
+         }
+    }
     $ret .= "<div style='margin: 10px 0 10px 40px'>";
 
     # text questions
diff -r 740a768a0adc -r 248c0978b595 htdocs/poll/create.bml
--- a/htdocs/poll/create.bml    Wed Sep 08 19:55:24 2010 +0800
+++ b/htdocs/poll/create.bml    Wed Sep 08 20:13:40 2010 +0800
@@ -56,6 +56,10 @@ _c?>
                   "to" => 10,             # default to value for a scale
                   "by" => 1,             # default by value for a scale
                   "maxitems" => 20,         # maximum number of items allowed 
in a scale
+              },
+              "checkbox" => {
+                  "checkmin" => 0,      # number of checkboxes a user must 
tick in that question (default 0: no limit)  
+                  "checkmax" => 255,    # maximum number of checkboxes a user 
is allowed to tick in that question
               },
               );
 
@@ -176,7 +180,7 @@ _c?>
             my $qrec = {};
 
             # validate question attributes
-            foreach my $atr (qw(type question opts size maxlength from to by)) 
{
+            foreach my $atr (qw(type question opts size maxlength from to by 
checkmin checkmax)) {
                 my $val = $POST{"pq_${q}_$atr"};
                 next unless defined $val;
 
@@ -246,6 +250,12 @@ _c?>
 
                     next;
                 }
+                
+                if ($atr eq 'checkmin') {
+                    $qrec->{'checkmin'} = int($POST{"pq_${q}_checkmin"}) || 0;
+                    $qrec->{'checkmax'} = int($POST{"pq_${q}_checkmax"}) || 
255;
+                    next;
+                }
 
                 # otherwise, let it by.
                 $qrec->{$atr} = $val;
@@ -261,17 +271,31 @@ _c?>
                 if (length($POST{"pq_${q}_opt_$o"}) > 
$RULES{'items'}->{'maxlength'}) {
                     $qrec->{'opt'}->[$o] = substr($POST{"pq_${q}_opt_$o"}, 0, 
$RULES{'items'}->{'maxlength'});
                     $err->{$q}->{$o}->{'items'} = $ML{'.error.texttoobig'};
-                } else {
+                    $num_opts++;
+                } elsif (length($POST{"pq_${q}_opt_$o"}) > 0){
                     # no change necessary
                     $qrec->{'opt'}->[$o] = $POST{"pq_${q}_opt_$o"};
+                    $num_opts++;
                 }
-
-                $num_opts++;
             }
 
             # too few options specified?
             if ($num_opts < $RULES{'items'}->{'min'} && $qrec->{'type'} =~ 
/^(drop|check|radio)$/) {
                 $err->{$q}->{'items'} = $ML{'.error.allitemsblank'};
+            }
+
+            # checks if minimum and maximum options for checkboxes are OK
+            
+            if ($qrec->{'type'} == 'check') {
+                my $checkmin = $qrec->{'checkmin'};
+                if ($checkmin > $num_opts) {
+                    $err->{$q}->{'checkmin'} = $ML{'.error.checkmintoohigh'};
+                }
+                
+                my $checkmax = $qrec->{'checkmax'};
+                if ($checkmax < $checkmin) {
+                    $err->{$q}->{'checkmax'} = $ML{'.error.checkmaxtoolow'};
+                }
             }
         }
 
@@ -527,6 +551,20 @@ _c?>
                 $ret .= $elem->{'opts'} < $RULES{'items'}->{'max'}
                     ? "<br />" . LJ::html_submit("request:$q:do", undef, { 
'raw' => " value='More &gt;&gt;'" }) . "\n"
                     : "<br /><?de [$ML{'.options.limitreached'}] de?>\n";
+                
+                if ($elem->{'type'} eq 'check') {
+                    $ret .= "<br/>";
+                    foreach my $atr ( qw(checkmin checkmax) ) {
+                        $ret .= $ML{"." . $atr};
+                        $ret .= LJ::html_text({ 'name' => "pq_${q}_$atr",
+                                                'value' => defined 
$elem->{$atr} ? $elem->{$atr} : $RULES{'checkbox'}->{$atr},
+                                                'size' => '3', 'maxlength' => 
'9' }) . "\n";
+                    }                           
+                    foreach my $atr ( qw(checkmin checkmax) ) {
+                       $ret .= "<br /><font 
size='1'><b>[$err->{$q}->{$atr}]</b></font>\n"
+                            if $err->{$q}->{$atr};
+                    }
+                } 
 
             # text type
             } elsif ($elem->{'type'} eq 'text') {
@@ -602,6 +640,10 @@ _c?>
                     foreach my $el ( qw(from to by) ) {
                         $ret .= " $el='" . LJ::ehtml($elem->{$el}) . "'";
                     }
+                } elsif ($elem->{'type'} eq 'check') {
+                     foreach my $el ( qw(checkmin checkmax) ) {
+                         $ret .= " $el='" . LJ::ehtml($elem->{$el}) . "'";
+                     }
                 }
                 $ret .= ">\n";
                 $ret .= $elem->{'question'} . "\n" if $elem->{'question'};
diff -r 740a768a0adc -r 248c0978b595 htdocs/poll/create.bml.text
--- a/htdocs/poll/create.bml.text       Wed Sep 08 19:55:24 2010 +0800
+++ b/htdocs/poll/create.bml.text       Wed Sep 08 20:13:40 2010 +0800
@@ -11,6 +11,10 @@
 
 .button.startover=Start Over
 
+.checkmin=Minimum options required: 
+
+.checkmax=Maximum options accepted: 
+
 .elements.limitreached=Element limit reached
 
 .error.accttype=Your account type does not permit you to use the poll creation 
feature.
@@ -18,6 +22,10 @@
 .error.accttype2=Your account type does not permit you to use the poll 
creation feature.
 
 .error.allitemsblank=All items cannot be blank.
+
+.error.checkmintoohigh=Minimum value for checkbox options is too high
+
+.error.checkmaxtoolow=Maximum value for checkbox options is too low
 
 .error.notext=You need text explaining your question
 
diff -r 740a768a0adc -r 248c0978b595 htdocs/poll/index.bml
--- a/htdocs/poll/index.bml     Wed Sep 08 19:55:24 2010 +0800
+++ b/htdocs/poll/index.bml     Wed Sep 08 20:13:40 2010 +0800
@@ -111,7 +111,12 @@ _c?>
         }
 
         my $error;
-        LJ::Poll->process_submission(\%FORM, \$error);
+        my $error_code = LJ::Poll->process_submission(\%FORM, \$error);
+        if ($error_code eq 2) {
+            $body .= $poll->render(mode => "enter");    
+            $body .= $error;
+            return;
+        }
         if ($error) {
             $title = $ML{'Error'};
             $body .= $error;
_______________________________________________
dw-changelog mailing list
[email protected]
http://lists.dwscoalition.org/mailman/listinfo/dw-changelog

Reply via email to