[system] / trunk / pg / macros / parserRadioButtons.pl Repository:
ViewVC logotype

Diff of /trunk/pg/macros/parserRadioButtons.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 5556 Revision 5672
1################################################################################ 1################################################################################
2# WeBWorK Online Homework Delivery System 2# WeBWorK Online Homework Delivery System
3# Copyright 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ 3# Copyright 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/
4# $CVSHeader: webwork2/lib/WeBWorK.pm,v 1.100 2007/08/13 22:59:53 sh002i Exp $ 4# $CVSHeader: pg/macros/parserRadioButtons.pl,v 1.10 2007/10/04 16:40:49 sh002i Exp $
5# 5#
6# This program is free software; you can redistribute it and/or modify it under 6# This program is free software; you can redistribute it and/or modify it under
7# the terms of either: (a) the GNU General Public License as published by the 7# the terms of either: (a) the GNU General Public License as published by the
8# Free Software Foundation; either version 2, or (at your option) any later 8# Free Software Foundation; either version 2, or (at your option) any later
9# version, or (b) the "Artistic License" which comes with this package. 9# version, or (b) the "Artistic License" which comes with this package.
30where "choices" are the strings for the items in the radio buttons, 30where "choices" are the strings for the items in the radio buttons,
31"correct" is the choice that is the correct answer for the group, 31"correct" is the choice that is the correct answer for the group,
32and options are chosen from among: 32and options are chosen from among:
33 33
34=over 34=over
35
36=item C<S<< order => [choice,...] >>>
37
38Specifies the order in which choices should be presented. All choices must be
39listed. If this option is specified, the C<first> and C<last> options are
40ignored.
41
42=item C<S<< first => [choice,...] >>>
43
44Specifies choices which should appear first, in the order specified, in the list
45of choices. Ignored if the C<order> option is specified.
46
47=item C<S<< last => [choice,...] >>>
48
49Specifies choices which should appear last, in the order specified, in the list
50of choices. Ignored if the C<order> option is specified.
35 51
36=item C<S<< labels => [label1,...] >>> 52=item C<S<< labels => [label1,...] >>>
37 53
38Specifies the text to be used 54Specifies the text to be used
39as the student answer for each 55as the student answer for each
127 labels => [], 143 labels => [],
128 separator => $main::BR, 144 separator => $main::BR,
129 checked => undef, 145 checked => undef,
130 maxLabelSize => 25, 146 maxLabelSize => 25,
131 uncheckable => 0, 147 uncheckable => 0,
148 first => undef,
149 last => undef,
150 order => undef,
132 @_, 151 @_,
133 ); 152 );
134 $options{labels} = [1..scalar(@$choices)] if $options{labels} eq "123"; 153 $options{labels} = [1..scalar(@$choices)] if $options{labels} eq "123";
135 $options{labels} = [@main::ALPHABET[0..scalar(@$choices)-1]] if $options{labels} eq "ABC"; 154 $options{labels} = [@main::ALPHABET[0..scalar(@$choices)-1]] if $options{labels} eq "ABC";
136 my $self = bless {%options, choices=>$choices}, $class; # temporary to so we can call our methods 155 my $self = bless {%options, choices=>$choices}, $class; # temporary to so we can call our methods
145 $self = bless $context->Package("String")->new($context,$value)->with(choices => $choices, %options), $class; 164 $self = bless $context->Package("String")->new($context,$value)->with(choices => $choices, %options), $class;
146 $self->JavaScript if $self->{uncheckable}; 165 $self->JavaScript if $self->{uncheckable};
147 return $self; 166 return $self;
148} 167}
149 168
150# 169#
151# Locate the label of the correct answer 170# Given a choice, a label, or an index into the choices array,
152# The answer can be given as an index, as the full answer 171# return the label.
153# or as the label itself. 172#
154# 173sub findChoice {
155sub correctChoice {
156 my $self = shift; my $value = shift; 174 my $self = shift; my $value = shift;
157 my $index = $self->Index($value); 175 my $index = $self->Index($value);
158 foreach my $i (0..scalar(@{$self->{choices}})-1) { 176 foreach my $i (0..scalar(@{$self->{choices}})-1) {
159 my $label = $self->{labels}[$i]; my $choice = $self->{choices}[$i]; 177 my $label = $self->{labels}[$i]; my $choice = $self->{choices}[$i];
160 $label = $self->makeLabel($choice) unless defined $label; 178 $label = $self->makeLabel($choice) unless defined $label;
161 return $label if $label eq $value || $index == $i || $choice eq $value; 179 return $label if $label eq $value || $index == $i || $choice eq $value;
162 } 180 }
181}
182
183#
184# Locate the label of the correct answer
185# The answer can be given as an index, as the full answer
186# or as the label itself.
187#
188sub correctChoice {
189 my $self = shift; my $value = shift;
190 my $choice = $self->findChoice($value);
191 return $choice if defined $choice;
163 Value::Error("The correct answer should be one of the button choices"); 192 Value::Error("The correct answer should be one of the button choices");
164} 193}
165 194
166# 195#
167# Create the hash of label => answer pairs to be used for the 196# Create the hash of label => answer pairs to be used for the
244 my @radio = @_; 273 my @radio = @_;
245 foreach (@radio) {$_ =~ s/<INPUT/<INPUT $onclick/i} 274 foreach (@radio) {$_ =~ s/<INPUT/<INPUT $onclick/i}
246 return @radio; 275 return @radio;
247} 276}
248 277
278#
279# Determine the order the choices should be in.
280#
281sub orderedChoices {
282 my $self = shift;
283 my %choiceHash = $self->choiceHash;
284 my @labels = keys %choiceHash;
285
286 my @order = @{$self->{order}};
287 my @first = @{$self->{first}};
288 my @last = @{$self->{last}};
289
290 my @orderLabels;
291
292 if (@order) {
293 my %remainingChoices = %choiceHash;
294 Value::Error("When using the 'order' option, you must list all possible choices.")
295 unless @order == @labels;
296 foreach my $i (0..$#order) {
297 my $label = $self->findChoice($order[$i]);
298 Value::Error("Item $i of the 'order' option is not a choice.")
299 if not defined $label;
300 Value::Error("Item $i of the 'order' option was already specified.")
301 if not exists $remainingChoices{$label};
302 push @orderLabels, $label;
303 delete $remainingChoices{$label};
304 }
305 } elsif (@first or @last) {
306 my @firstLabels;
307 my @lastLabels;
308 my %remainingChoices = %choiceHash;
309
310 foreach my $i (0..$#first) {
311 my $label = $self->findChoice($first[$i]);
312 Value::Error("Item $i of the 'first' option is not a choice.")
313 if not defined $label;
314 Value::Error("Item $i of the 'first' option was already specified.")
315 if not exists $remainingChoices{$label};
316 push @firstLabels, $label;
317 delete $remainingChoices{$label};
318 }
319
320 foreach my $i (0..$#last) {
321 my $label = $self->findChoice($last[$i]);
322 Value::Error("Item $i of the 'last' option is not a choice.")
323 if not defined $label;
324 Value::Error("Item $i of the 'last' option was already specified.")
325 if not exists $remainingChoices{$label};
326 push @lastLabels, $label;
327 delete $remainingChoices{$label};
328 }
329
330 @orderLabels = (@firstLabels, keys %remainingChoices, @lastLabels);
331 } else {
332 # use the order of elements in the hash
333 # this is the current behavior
334 # might we want to explicitly randomize these?
335 @orderLabels = @labels;
336 }
337
338 return map { $_ => $choiceHash{$_} } @orderLabels;
339}
340
249# 341#
250# Create the radio-buttons text 342# Create the radio-buttons text
251# 343#
252sub buttons { 344sub buttons {
253 my $self = shift; 345 my $self = shift;
254 my @radio = main::ans_radio_buttons($self->choiceHash); 346 my @radio = main::ans_radio_buttons($self->orderedChoices);
255 @radio = $self->makeUncheckable(@radio) if $self->{uncheckable}; 347 @radio = $self->makeUncheckable(@radio) if $self->{uncheckable};
256 (wantarray) ? @radio : join($self->{separator}, @radio); 348 (wantarray) ? @radio : join($self->{separator}, @radio);
257} 349}
258sub named_buttons { 350sub named_buttons {
259 my $self = shift; my $name = shift; 351 my $self = shift; my $name = shift;
260 my @radio = NAMED_ANS_RADIO_BUTTONS($name,$self->choiceHash); 352 my @radio = NAMED_ANS_RADIO_BUTTONS($name,$self->orderedChoices);
261 @radio = $self->makeUncheckable(@radio) if $self->{uncheckable}; 353 @radio = $self->makeUncheckable(@radio) if $self->{uncheckable};
262 # 354 #
263 # Taken from PGbasicmacros.pl 355 # Taken from PGbasicmacros.pl
264 # It is wrong to have \item in the radio buttons and to add itemize here, 356 # It is wrong to have \item in the radio buttons and to add itemize here,
265 # but that is the way PGbasicmacros.pl does it. 357 # but that is the way PGbasicmacros.pl does it.

Legend:
Removed from v.5556  
changed lines
  Added in v.5672

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9