r24461 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r24460‎ | r24461 | r24462 >
Date:15:18, 30 July 2007
Author:yaron
Status:old
Tags:
Comment:
Overhaul - all input validation and adding/removing of instances of multiple
templates is now done through Javascript instead of PHP. Also, 'TemplateField'
class now holds more data, so many functions take in less parameters; more
CSS styles are now stored in CSS file instead of inline; and various other
streamlining of the code.
Modified paths:
  • /trunk/extensions/SemanticForms/includes/SF_FormPrinter.inc (modified) (history)

Diff [purge]

Index: trunk/extensions/SemanticForms/includes/SF_FormPrinter.inc
@@ -1,6 +1,6 @@
22 <?php
33 /**
4 - * Handles the display and running of a user-created form.
 4+ * Handles the creation and running of a user-created form.
55 *
66 * @author Yaron Koren
77 * @author Nils Oppermann
@@ -33,6 +33,8 @@
3434 $form_text = wfMsg( 'protectedpagetext' );
3535 }
3636 }
 37+ $javascript_text = "";
 38+ $js_validation_calls = array();
3739
3840 // Remove <noinclude> sections and <includeonly> tags from form definition
3941 $form_def = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $form_def);
@@ -44,6 +46,7 @@
4547 $start_position = 0;
4648 $section_start = 0;
4749 $free_text_was_included = false;
 50+ $all_values_for_template = array();
4851 while ($brackets_loc = strpos($form_def, "{{{", $start_position)) {
4952 $brackets_end_loc = strpos($form_def, "}}}", $brackets_loc);
5053 $bracketed_string = substr($form_def, $brackets_loc + 3, $brackets_end_loc - ($brackets_loc + 3));
@@ -56,25 +59,23 @@
5760 $section_start = $brackets_loc;
5861 }
5962 $start_position = $brackets_loc + 1;
60 - }
 63+ } // end while
6164 $form_def_sections[] = trim(substr($form_def, $section_start));
6265
6366 // cycle through form definition file (and possibly an existing article
6467 // as well), finding template and field declarations and replacing them
6568 // with form elements, either blank or pre-populated, as appropriate
6669 $all_fields = array();
67 - $passed_validation = true;
6870 $data_text = "";
6971 $template_name = "";
70 - $full_template_name = "";
71 - $instance_was_deleted = false;
7272 $allow_multiple = false;
 73+ $instance_num = 0;
 74+ $all_instances_printed = false;
7375 $strict_parsing = false;
7476 for ($section_num = 0; $section_num < count($form_def_sections); $section_num++) {
7577 $tif = new SFTemplateInForm();
7678 $start_position = 0;
7779 $template_text = "";
78 - $instance_added = false;
7980 // the append is there to ensure that the original array doesn't get
8081 // modified; is it necessary?
8182 $section = " " . $form_def_sections[$section_num];
@@ -101,23 +102,8 @@
102103 }
103104 }
104105 }
105 - // increment instance_num (used for query string) if it's
106 - // a repeated template, or if user has hit 'add' button
107 - // - this logic might not need to be this complicated
108 - if ($allow_multiple) {
109 - if ($old_template_name == $template_name || $repeat_section) {
110 - $instance_num++;
111 - } else {
112 - $instance_num = 1;
113 - }
114 - $repeat_section = false;
115 - $full_template_name = $query_template_name . '_' . $instance_num;
116 - } else {
117 - $instance_num = 1;
118 - $full_template_name = $query_template_name;
119 - }
120106 // if this is the first instance, add the label in the form
121 - if ($instance_num == 1 && isset($template_label)) {
 107+ if (($old_template_name != $template_name) && isset($template_label)) {
122108 $form_text .= "<fieldset>\n";
123109 $form_text .= "<legend>$template_label</legend>\n";
124110 }
@@ -125,15 +111,7 @@
126112 $all_fields = $tif->getAllFields();
127113 // remove template tag
128114 $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
129 - // if this is an 'allowed multiple' template, and user requested a
130 - // delete of this instance, increment the instance_num; that will
131 - // skip over all the fields of this template in the query
132 - $delete_cur_instance = false;
133 - $full_template_values = $wgRequest->getArray($full_template_name);
134 - if ($allow_multiple && $full_template_values['delete'] != null) {
135 - $delete_cur_instance = true;
136 - $instance_was_deleted = true;
137 - }
 115+ $template_instance_query_values = $wgRequest->getArray($query_template_name);
138116 // if we are editing a page, and this template can be found more than
139117 // once in that page, and multiple values are allowed, repeat this
140118 // section
@@ -148,11 +126,9 @@
149127 // instances of templates, one that doesn't involve re-parsing
150128 // the same tags, but I don't know what it is.
151129 if (preg_match_all('/\{\{' . $tif->template_name . '(.*?)\}\}/mis', $existing_page_content, $matches)) {
152 - if (count($matches[0]) > 1) {
153 - $repeat_section = true;
154 - }
 130+ $instance_num++;
155131 } else {
156 - $delete_cur_instance = true;
 132+ $all_instances_printed = true;
157133 }
158134 }
159135 // get the first instance of this template on the page being edited,
@@ -183,34 +159,41 @@
184160 $existing_page_content = str_replace($matches[0], '', $existing_page_content);
185161 }
186162 }
187 - // now the same check as above, but if the input came from a form -
188 - // if multiple instances of this template are allowed, and the template
189 - // name of the current instance is the same as the next one, re-use
190 - // the template section on the next loop through
191 - if ((! $source_is_page) && $allow_multiple) {
192 - $possible_next_template_name = $query_template_name . '_' . ($instance_num + 1);
193 - $template_values = $wgRequest->getArray($query_template_name);
194 - if (count($wgRequest->getArray($possible_next_template_name)) > 0) {
195 - $repeat_section = true;
196 - } elseif ($template_values['add'] != null && !$instance_added) {
197 - $instance_added = true;
198 - if (count($wgRequest->getArray($full_template_name)) > 0) {
199 - $repeat_section = true;
 163+ // if the input is from the form (meaning the user has hit one
 164+ // of the bottom row of buttons), and we're dealing with a
 165+ // multiple template, get the values for this instance of this
 166+ // template, then delete them from the array, so we can get the
 167+ // next group next time - the next() command for arrays doesn't
 168+ // seem to work here
 169+ if ((! $source_is_page) && $allow_multiple && $wgRequest) {
 170+ $all_instances_printed = true;
 171+ if ($old_template_name != $template_name) {
 172+ $all_values_for_template = $wgRequest->getArray($query_template_name);
 173+ }
 174+ if ($all_values_for_template) {
 175+ $cur_key = key($all_values_for_template);
 176+ // skip the input coming in from the "starter" div
 177+ if ($cur_key == 'num') {
 178+ unset($all_values_for_template[$cur_key]);
 179+ $cur_key = key($all_values_for_template);
200180 }
201 - } elseif (count($wgRequest->getArray($full_template_name)) == 0 && !$instance_added) {
202 - $delete_cur_instance = true;
 181+ if ($template_instance_query_values = current($all_values_for_template)) {
 182+ $all_instances_printed = false;
 183+ unset($all_values_for_template[$cur_key]);
 184+ }
203185 }
204186 }
205187 } elseif ($tag_title == 'end template') {
206188 // remove this tag, reset some variables, and close off form HTML tag
207189 $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
208 - $allow_multiple = false;
209190 $template_name = null;
210 - $full_template_name = null;
211191 if (isset($template_label)) {
212192 $form_text .= "</fieldset>\n";
213193 unset ($template_label);
214194 }
 195+ $allow_multiple = false;
 196+ $all_instances_printed = false;
 197+ $instance_num = 0;
215198 } elseif ($tag_title == 'field') {
216199 $field_name = trim($tag_components[1]);
217200 // cycle through the other components
@@ -256,10 +239,8 @@
257240 }
258241 }
259242 }
260 - $error_str = null;
261243 // get the value from the request, if it's there
262 - $full_template_values = $wgRequest->getArray($full_template_name);
263 - $cur_value = $full_template_values[$field_name];
 244+ $cur_value = $template_instance_query_values[$field_name];
264245 if ($cur_value && ! is_array($cur_value)) {
265246 $cur_value = Sanitizer::safeEncodeAttribute($cur_value);
266247 }
@@ -277,51 +258,28 @@
278259 $cur_value = Sanitizer::safeEncodeAttribute($cur_value);
279260 }
280261 }
281 - // check that all mandatory values have been filled in
282 - if ($form_submitted && $is_mandatory && $cur_value == "") {
283 - $error_str = wfMsg('sf_blank_error');
284 - $passed_validation = false;
285 - }
286 - // the template display name might be different from what's in
287 - // the query string, if a previous instance was deleted
288 - if ($allow_multiple && $instance_was_deleted) {
289 - $template_display_name = $query_template_name . '_' . ($instance_num - 1);
290 - } else {
291 - $template_display_name = $full_template_name;
292 - }
 262+ $template_display_name = $query_template_name;
293263 // handle non-template fields - 'page title' and 'free text'
294264 if ($template_name == '') {
295265 if ($field_name == 'page title') {
296 - // if we're adding a new page, make it an input field, and
297 - // possibly validate it; otherwise just put in the name
298 - if ($page_title == null) {
299 - $title = $wgRequest->getVal('page_title');
300 - if ($form_submitted && $title == "") {
301 - $error_str = wfMsg('sf_blank_error');
302 - $passed_validation = false;
303 - }
304 - if ($size == null) $size = 35;
305 - $new_text = SFFormPrinter::textEntryHTML($size, '', $field_name, $title, $error_str);
306 - } else {
307 - $new_text = $page_title;
308 - }
309 - $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
 266+ // the actual value should be non-null - stick it in
 267+ $new_text = $page_title;
310268 } elseif ($field_name == 'free text') {
311269 // add placeholders for the free text in both the form and
312270 // the page, using <free_text> tags - once all the free text
313271 // is known (at the end), it will get substituted in
314272 if ($is_hidden) {
315 - $new_text = SFFormPrinter::hiddenFieldHTML(null, 'free_text', '<free_text>');
 273+ $new_text = SFFormPrinter::hiddenFieldHTML('free_text', '<free_text>');
316274 } else {
317275 if ($num_rows == null) $num_rows = 5;
318276 if ($num_cols == null) $num_cols = 30;
319 - $new_text = SFFormPrinter::textAreaHTML($num_rows, $num_cols, null, 'free_text', '<free_text>', null);
 277+ $new_text = SFFormPrinter::textAreaHTML($num_rows, $num_cols, 'free_text', '<free_text>', null);
320278 }
321 - $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
322279 $free_text_was_included = true;
323280 // add a similar placeholder to the data text
324281 $data_text .= "<free_text>\n\n";
325282 }
 283+ $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
326284 } else { // this field is part of a template
327285 if (is_array($cur_value)) {
328286 // if it has 1 or 2 elements, assume it's a checkbox; if it has
@@ -361,9 +319,17 @@
362320 } else { // value is not an array
363321 $cur_value_in_template = $cur_value;
364322 }
365 - $new_text = SFFormPrinter::formTemplateFieldHTML($template_display_name, $field_name, $instance_num,
 323+ if ($query_template_name == null || $query_template_name == '')
 324+ $input_name = $field_name;
 325+ elseif ($allow_multiple)
 326+ // 'num' will get replaced by an actual index, either in PHP
 327+ // or in Javascript, later on
 328+ $input_name = $query_template_name . '[num][' . $field_name . ']';
 329+ else
 330+ $input_name = $query_template_name . '[' . $field_name . ']';
 331+ $new_text = SFFormPrinter::formTemplateFieldHTML($field_name, $input_name, $allow_multiple,
366332 $cur_value, $is_mandatory, $is_hidden, $input_type, $size, $num_rows, $num_cols, $no_autocomplete,
367 - $autocomplete_category, $error_str, $all_fields, $strict_parsing);
 333+ $autocomplete_category, $all_fields, $strict_parsing);
368334 if ($new_text) {
369335 if (is_numeric($field_name)) {
370336 // if the value is null, don't include it at all -
@@ -376,6 +342,12 @@
377343 $template_text .= "\n|$field_name=$cur_value_in_template";
378344 }
379345 $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
 346+ // also add to Javascript validation code
 347+ if ($is_mandatory) {
 348+ $input_id = "input_" . $gTabIndex;
 349+ $info_id = "info_" . $gTabIndex;
 350+ $js_validation_calls[] = "validate_mandatory_field ('$input_id', '$info_id')";
 351+ }
380352 } else {
381353 $start_position = $brackets_end_loc;
382354 }
@@ -386,43 +358,49 @@
387359 }
388360 } // end while
389361
390 - if ($full_template_name != '' && ! $delete_cur_instance) {
 362+ if (! $all_instances_printed && ($template_text != '')) {
391363 // add another newline before the final bracket, if this template
392364 // call is already more than one line
393365 if (strpos($template_text, "\n")) {
394366 $template_text .= "\n";
395367 }
396 - $template_text .= "}}\n";
397 - // if this is the last of its kind, add another newline
398 - if ($allow_multiple == false || $repeat_section == false)
399 - $template_text .= "\n";
 368+ $template_text .= "}}\n\n";
 369+ // TODO - should instances of the same template not be separated
 370+ // by a blank line? if so, the following code could be used:
 371+ //if (($data_text != "") &&
 372+ // (! $allow_multiple || $old_template_name != $template_name)) {
 373+ // $data_text .= "\n";
 374+ //}
400375 $data_text .= $template_text;
401376 }
402377 if ($allow_multiple) {
403 - if (! $delete_cur_instance) {
404 - $input_name = $full_template_name . '[delete]';
 378+ if (! $all_instances_printed) {
 379+ $section = str_replace('[num]', "[{$instance_num}a]", $section);
405380 $remove_text = wfMsg('sf_editdata_remove');
406 - $gTabIndex++;
407381 $form_text .=<<<END
408 - <div style="background-color:#cccccc; padding:7px; margin:10px 0px 10px 0px;">
 382+ <div id="wrapper_$gTabIndex" class="multiple_template">
409383 $section
410 - <input tabindex="$gTabIndex" type="submit" name="$input_name" value="$remove_text" $gDisabledText>
 384+ <input type="button" onclick="blankInstance('wrapper_$gTabIndex');" value="$remove_text" tabindex="$gTabIndex" />
411385 </div>
412386
413387 END;
414 - }
415 - if ($repeat_section) {
416388 // this will cause the section to be re-parsed on the next go
417389 $section_num--;
418390 } else {
419391 // this is the last instance of this template - stick an 'add'
420392 // button in the form
421 - $input_name = $template_name . '[add]';
 393+ $form_text .=<<<END
 394+ <div id="starter_$query_template_name" class="multiple_template" style="display: none;">
 395+ $section
 396+ </div>
 397+ <div id="main_$query_template_name"></div>
 398+
 399+END;
422400 $add_another = wfMsg('sf_editdata_addanother');
423 - $gTabIndex++;
424401 $form_text .=<<<END
425402 <p style="margin-left:10px;">
426 - <input tabindex="$gTabIndex" type="submit" name="$input_name" value="$add_another" $gDisabledText></p>
 403+ <input type="hidden" value="0" id="numElements" />
 404+ <p><input type="button" onclick="addInstance('starter_$query_template_name', 'main_$query_template_name', '$gTabIndex');" value="$add_another" tabindex="$gTabIndex" /></p>
427405
428406 END;
429407 }
@@ -436,7 +414,7 @@
437415 // 'free text' input at the bottom of the form
438416 if (! $free_text_was_included) {
439417 $form_text .= ' <fieldset><legend>' . wfMsg('sf_editdata_freetextlabel') . "</legend>\n";
440 - $form_text .= SFFormPrinter::textAreaHTML(5, 30, null, 'free_text', '<free_text>', null);
 418+ $form_text .= SFFormPrinter::textAreaHTML(5, 30, 'free_text', '<free_text>', null);
441419 $form_text .= " </fieldset>\n";
442420 }
443421 // get free text, and add to page data, as well as retroactively
@@ -460,77 +438,174 @@
461439 // now that we have it, substitute free text into the form and page
462440 $form_text = str_replace('<free_text>', $free_text, $form_text);
463441 $data_text = str_replace('<free_text>', $free_text, $data_text);
464 - return array($form_text, $title, $data_text, $passed_validation);
 442+
 443+ // add general Javascript code
 444+ $blank_error_str = wfMsg('sf_blank_error');
 445+ $javascript_text .=<<<END
 446+
 447+function validate_mandatory_field(field_id, info_id) {
 448+ field = document.getElementById(field_id);
 449+ if (field.value.replace(/\s+/, '') == '') {
 450+ infobox = document.getElementById(info_id);
 451+ infobox.innerHTML = "$blank_error_str";
 452+ //field.style.border = "1px solid red";
 453+ return false;
 454+ } else {
 455+ return true;
 456+ }
 457+}
 458+
 459+function validate_all() {
 460+ var num_errors = 0;
 461+
 462+END;
 463+ foreach ($js_validation_calls as $function_call) {
 464+ $javascript_text .= " if (!$function_call) num_errors += 1;\n";
 465+ }
 466+ $remove_text = wfMsg('sf_editdata_remove');
 467+ $javascript_text .=<<<END
 468+ return (num_errors == 0);
 469+}
 470+
 471+// This Javascript code is heavily indebted to Dustin Diaz's 'add and remove
 472+// HTML elements' tutorial - http://www.dustindiaz.com/add-and-remove-html-elements-dynamically-with-javascript/
 473+function addInstance(starter_div_id, main_div_id, tab_index) {
 474+ var starter_div = document.getElementById(starter_div_id);
 475+ var main_div = document.getElementById(main_div_id);
 476+ var numi = document.getElementById('numElements');
 477+ var num = (document.getElementById('numElements').value -1)+ 2;
 478+ numi.value = num;
 479+ var newdiv = document.createElement('div');
 480+ var div_id = 'div_' + num;
 481+ newdiv.setAttribute('id', div_id);
 482+ newdiv.setAttribute('class', 'multiple_template');
 483+ // workaround for IE 6 bug
 484+ newdiv.setAttribute('className', 'multiple_template');
 485+ // make internal ID unique for the relevant divs and spans, and replace
 486+ // the [num] index with an actual unique index
 487+ var orig_html = starter_div.innerHTML;
 488+ orig_html = orig_html.replace(/input_/g, 'input_' + num + '_');
 489+ orig_html = orig_html.replace(/info_/g, 'info_' + num + '_');
 490+ orig_html = orig_html.replace(/div_/g, 'div_' + num + '_');
 491+ orig_html = orig_html.replace(/\[num\]/g, '[' + num + ']');
 492+ newdiv.innerHTML = orig_html + '<input type="button" onclick="removeInstance(\'' + main_div_id + '\', \'' + div_id + '\');" value="$remove_text" tabindex="' + tab_index + '" />';
 493+ main_div.appendChild(newdiv);
 494+}
 495+
 496+function removeInstance(main_div_id, this_div_id) {
 497+ var d = document.getElementById(main_div_id);
 498+ var olddiv = document.getElementById(this_div_id);
 499+ d.removeChild(olddiv);
 500+}
 501+
 502+// hack function - an element that's not a child of anything can't be
 503+// removed, so do the next best thing: set its contents to blank and its
 504+// display to 'none'
 505+function blankInstance(div_id) {
 506+ var d = document.getElementById(div_id);
 507+ d.innerHTML = "";
 508+ d.style.display = "none";
 509+}
 510+
 511+END;
 512+ return array($form_text, $javascript_text, $title, $data_text);
465513 }
466514
467 - function formTemplateFieldHTML($template_name, $field_name, $instance_num, $cur_value, $is_mandatory, $is_hidden, $input_type, $size, $num_rows, $num_cols, $no_autocomplete, $autocomplete_category, $error_str, $all_fields, $strict_parsing) {
 515+ function formTemplateFieldHTML($field_name, $input_name, $part_of_multiple, $cur_value, $is_mandatory, $is_hidden, $input_type, $size, $num_rows, $num_cols, $no_autocomplete, $autocomplete_category, $all_fields, $strict_parsing) {
 516+ global $gTabIndex;
468517
469518 // see if this field matches one of the fields defined for this template -
470519 // if it is, use all available information about that field; if it's not,
471520 // either include it in the form or not, depending on whether template
472521 // has 'strict' setting in the form definition
 522+ $the_field = null;
473523 foreach ($all_fields as $cur_field) {
474524 if ($field_name == $cur_field->field_name) {
475 - $text = SFFormPrinter::formFieldHTML($template_name, $field_name, $cur_field, $instance_num, $cur_value, $is_mandatory, $is_hidden, $input_type, $size, $num_rows, $num_cols, $no_autocomplete, $autocomplete_category, $error_str);
476 - return $text;
 525+ $the_field = $cur_field;
 526+ break;
477527 }
478528 }
479 - // if we're still here, field wasn't found
480 - if (! $strict_parsing) {
481 - $dummy_field = new SFTemplateField();
482 - $text = SFFormPrinter::formFieldHTML($template_name, $field_name, $dummy_field, $instance_num, $cur_value, $is_mandatory, $is_hidden, $input_type, $size, $num_rows, $num_cols, $no_autocomplete, $autocomplete_category, $error_str);
483 - return $text;
 529+ if ($the_field == null) {
 530+ if ($strict_parsing)
 531+ return null;
 532+ $the_field = new SFTemplateField();
484533 }
485 - return null;
 534+
 535+ // if this is not part of a 'multiple' template, incrememt the
 536+ // global tab index (used for correct tabbing, and for creating
 537+ // unique div IDs.)
 538+ if (! $part_of_multiple)
 539+ $gTabIndex++;
 540+
 541+ // populate field object with settings from the form definition file
 542+ $the_field->is_mandatory = $is_mandatory;
 543+ $the_field->is_hidden = $is_hidden;
 544+ $the_field->input_type = $input_type;
 545+ $the_field->size = $size;
 546+ $the_field->num_rows = $num_rows;
 547+ $the_field->num_cols = $num_cols;
 548+ $the_field->no_autocomplete = $no_autocomplete;
 549+ $the_field->autocomplete_category = $autocomplete_category;
 550+ $the_field->input_name = $input_name;
 551+ $the_field->part_of_multiple = $part_of_multiple;
 552+ $text = SFFormPrinter::formFieldHTML($the_field, $cur_value);
 553+ return $text;
486554 }
487555
488 - function formFieldHTML($template_name, $field_name, $template_field, $instance_num, $cur_value, $is_mandatory, $is_hidden, $input_type, $size, $num_rows, $num_cols, $no_autocomplete, $autocomplete_category, $error_str) {
 556+ function formFieldHTML($template_field, $cur_value) {
489557 global $smwgContLang;
490 - if ($is_hidden) {
491 - $text = SFFormPrinter::hiddenFieldHTML($template_name, $field_name, $cur_value);
492 - } elseif ($autocomplete_category != null) {
493 - if ($size == null) $size = 35;
494 - $text = SFFormPrinter::textEntryWithAutocompleteHTML($size, $template_name, $field_name, $instance_num, $autocomplete_category, false, $cur_value, $error_str);
495 - } elseif ($input_type == 'text') {
496 - if ($size == null) $size = 35;
497 - $text = SFFormPrinter::textEntryHTML($size, $template_name, $field_name, $cur_value, $error_str);
498 - } elseif ($input_type == 'textarea') {
499 - if ($num_rows == null) $num_rows = 4;
500 - if ($num_cols == null) $num_cols = 40;
501 - $text = SFFormPrinter::textAreaHTML($num_rows, $num_cols, $template_name, $field_name, $cur_value, $error_str);
502 - } elseif ($input_type == 'date') {
503 - $text = SFFormPrinter::dateEntryHTML($template_name, $field_name, $cur_value, $error_str);
504 - } elseif ($input_type == 'checkbox') {
505 - $text = SFFormPrinter::checkboxHTML($template_name, $field_name, $cur_value, $error_str);
506 - } elseif ($template_field->attr_or_rel == "relation") {
507 - if ($size == null) $size = 35;
508 - if ($no_autocomplete) {
509 - $text = SFFormPrinter::textEntryHTML($size, $template_name, $field_name, $cur_value, $error_str);
510 - } else {
511 - $text = SFFormPrinter::textEntryWithAutocompleteHTML($size, $template_name, $field_name, $instance_num, $template_field->semantic_field, true, $cur_value, $error_str);
512 - }
513 - } else { // input type not defined in form, and not a relation
514 - $attr_type = $template_field->attribute_type;
515 - if ($attr_type == $smwgContLang->smwDatatypeLabels['smw_enum']) {
516 - // prepend the "None" option if it's not a mandatory field
517 - $include_none = ! $is_mandatory;
518 - $text = SFFormPrinter::dropdownHTML($template_name, $field_name, $template_field->possible_values, $include_none, $cur_value, $error_str);
519 - } elseif ($attr_type == $smwgContLang->smwDatatypeLabels['smw_datetime']) {
520 - $text = SFFormPrinter::dateEntryHTML($template_name, $field_name, $cur_value, $error_str);
521 - } elseif ($attr_type == $smwgContLang->smwDatatypeLabels['smw_float'] || $attr_type == $smwgContLang->smwDatatypeLabels['smw_int']) {
522 - if ($size == null) $size = 10;
523 - $text = SFFormPrinter::textEntryHTML($size, $template_name, $field_name, $cur_value, $error_str);
524 - } elseif ($attr_type == $smwgContLang->smwDatatypeLabels['smw_url']) {
525 - if ($size == null) $size = 100;
526 - $text = SFFormPrinter::textEntryHTML($size, $template_name, $field_name, $cur_value, $error_str);
527 - } elseif ($attr_type == $smwgContLang->smwDatatypeLabels['smw_bool']) {
528 - $text = SFFormPrinter::checkboxHTML($template_name, $field_name, $cur_value, $error_str);
529 - } else { // String or anything else
530 - if ($size == null) $size = 35;
531 - $text = SFFormPrinter::textEntryHTML($size, $template_name, $field_name, $cur_value, $error_str);
532 - }
533 - }
534 - return $text;
 558+
 559+ if ($template_field->is_hidden) {
 560+ $text = SFFormPrinter::hiddenFieldHTML($template_field->input_name, $cur_value);
 561+ } elseif ($template_field->autocomplete_category != null) {
 562+ $size = $template_field->size;
 563+ if ($size == null) $size = 35;
 564+ $text = SFFormPrinter::textEntryWithAutocompleteHTML($size, $template_field->input_name, $template_field->part_of_multiple, $template_field->autocomplete_category, false, $cur_value);
 565+ } elseif ($template_field->input_type == 'text') {
 566+ $size = $template_field->size;
 567+ if ($size == null) $size = 35;
 568+ $text = SFFormPrinter::textEntryHTML($size, $template_field->input_name, $cur_value);
 569+ } elseif ($template_field->input_type == 'textarea') {
 570+ $num_rows = $template_field->num_rows;
 571+ if ($num_rows == null) $num_rows = 4;
 572+ $num_cols = $template_field->num_cols;
 573+ if ($num_cols == null) $num_cols = 40;
 574+ $text = SFFormPrinter::textAreaHTML($num_rows, $num_cols, $template_field->input_name, $cur_value);
 575+ } elseif ($template_field->input_type == 'date') {
 576+ $text = SFFormPrinter::dateEntryHTML($template_field->input_name, $cur_value);
 577+ } elseif ($template_field->input_type == 'checkbox') {
 578+ $text = SFFormPrinter::checkboxHTML($template_field->input_name, $cur_value);
 579+ } elseif ($template_field->attr_or_rel == "relation") {
 580+ $size = $template_field->size;
 581+ if ($size == null) $size = 35;
 582+ if ($template_field->no_autocomplete) {
 583+ $text = SFFormPrinter::textEntryHTML($size, $template_field->input_name, $cur_value);
 584+ } else {
 585+ $text = SFFormPrinter::textEntryWithAutocompleteHTML($size, $template_field->input_name, $template_field->part_of_multiple, $template_field->semantic_field, true, $cur_value);
 586+ }
 587+ } else { // input type not defined in form, and not a relation
 588+ $attr_type = $template_field->attribute_type;
 589+ $size = $template_field->size;
 590+ if ($attr_type == $smwgContLang->smwDatatypeLabels['smw_enum']) {
 591+ // prepend the "None" option if it's not a mandatory field
 592+ $include_none = ! $template_field->is_mandatory;
 593+ $text = SFFormPrinter::dropdownHTML($template_field->input_name, $template_field->possible_values, $include_none, $cur_value);
 594+ } elseif ($attr_type == $smwgContLang->smwDatatypeLabels['smw_datetime']) {
 595+ $text = SFFormPrinter::dateEntryHTML($template_field->input_name, $cur_value);
 596+ } elseif ($attr_type == $smwgContLang->smwDatatypeLabels['smw_float'] || $attr_type == $smwgContLang->smwDatatypeLabels['smw_int']) {
 597+ if ($size == null) $size = 10;
 598+ $text = SFFormPrinter::textEntryHTML($size, $template_field->input_name, $cur_value);
 599+ } elseif ($attr_type == $smwgContLang->smwDatatypeLabels['smw_url']) {
 600+ if ($size == null) $size = 100;
 601+ $text = SFFormPrinter::textEntryHTML($size, $template_field->input_name, $cur_value);
 602+ } elseif ($attr_type == $smwgContLang->smwDatatypeLabels['smw_bool']) {
 603+ $text = SFFormPrinter::checkboxHTML($template_field->input_name, $cur_value);
 604+ } else { // String or anything else
 605+ if ($size == null) $size = 35;
 606+ $text = SFFormPrinter::textEntryHTML($size, $template_field->input_name, $cur_value);
 607+ }
 608+ }
 609+ return $text;
535610 }
536611
537612 function createAutocompleteValuesString($field_name, $is_relation) {
@@ -542,11 +617,13 @@
543618 // the query depends on whether this field is a relation or a category
544619 if ($is_relation) {
545620 $conditions = "relation_title = '$field_name'";
 621+ $sql_options['ORDER BY'] = 'object_title';
546622 $res = $db->select( $db->tableName('smw_relations'),
547623 'DISTINCT object_title',
548624 $conditions, $fname, $sql_options);
549625 } else {
550626 $conditions = "cl_from = page_id AND cl_to = '$field_name'";
 627+ $sql_options['ORDER BY'] = 'page_title';
551628 $res = $db->select( $db->tableNames('categorylinks', 'page'),
552629 'page_title',
553630 $conditions, $fname, $sql_options);
@@ -563,30 +640,24 @@
564641 return $array_str;
565642 }
566643
567 - function textEntryHTML($size, $template_name, $field_name, $cur_value, $error_str) {
 644+ function textEntryHTML($size, $input_name, $cur_value) {
568645 global $gTabIndex, $gDisabledText;
569 - $gTabIndex++;
 646+ $input_id = "input_$gTabIndex";
 647+ $info_id = "info_$gTabIndex";
570648
571 - if ($template_name == null || $template_name == '')
572 - $input_name = $field_name;
573 - else
574 - $input_name = $template_name . '[' . $field_name . ']';
575649 $text =<<<END
576 - <input tabindex="$gTabIndex" class="createboxInput" name="$input_name" type="text"
 650+ <input id="$input_id" tabindex="$gTabIndex" class="createboxInput" name="$input_name" type="text"
577651 value="$cur_value" size="$size" $gDisabledText/>
 652+ <span id="$info_id" class="error_message"></span>
578653
579654 END;
580 - if ($error_str) {
581 - $text .= " <font color=\"red\">$error_str</font>\n";
582 - }
583655 return $text;
584656 }
585657
586 - function dropdownHTML($template_name, $field_name, $possible_values, $include_none, $cur_value, $error_str) {
 658+ function dropdownHTML($input_name, $possible_values, $include_none, $cur_value) {
587659 global $gTabIndex, $gDisabledText;
588 - $gTabIndex++;
589660
590 - $text = ' <select tabindex="' . $gTabIndex . '" name="' . $template_name . '[' . $field_name . ']" ' . $gDisabledText . '>';
 661+ $text = ' <select tabindex="' . $gTabIndex . '" name="' . $input_name . '" ' . $gDisabledText . '>';
591662 if ($include_none)
592663 $text .= " <option value=\"\">[None]</option>\n";
593664 foreach ($possible_values as $possible_value) {
@@ -594,37 +665,27 @@
595666 if ($possible_value == $cur_value) {$text .= " selected=\"selected\""; }
596667 $text .= ">$possible_value</option>\n";
597668 }
598 - $text .= " </select>\n";
599 - if ($error_str)
600 - $text .= " <font color=\"red\">$error_str</font>\n";
 669+ $text .=<<<END
 670+ </select>
 671+ <span id="$info_id" class="error_message"></span>
 672+
 673+END;
601674 return $text;
602675 }
603676
604 - function textEntryWithAutocompleteHTML($size, $template_name, $field_name, $instance_num, $semantic_field_name, $is_relation, $cur_value, $error_str) {
 677+ function textEntryWithAutocompleteHTML($size, $input_name, $part_of_multiple, $semantic_field_name, $is_relation, $cur_value) {
605678 global $gTabIndex, $gDisabledText;
606679 $gTabIndex++;
607680
608 - $input_id = $template_name . "_" . $field_name . "_input";
609 - $div_name = $template_name . "_" . $field_name . "_div";
610 - // add instance num to the HTML labels if it's the second or higher, to
611 - // guarantee uniqueness of name; autocompletion fails on IE otherwise
612 - if ($instance_num > 1) {
613 - $input_id .= "_" . $instance_num;
614 - $div_name .= "_" . $instance_num;
615 - }
616 - $input_name = $template_name . '[' . $field_name . ']';
617 -
 681+ $input_id = "input_" . $gTabIndex;
 682+ $info_id = "info_" . $gTabIndex;
 683+ $div_name = "div_" . $gTabIndex;
618684 $options_str = SFFormPrinter::createAutocompleteValuesString(str_replace(' ', '_', $semantic_field_name), $is_relation);
619685 $text =<<<END
620 - <input tabindex="$gTabIndex" id="$input_id" autocomplete="off" class="createboxInput" name="$input_name" type="text"
621 - value="" size="$size" $gDisabledText/>
622 -
623 -END;
624 - if ($error_str) {
625 - $text .= " <font color=\"red\">$error_str</font>";
626 - }
627 - $text .=<<<END
628 - <div class="page_name_auto_complete" id="$div_name" style="display:none"></div>
 686+ <input tabindex="$gTabIndex" id="$input_id" name="$input_name" type="text"
 687+ value="" size="$size" $gDisabledText/>
 688+ <span id="$info_id" class="error_message"></span>
 689+ <div class="page_name_auto_complete" id="$div_name" style="display:none"></div>
629690 <script type="text/javascript">
630691 new Autocompleter.Local('$input_id', '$div_name', $options_str, {});
631692
@@ -636,29 +697,23 @@
637698 return $text;
638699 }
639700
640 - function textAreaHTML($rows, $cols, $template_name, $field_name, $cur_value, $error_str) {
 701+ function textAreaHTML($rows, $cols, $input_name, $cur_value) {
641702 global $gTabIndex, $gDisabledText;
642 - $gTabIndex++;
 703+ $input_id = "input_$gTabIndex";
 704+ $info_id = "info_$gTabIndex";
643705
644 - if ($template_name == null) {
645 - $input_name = $field_name;
646 - } else {
647 - $input_name = $template_name . '[' . $field_name . ']';
648 - }
649706 $text =<<<END
650 - <textarea tabindex="$gTabIndex" name="$input_name" rows=$rows cols=$cols $gDisabledText/>$cur_value</textarea>
 707+ <textarea tabindex="$gTabIndex" id="$input_id" name="$input_name" rows=$rows cols=$cols $gDisabledText/>$cur_value</textarea>
 708+ <span id="$info_id" class="error_message"></span>
651709
652710 END;
653 - if ($error_str)
654 - $text .= " <font color=\"red\">$error_str</font>\n";
655711 return $text;
656712 }
657713
658 - function monthDropdownHTML($cur_month, $template_name, $index) {
 714+ function monthDropdownHTML($cur_month, $input_name) {
659715 global $gTabIndex, $gDisabledText;
660 - $gTabIndex++;
661716
662 - $text = ' <select tabindex="' . $gTabIndex . '" name="' . $template_name . '[' . $index . "][month]\" $gDisabledText>\n";
 717+ $text = ' <select tabindex="' . $gTabIndex . '" id="input_' . $gTabIndex . '" name="' . $input_name . "[month]\" $gDisabledText>\n";
663718 $month_names = array(
664719 wfMsgForContent('sf_january'),
665720 wfMsgForContent('sf_february'),
@@ -682,9 +737,8 @@
683738 return $text;
684739 }
685740
686 - function dateEntryHTML($template_name, $index, $date, $error_str) {
 741+ function dateEntryHTML($input_name, $date) {
687742 global $gTabIndex, $gDisabledText;
688 - $gTabIndex++;
689743
690744 if ($date) {
691745 // can show up here either as an array or a string, depending on
@@ -705,25 +759,21 @@
706760 $month = $cur_date[month];
707761 $day = null; // no need for day
708762 }
709 - $text .= SFFormPrinter::monthDropdownHTML($month, $template_name, $index);
710 - $gTabIndex++;
711 - $text .= ' <input tabindex="' . $gTabIndex . '" name="' . $template_name . '[' . $index . '][day]" type="text" value="' . $day . '" size="2"/ ' . $gDisabledText . '>' . "\n";
712 - $gTabIndex++;
713 - $text .= ' <input tabindex="' . $gTabIndex . '" name="' . $template_name . '[' . $index . '][year]" type="text" value="' . $year . '" size="4"/ ' . $gDisabledText . '>' . "\n";
714 - if ($error_str) {
715 - $text .= " <font color=\"red\">$error_str</font>\n";
716 - }
 763+ $text .= SFFormPrinter::monthDropdownHTML($month, $input_name);
 764+ $text .= ' <input tabindex="' . $gTabIndex . '" id="input_' . $gTabIndex . '" name="' . $input_name . '[day]" type="text" value="' . $day . '" size="2"/ ' . $gDisabledText . '>' . "\n";
 765+ $text .= ' <input tabindex="' . $gTabIndex . '" id="input_' . $gTabIndex . '" name="' . $input_name . '[year]" type="text" value="' . $year . '" size="4"/ ' . $gDisabledText . '>' . "\n";
 766+ $info_id = "info_$gTabIndex";
 767+ $text .= " <span id=\"$info_id\" class=\"error_message\"></span>";
717768 return $text;
718769 }
719770
720 - function radioButtonHTML($template_name, $field_name, $cur_value, $options_array) {
 771+ function radioButtonHTML($input_name, $cur_value, $options_array) {
721772 global $gTabIndex, $gDisabledText;
722 - $gTabIndex++;
723773
724774 if ($title)
725775 $text .= " <strong>$title:</strong>\n";
726776 foreach ($options_array as $i => $option) {
727 - $text .= ' <input type="radio" tabindex="' . $gTabIndex . '" name="' . $template_name . '[' . $field_name . ']" value="$option"';
 777+ $text .= ' <input type="radio" tabindex="' . $gTabIndex . '" name="' . $input_name . '" value="' . $option . '"';
728778 if ($cur_value == $option || (! $cur_value && $i == 0))
729779 $text .= " checked";
730780 $text .= " $gDisabledText/> $option\n";
@@ -731,9 +781,9 @@
732782 return $text;
733783 }
734784
735 - function checkboxHTML($template_name, $field_name, $cur_value, $error_str) {
 785+ function checkboxHTML($input_name, $cur_value) {
736786 global $gTabIndex, $gDisabledText;
737 - $gTabIndex++;
 787+ $info_id = "info_$gTabIndex";
738788
739789 // can show up here either as an array or a string, depending on
740790 // whether it came from user input or a wiki page
@@ -748,23 +798,16 @@
749799 $checked_str = "";
750800 }
751801 }
752 - $input_name = $template_name . '[' . $field_name . ']';
753802 $text =<<<END
754803 <input name="{$input_name}[is_checkbox]" type="hidden" value="true" />
755 - <input name="{$input_name}[value]" type="checkbox" tabindex="$gTabIndex " $checked_str $gDisabledText/>
 804+ <input id="input_$gTabIndex" name="{$input_name}[value]" type="checkbox" tabindex="$gTabIndex " $checked_str $gDisabledText/>
 805+ <span id="$info_id" class="error_message"></span>
756806
757807 END;
758 - if ($error_str) {
759 - $text .= " <font color=\"red\">$error_str</font>\n";
760 - }
761808 return $text;
762809 }
763810
764 - function hiddenFieldHTML($template_name, $field_name, $cur_value) {
765 - if ($template_name == null || $template_name == '')
766 - $input_name = $field_name;
767 - else
768 - $input_name = $template_name . '[' . $field_name . ']';
 811+ function hiddenFieldHTML($input_name, $cur_value) {
769812 $text =<<<END
770813 <input type="hidden" name="$input_name" value="$cur_value" />
771814

Status & tagging log