Index: trunk/extensions/SemanticForms/includes/SF_FormPrinter.inc |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | class SFFormPrinter { |
12 | 12 | |
13 | 13 | function formHTML($form_def, $form_submitted, $source_is_page, $existing_page_content = null, $page_title = null) { |
14 | | - global $wgRequest, $wgUser; |
| 14 | + global $wgRequest, $wgUser, $wgParser; |
15 | 15 | global $gTabIndex; // used to represent the current tab index in the form |
16 | 16 | global $gDisabledText; // disables all form elements if user doesn't have edit permission |
17 | 17 | |
— | — | @@ -72,8 +72,10 @@ |
73 | 73 | $instance_num = 0; |
74 | 74 | $all_instances_printed = false; |
75 | 75 | $strict_parsing = false; |
76 | | - $autocomplete_value_array = array(); |
77 | | - $autocomplete_value_array['mappings'] = array(); |
| 76 | + $autocomplete_values = array(); |
| 77 | + $autocomplete_values['mappings'] = array(); |
| 78 | + // initialize list of choosers (dropdowns with available templates) |
| 79 | + $choosers = array(); |
78 | 80 | for ($section_num = 0; $section_num < count($form_def_sections); $section_num++) { |
79 | 81 | $tif = new SFTemplateInForm(); |
80 | 82 | $start_position = 0; |
— | — | @@ -92,7 +94,9 @@ |
93 | 95 | $template_name = trim($tag_components[1]); |
94 | 96 | $tif->template_name = $template_name; |
95 | 97 | $query_template_name = str_replace(' ', '_', $template_name); |
96 | | - // cycle through the other components |
| 98 | + $chooser_name = false; |
| 99 | + $chooser_caption = false; |
| 100 | + // cycle through the other components |
97 | 101 | for ($i = 2; $i < count($tag_components); $i++) { |
98 | 102 | $component = $tag_components[$i]; |
99 | 103 | if ($component == 'multiple') $allow_multiple = true; |
— | — | @@ -102,11 +106,23 @@ |
103 | 107 | if ($sub_components[0] == 'label') { |
104 | 108 | $template_label = $sub_components[1]; |
105 | 109 | } |
| 110 | + if ($sub_components[0] == 'chooser') { |
| 111 | + $allow_multiple = true; |
| 112 | + $chooser_name = $sub_components[1]; |
| 113 | + } |
| 114 | + if ($sub_components[0] == 'chooser caption') { |
| 115 | + $chooser_caption = $sub_components[1]; |
| 116 | + } |
106 | 117 | } |
107 | 118 | } |
108 | 119 | // if this is the first instance, add the label in the form |
109 | 120 | if (($old_template_name != $template_name) && isset($template_label)) { |
110 | | - $form_text .= "<fieldset>\n"; |
| 121 | + // add a placeholder to the form text so the fieldset can be |
| 122 | + // hidden if chooser support demands it |
| 123 | + if ($chooser_name !== false) |
| 124 | + $form_text .= "<fieldset [[placeholder]] haschooser=true>\n"; |
| 125 | + else |
| 126 | + $form_text .= "<fieldset>\n"; |
111 | 127 | $form_text .= "<legend>$template_label</legend>\n"; |
112 | 128 | } |
113 | 129 | $template_text .= "{{" . $tif->template_name; |
— | — | @@ -216,6 +232,10 @@ |
217 | 233 | $allow_multiple = false; |
218 | 234 | $all_instances_printed = false; |
219 | 235 | $instance_num = 0; |
| 236 | + // if the hiding placeholder is still around, this fieldset should |
| 237 | + // be hidden because it is empty and choosers are being used. So, |
| 238 | + // hide it. |
| 239 | + $form_text = str_replace("[[placeholder]]", "style='display:none'", $form_text); |
220 | 240 | } elseif ($tag_title == 'field') { |
221 | 241 | $field_name = trim($tag_components[1]); |
222 | 242 | // cycle through the other components |
— | — | @@ -369,7 +389,7 @@ |
370 | 390 | $input_name = $query_template_name . '[' . $field_name . ']'; |
371 | 391 | $new_text = SFFormPrinter::formTemplateFieldHTML($field_name, $input_name, $allow_multiple, |
372 | 392 | $cur_value, $is_mandatory, $is_hidden, $is_restricted, $input_type, $size, $num_rows, $num_cols, $no_autocomplete, |
373 | | - $autocomplete_category, $all_fields, $strict_parsing, $autocomplete_value_array); |
| 393 | + $autocomplete_category, $all_fields, $strict_parsing, $autocomplete_values); |
374 | 394 | |
375 | 395 | // if this was field was disabled due to being 'restricted', |
376 | 396 | // restore $gDisabledText back to its actual value, and add |
— | — | @@ -440,6 +460,9 @@ |
441 | 461 | END; |
442 | 462 | // this will cause the section to be re-parsed on the next go |
443 | 463 | $section_num--; |
| 464 | + // because there is an instance, the fieldset will never be hidden, |
| 465 | + // even if choosers are being used. So, do not hide the fieldset. |
| 466 | + $form_text = str_replace("[[placeholder]]", "", $form_text); |
444 | 467 | } else { |
445 | 468 | // this is the last instance of this template - stick an 'add' |
446 | 469 | // button in the form |
— | — | @@ -456,6 +479,10 @@ |
457 | 480 | <p><input type="button" onclick="addInstance('starter_$query_template_name', 'main_$query_template_name', '$gTabIndex');" value="$add_another" tabindex="$gTabIndex" /></p> |
458 | 481 | |
459 | 482 | END; |
| 483 | + // if a chooser is being used for this template, add the template |
| 484 | + // to the chooser data array |
| 485 | + if ($chooser_name !== false) |
| 486 | + $choosers[$chooser_name][]= array($query_template_name, $gTabIndex, $chooser_caption); |
460 | 487 | } |
461 | 488 | } else { |
462 | 489 | $form_text .= $section; |
— | — | @@ -492,6 +519,86 @@ |
493 | 520 | $form_text = str_replace('<free_text>', $free_text, $form_text); |
494 | 521 | $data_text = str_replace('<free_text>', $free_text, $data_text); |
495 | 522 | |
| 523 | + //Substitute the choosers in here too. |
| 524 | + $chooser_count = 0; |
| 525 | + $chooser_text = ""; |
| 526 | + $using_choosers = "false"; |
| 527 | + foreach ($choosers as $choosername => $chooser) { |
| 528 | + if (count($chooser)!=0) { |
| 529 | + $chooser_count++; |
| 530 | + if ($chooser_count==1) { |
| 531 | + // emit the initial javascript code |
| 532 | + $using_choosers = "true"; |
| 533 | + $chooser_text .= <<<END |
| 534 | +<script type="text/javascript"> |
| 535 | +function updatechooserbutton(f,n) |
| 536 | +{ |
| 537 | + document.getElementById(n).disabled = (f.options[f.selectedIndex].value=="invalid"); |
| 538 | +} |
| 539 | + |
| 540 | +function addInstanceFromChooser(chooserid) |
| 541 | +{ |
| 542 | + var chooser = document.getElementById(chooserid); |
| 543 | + var optionstring = chooser.options[chooser.selectedIndex].value; |
| 544 | + var pos = optionstring.indexOf(","); |
| 545 | + var tabindex = optionstring.substr(0,pos); |
| 546 | + var chooservalue = optionstring.substr(pos+1); |
| 547 | + addInstance('starter_' + chooservalue, 'main_' + chooservalue, parseInt(tabindex)); |
| 548 | +} |
| 549 | + |
| 550 | +//The fieldset containing the given element was just updated. If the fieldset is associated with a chooser, |
| 551 | +//ensure that the fieldset is hidden if and only if there are no template instances inside. |
| 552 | +function hideOrShowFieldset(element) |
| 553 | +{ |
| 554 | + //Find fieldset |
| 555 | + while (element.tagName.toLowerCase() != "fieldset") |
| 556 | + element = element.parentNode; |
| 557 | + //Bail out if fieldset is not part of chooser |
| 558 | + if (!element.getAttribute("haschooser")) |
| 559 | + return; |
| 560 | + //Now look for "input" or "select" tags that don't look like they're part of the starter template |
| 561 | + var inputs = element.getElementsByTagName("input"); |
| 562 | + var x; |
| 563 | + var show = false; |
| 564 | + for (x=0;x<inputs.length;x++) |
| 565 | + { |
| 566 | + if (inputs[x].type=="text" && inputs[x].name.indexOf("[num]") == -1) |
| 567 | + show = true; |
| 568 | + } |
| 569 | + var selects = element.getElementsByTagName("select"); |
| 570 | + for (x=0;x<selects.length;x++) |
| 571 | + { |
| 572 | + if (selects[x].name.indexOf("[num]") == -1) |
| 573 | + show = true; |
| 574 | + } |
| 575 | + //Now show or hide fieldset |
| 576 | + element.style.display = (show?"block":"none"); |
| 577 | +} |
| 578 | +</script> |
| 579 | +END; |
| 580 | + } |
| 581 | + |
| 582 | + |
| 583 | + |
| 584 | + |
| 585 | + $chooser_text .= "<p>$choosername:<select id='chooserselect$chooser_count' size='1' onchange='updatechooserbutton(this,\"chooserbutton$chooser_count\")'>"; |
| 586 | + $chooser_text .= "<option value='invalid'>Choose a field to add</option>"; |
| 587 | + foreach ($chooser as $chooser_item) { |
| 588 | + $chooser_value = str_replace('"','\\"',$chooser_item[0]); |
| 589 | + $tabindex = $chooser_item[1]; |
| 590 | + $chooser_caption = $chooser_item[2]; |
| 591 | + if ($chooser_caption === false) |
| 592 | + $chooser_caption = str_replace('_', ' ', $chooser_value); |
| 593 | + $chooser_text .= "<option value=\"$tabindex ,$chooser_value\">$chooser_caption</option>"; |
| 594 | + } |
| 595 | + $chooser_text .= "</select>\n"; |
| 596 | + } |
| 597 | + $chooser_text .= "<input type='button' onclick=\"addInstanceFromChooser('chooserselect$chooser_count');\" value='" . wfMsg('sf_editdata_addanother') . "' disabled='true' id='chooserbutton$chooser_count'></p>"; |
| 598 | + } |
| 599 | + |
| 600 | + $form_text = str_replace('<choosers>', $chooser_text, $form_text); |
| 601 | + |
| 602 | + |
496 | 603 | // add general Javascript code |
497 | 604 | $blank_error_str = wfMsg('sf_blank_error'); |
498 | 605 | $javascript_text .=<<<END |
— | — | @@ -561,6 +668,11 @@ |
562 | 669 | //Add the new instance |
563 | 670 | main_div.appendChild(new_div); |
564 | 671 | attachAutocompleteToAllFields(new_div); |
| 672 | + |
| 673 | + if ($using_choosers) |
| 674 | + { |
| 675 | + hideOrShowFieldset(new_div); |
| 676 | + } |
565 | 677 | } |
566 | 678 | |
567 | 679 | function removeInstanceEventHandler(this_div_id) |
— | — | @@ -573,7 +685,10 @@ |
574 | 686 | |
575 | 687 | function removeInstance(div_id) { |
576 | 688 | var olddiv = document.getElementById(div_id); |
577 | | - olddiv.parentNode.removeChild(olddiv); |
| 689 | + var parent = olddiv.parentNode; |
| 690 | + parent.removeChild(olddiv); |
| 691 | + if ($using_choosers) |
| 692 | + hideOrShowFieldset(parent); |
578 | 693 | } |
579 | 694 | |
580 | 695 | var autocompletestrings = new Array(); |
— | — | @@ -625,21 +740,16 @@ |
626 | 741 | |
627 | 742 | END; |
628 | 743 | |
629 | | - //Send the autocomplete values to the browser, along with the mappings of which values should apply to which fields |
630 | | - foreach ($autocomplete_value_array as $autocomplete_key => $autocomplete_string) |
631 | | - { |
632 | | - if ($autocomplete_key == "mappings") |
633 | | - { |
634 | | - foreach ($autocomplete_string as $field_number => $field_key) |
635 | | - { |
636 | | - $javascript_text .= "autocompletemappings[$field_number] = '" . str_replace("'", "\'", $field_key) . "';\n"; |
637 | | - } |
638 | | - } |
639 | | - else |
640 | | - { |
641 | | - $javascript_text .= "autocompletestrings['" . str_replace("'", "\'", $autocomplete_key) . "'] = $autocomplete_string;\n"; |
642 | | - } |
643 | | - } |
| 744 | + // send the autocomplete values to the browser, along with the mappings of which values should apply to which fields |
| 745 | + foreach ($autocomplete_values as $autocomplete_key => $autocomplete_string) { |
| 746 | + if ($autocomplete_key == "mappings") { |
| 747 | + foreach ($autocomplete_string as $field_number => $field_key) { |
| 748 | + $javascript_text .= "autocompletemappings[$field_number] = '" . str_replace("'", "\'", $field_key) . "';\n"; |
| 749 | + } |
| 750 | + } else { |
| 751 | + $javascript_text .= "autocompletestrings['" . str_replace("'", "\'", $autocomplete_key) . "'] = $autocomplete_string;\n"; |
| 752 | + } |
| 753 | + } |
644 | 754 | return array($form_text, $javascript_text, $title, $data_text); |
645 | 755 | } |
646 | 756 | |
— | — | @@ -770,6 +880,9 @@ |
771 | 881 | $names_array[] = str_replace('_', ' ', $cur_value); |
772 | 882 | } |
773 | 883 | $array_str = "['" . implode("', '", $names_array) . "']"; |
| 884 | + } else { |
| 885 | + // return an empty array |
| 886 | + $array_str = "[]"; |
774 | 887 | } |
775 | 888 | $db->freeResult($res); |
776 | 889 | return $array_str; |