2 A tristate checkbox (with three values: true, false, and null).
3 Internally, this creates a checkbox, coupled via javascript to a hidden
4 field that actually contains the value. For now, the only values these
5 can have are 1, -1, and empty. Clicking the checkbox cycles between them.
7 For compatibility with regular checkboxes, empty is the false state and
8 -1 is the indeterminate state.
10 Displaying these is a problem. "indeterminate" is a standard HTML5 attribute
11 but some browsers display it in unhelpful ways (e.g. Firefox slightly grays
12 the checkbox, approximately #dddddd), and checkboxes ignore nearly all CSS
26 input.partial + label::before {
30 input.partial:checked + label::before {
33 input.partial:indeterminate + label::before {
37 <SCRIPT TYPE="text/javascript">
38 function tristate_onclick() {
40 var input = checkbox.input;
41 if ( input.value == "" ) { // false -> true
43 checkbox.checked = true;
44 checkbox.indeterminate = false;
45 } else if ( input.value == "1" ) { // true -> indeterminate
47 checkbox.checked = false;
48 checkbox.indeterminate = true;
49 } else if ( input.value == "-1" ) { // indeterminate -> false
51 checkbox.checked = false;
52 checkbox.indeterminate = false;
57 var tristate_boxes = [];
58 window.onload = function() { // don't do this until all of the checkboxes exist
59 %# tristates = document.getElementsByClassName('tristate'); # curse you, IE8
60 var all_inputs = document.getElementsByTagName('input');
61 for (var i=0; i < all_inputs.length; i++) {
62 if ( all_inputs[i].className == 'tristate' ) {
63 tristates.push(all_inputs[i]);
66 for (var i=0; i < tristates.length; i++) {
68 document.getElementById('checkbox_' + tristates[i].name);
69 // make sure they can find each other
70 tristate_boxes[i].input = tristates[i];
71 tristates[i].checkbox = tristate_boxes[i];
73 tristate_boxes[i].onclick = tristate_onclick;
75 if ( tristates[i].value == "-1" ) {
76 tristate_boxes[i].indeterminate = true
78 if ( tristates[i].value == "1" ) {
79 tristate_boxes[i].checked = true;
85 <INPUT TYPE="hidden" NAME="<% $opt{field} %>"
87 VALUE="<% $curr_value %>"
89 <INPUT TYPE="checkbox" ID="checkbox_<%$opt{field}%>" CLASS="partial">
95 # might be useful but I'm not implementing it yet
96 #my $onchange = $opt{'onchange'}
97 # ? 'onChange="'. $opt{'onchange'}. '(this)"'
100 $opt{'id'} ||= 'hidden_'.$opt{'field'};
101 my $curr_value = '-1';
102 if (exists $opt{curr_value}) {
103 $curr_value = $opt{curr_value};
104 $curr_value = '' unless $curr_value eq '-1' or $curr_value eq '1';