xref: /dokuwiki/inc/form.php (revision 53cc32cc69765e09542d9c4a69e59fa82c6566b9)
1<?php
2/**
3 * DokuWiki XHTML Form
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Tom N Harris <tnharris@whoopdedo.org>
7 */
8
9if(!defined('DOKU_INC')) define('DOKU_INC',fullpath(dirname(__FILE__).'/../').'/');
10if(!defined('NL')) define('NL',"\n");
11require_once(DOKU_INC.'inc/html.php');
12
13/**
14 * Class for creating simple HTML forms.
15 *
16 * The forms is built from a list of pseudo-tags (arrays with expected keys).
17 * Every pseudo-tag must have the key '_elem' set to the name of the element.
18 * When printed, the form class calls functions named 'form_$type' for each
19 * element it contains.
20 *
21 * Standard practice is for non-attribute keys in a pseudo-element to start
22 * with '_'. Other keys are HTML attributes that will be included in the element
23 * tag. That way, the element output functions can pass the pseudo-element
24 * directly to buildAttributes.
25 *
26 * See the form_make* functions later in this file.
27 *
28 * @author Tom N Harris <tnharris@whoopdedo.org>
29 */
30class Doku_Form {
31
32  // Usually either DOKU_SCRIPT or wl($ID)
33  var $action = '';
34
35  // Most likely no need to change this
36  var $method = 'post';
37
38  // Form id attribute
39  var $id = '';
40
41  // Draw a border around form fields.
42  // Adds <fieldset></fieldset> around the elements
43  var $_infieldset = false;
44
45  // Hidden form fields.
46  var $_hidden = array();
47
48  // Array of pseudo-tags
49  var $_content = array();
50
51  /**
52   * Constructor
53   *
54   * Autoadds a security token
55   *
56   * @param   string  $id     ID attribute of the form.
57   * @param   string  $action (optional) submit URL, defaults to DOKU_SCRIPT
58   * @param   string  $method (optional) 'POST' or 'GET', default is post
59   * @author  Tom N Harris <tnharris@whoopdedo.org>
60   */
61  function Doku_Form($id, $action=false, $method=false) {
62    $this->id = $id;
63    $this->action = ($action) ? $action : script();
64    if ($method) $this->method = $method;
65
66    $this->addHidden('sectok', getSecurityToken());
67  }
68
69  /**
70   * startFieldset
71   *
72   * Add <fieldset></fieldset> tags around fields.
73   * Usually results in a border drawn around the form.
74   *
75   * @param   string  $legend Label that will be printed with the border.
76   * @author  Tom N Harris <tnharris@whoopdedo.org>
77   */
78  function startFieldset($legend) {
79    if ($this->_infieldset) {
80      $this->addElement(array('_elem'=>'closefieldset'));
81    }
82    $this->addElement(array('_elem'=>'openfieldset', '_legend'=>$legend));
83    $this->_infieldset = true;
84  }
85
86  /**
87   * endFieldset
88   *
89   * @author  Tom N Harris <tnharris@whoopdedo.org>
90   */
91  function endFieldset() {
92    if ($this->_infieldset) {
93      $this->addElement(array('_elem'=>'closefieldset'));
94    }
95    $this->_infieldset = false;
96  }
97
98  /**
99   * addHidden
100   *
101   * Adds a name/value pair as a hidden field.
102   * The value of the field (but not the name) will be passed to
103   * formText() before printing.
104   *
105   * @param   string  $name   Field name.
106   * @param   string  $value  Field value. If null, remove a previously added field.
107   * @author  Tom N Harris <tnharris@whoopdedo.org>
108   */
109  function addHidden($name, $value) {
110    if (is_null($value))
111      unset($this->_hidden[$name]);
112    else
113      $this->_hidden[$name] = $value;
114  }
115
116  /**
117   * addElement
118   *
119   * Appends a content element to the form.
120   * The element can be either a pseudo-tag or string.
121   * If string, it is printed without escaping special chars.   *
122   *
123   * @param   string  $elem   Pseudo-tag or string to add to the form.
124   * @author  Tom N Harris <tnharris@whoopdedo.org>
125   */
126  function addElement($elem) {
127    $this->_content[] = $elem;
128  }
129
130  /**
131   * insertElement
132   *
133   * Inserts a content element at a position.
134   *
135   * @param   string  $pos    0-based index where the element will be inserted.
136   * @param   string  $elem   Pseudo-tag or string to add to the form.
137   * @author  Tom N Harris <tnharris@whoopdedo.org>
138   */
139  function insertElement($pos, $elem) {
140    array_splice($this->_content, $pos, 0, array($elem));
141  }
142
143  /**
144   * replaceElement
145   *
146   * Replace with NULL to remove an element.
147   *
148   * @param   int     $pos    0-based index the element will be placed at.
149   * @param   string  $elem   Pseudo-tag or string to add to the form.
150   * @author  Tom N Harris <tnharris@whoopdedo.org>
151   */
152  function replaceElement($pos, $elem) {
153    $rep = array();
154    if (!is_null($elem)) $rep[] = $elem;
155    array_splice($this->_content, $pos, 1, $rep);
156  }
157
158  /**
159   * findElementByType
160   *
161   * Gets the position of the first of a type of element.
162   *
163   * @param   string  $type   Element type to look for.
164   * @return  array   pseudo-element if found, false otherwise
165   * @author  Tom N Harris <tnharris@whoopdedo.org>
166   */
167  function findElementByType($type) {
168    foreach ($this->_content as $pos=>$elem) {
169      if (is_array($elem) && $elem['_elem'] == $type)
170        return $pos;
171    }
172    return false;
173  }
174
175  /**
176   * findElementById
177   *
178   * Gets the position of the element with an ID attribute.
179   *
180   * @param   string  $id     ID of the element to find.
181   * @return  array   pseudo-element if found, false otherwise
182   * @author  Tom N Harris <tnharris@whoopdedo.org>
183   */
184  function findElementById($id) {
185    foreach ($this->_content as $pos=>$elem) {
186      if (is_array($elem) && isset($elem['id']) && $elem['id'] == $id)
187        return $pos;
188    }
189    return false;
190  }
191
192  /**
193   * findElementByAttribute
194   *
195   * Gets the position of the first element with a matching attribute value.
196   *
197   * @param   string  $name   Attribute name.
198   * @param   string  $value  Attribute value.
199   * @return  array   pseudo-element if found, false otherwise
200   * @author  Tom N Harris <tnharris@whoopdedo.org>
201   */
202  function findElementByAttribute($name, $value) {
203    foreach ($this->_content as $pos=>$elem) {
204      if (is_array($elem) && isset($elem[$name]) && $elem[$name] == $value)
205        return $pos;
206    }
207    return false;
208  }
209
210  /**
211   * getElementAt
212   *
213   * Returns a reference to the element at a position.
214   * A position out-of-bounds will return either the
215   * first (underflow) or last (overflow) element.
216   *
217   * @param   int     $pos    0-based index
218   * @return  arrayreference  pseudo-element
219   * @author  Tom N Harris <tnharris@whoopdedo.org>
220   */
221  function &getElementAt($pos) {
222    if ($pos < 0) $pos = count($this->_content) + $pos;
223    if ($pos < 0) $pos = 0;
224    if ($pos >= count($this->_content)) $pos = count($this->_content) - 1;
225    return $this->_content[$pos];
226  }
227
228  /**
229   * printForm
230   *
231   * Output the form.
232   * Each element in the form will be passed to a function named
233   * 'form_$type'. The function should return the HTML to be printed.
234   *
235   * @author  Tom N Harris <tnharris@whoopdedo.org>
236   */
237  function printForm() {
238    global $lang;
239    print '<form action="'.$this->action.'" method="'.$this->method.'" accept-charset="'.$lang['encoding'].'"';
240    if (!empty($this->id)) print ' id="'.$this->id.'"';
241    print '>'.NL;
242    if (!empty($this->_hidden)) {
243      print '<div class="no">';
244      foreach ($this->_hidden as $name=>$value)
245        print form_hidden(array('name'=>$name, 'value'=>$value));
246      print '</div>'.NL;
247    }
248    foreach ($this->_content as $element) {
249      if (is_array($element)) {
250        $elem_type = $element['_elem'];
251        if (function_exists('form_'.$elem_type)) {
252          print call_user_func('form_'.$elem_type, $element).NL;
253        }
254      } else {
255        print $element;
256      }
257    }
258    if ($this->_infieldset) print form_closefieldset().NL;
259    print '</form>'.NL;
260  }
261
262}
263
264/**
265 * form_makeTag
266 *
267 * Create a form element for a non-specific empty tag.
268 *
269 * @param   string  $tag    Tag name.
270 * @param   array   $attrs  Optional attributes.
271 * @return  array   pseudo-tag
272 * @author  Tom N Harris <tnharris@whoopdedo.org>
273 */
274function form_makeTag($tag, $attrs=array()) {
275  $elem = array('_elem'=>'tag', '_tag'=>$tag);
276  return array_merge($elem, $attrs);
277}
278
279/**
280 * form_makeOpenTag
281 *
282 * Create a form element for a non-specific opening tag.
283 * Remember to put a matching close tag after this as well.
284 *
285 * @param   string  $tag    Tag name.
286 * @param   array   $attrs  Optional attributes.
287 * @return  array   pseudo-tag
288 * @author  Tom N Harris <tnharris@whoopdedo.org>
289 */
290function form_makeOpenTag($tag, $attrs=array()) {
291  $elem = array('_elem'=>'opentag', '_tag'=>$tag);
292  return array_merge($elem, $attrs);
293}
294
295/**
296 * form_makeCloseTag
297 *
298 * Create a form element for a non-specific closing tag.
299 * Careless use of this will result in invalid XHTML.
300 *
301 * @param   string  $tag    Tag name.
302 * @return  array   pseudo-tag
303 * @author  Tom N Harris <tnharris@whoopdedo.org>
304 */
305function form_makeCloseTag($tag) {
306  return array('_elem'=>'closetag', '_tag'=>$tag);
307}
308
309/**
310 * form_makeWikiText
311 *
312 * Create a form element for a textarea containing wiki text.
313 * Only one wikitext element is allowed on a page. It will have
314 * a name of 'wikitext' and id 'wiki__text'. The text will
315 * be passed to formText() before printing.
316 *
317 * @param   string  $text   Text to fill the field with.
318 * @param   array   $attrs  Optional attributes.
319 * @return  array   pseudo-tag
320 * @author  Tom N Harris <tnharris@whoopdedo.org>
321 */
322function form_makeWikiText($text, $attrs=array()) {
323  $elem = array('_elem'=>'wikitext', '_text'=>$text,
324                'class'=>'edit', 'cols'=>'80', 'rows'=>'10');
325  return array_merge($elem, $attrs);
326}
327
328/**
329 * form_makeButton
330 *
331 * Create a form element for an action button.
332 * A title will automatically be generated using the value and
333 * accesskey attributes, unless you provide one.
334 *
335 * @param   string  $type   Type attribute. 'submit' or 'cancel'
336 * @param   string  $act    Wiki action of the button, will be used as the do= parameter
337 * @param   string  $value  (optional) Displayed label. Uses $act if not provided.
338 * @param   array   $attrs  Optional attributes.
339 * @return  array   pseudo-tag
340 * @author  Tom N Harris <tnharris@whoopdedo.org>
341 */
342function form_makeButton($type, $act, $value='', $attrs=array()) {
343  if ($value == '') $value = $act;
344  //$name = (!empty($act)) ? 'do[$act]' : null;
345  $elem = array('_elem'=>'button', 'type'=>$type, '_action'=>$act,
346                'value'=>$value, 'class'=>'button');
347  if (!empty($attrs['accesskey']) && empty($attrs['title'])) {
348    $attrs['title'] = $value . ' [ALT+'.strtoupper($attrs['accesskey']).']';
349  }
350  return array_merge($elem, $attrs);
351}
352
353/**
354 * form_makeField
355 *
356 * Create a form element for a labelled input element.
357 * The label text will be printed before the input.
358 *
359 * @param   string  $type   Type attribute of input.
360 * @param   string  $name   Name attribute of the input.
361 * @param   string  $value  (optional) Default value.
362 * @param   string  $class  Class attribute of the label. If this is 'block',
363 *                          then a line break will be added after the field.
364 * @param   string  $label  Label that will be printed before the input.
365 * @param   string  $id     ID attribute of the input. If set, the label will
366 *                          reference it with a 'for' attribute.
367 * @param   array   $attrs  Optional attributes.
368 * @return  array   pseudo-tag
369 * @author  Tom N Harris <tnharris@whoopdedo.org>
370 */
371function form_makeField($type, $name, $value='', $label=null, $id='', $class='', $attrs=array()) {
372  if (is_null($label)) $label = $name;
373  $elem = array('_elem'=>'field', '_text'=>$label, '_class'=>$class,
374                'type'=>$type, 'id'=>$id, 'name'=>$name, 'value'=>$value);
375  return array_merge($elem, $attrs);
376}
377
378/**
379 * form_makeFieldRight
380 *
381 * Create a form element for a labelled input element.
382 * The label text will be printed after the input.
383 *
384 * @see     form_makeField
385 * @author  Tom N Harris <tnharris@whoopdedo.org>
386 */
387function form_makeFieldRight($type, $name, $value='', $label=null, $id='', $class='', $attrs=array()) {
388  if (is_null($label)) $label = $name;
389  $elem = array('_elem'=>'fieldright', '_text'=>$label, '_class'=>$class,
390                'type'=>$type, 'id'=>$id, 'name'=>$name, 'value'=>$value);
391  return array_merge($elem, $attrs);
392}
393
394/**
395 * form_makeTextField
396 *
397 * Create a form element for a text input element with label.
398 *
399 * @see     form_makeField
400 * @author  Tom N Harris <tnharris@whoopdedo.org>
401 */
402function form_makeTextField($name, $value='', $label=null, $id='', $class='', $attrs=array()) {
403  if (is_null($label)) $label = $name;
404  $elem = array('_elem'=>'textfield', '_text'=>$label, '_class'=>$class,
405                'id'=>$id, 'name'=>$name, 'value'=>$value, 'class'=>'edit');
406  return array_merge($elem, $attrs);
407}
408
409/**
410 * form_makePasswordField
411 *
412 * Create a form element for a password input element with label.
413 * Password elements have no default value, for obvious reasons.
414 *
415 * @see     form_makeField
416 * @author  Tom N Harris <tnharris@whoopdedo.org>
417 */
418function form_makePasswordField($name, $label=null, $id='', $class='', $attrs=array()) {
419  if (is_null($label)) $label = $name;
420  $elem = array('_elem'=>'passwordfield', '_text'=>$label, '_class'=>$class,
421                'id'=>$id, 'name'=>$name, 'class'=>'edit');
422  return array_merge($elem, $attrs);
423}
424
425/**
426 * form_makeCheckboxField
427 *
428 * Create a form element for a checkbox input element with label.
429 *
430 * @see     form_makeFieldRight
431 * @author  Tom N Harris <tnharris@whoopdedo.org>
432 */
433function form_makeCheckboxField($name, $value='1', $label=null, $id='', $class='', $attrs=array()) {
434  if (is_null($label)) $label = $name;
435  if (is_null($value) || $value=='') $value='0';
436  $elem = array('_elem'=>'checkboxfield', '_text'=>$label, '_class'=>$class,
437                'id'=>$id, 'name'=>$name, 'value'=>$value);
438  return array_merge($elem, $attrs);
439}
440
441/**
442 * form_makeRadioField
443 *
444 * Create a form element for a radio button input element with label.
445 *
446 * @see     form_makeFieldRight
447 * @author  Tom N Harris <tnharris@whoopdedo.org>
448 */
449function form_makeRadioField($name, $value='1', $label=null, $id='', $class='', $attrs=array()) {
450  if (is_null($label)) $label = $name;
451  if (is_null($value) || $value=='') $value='0';
452  $elem = array('_elem'=>'radiofield', '_text'=>$label, '_class'=>$class,
453                'id'=>$id, 'name'=>$name, 'value'=>$value);
454  return array_merge($elem, $attrs);
455}
456
457/**
458 * form_makeMenuField
459 *
460 * Create a form element for a drop-down menu with label.
461 * The list of values can be strings, arrays of (value,text),
462 * or an associative array with the values as keys and labels as values.
463 * An item is selected by supplying its value or integer index.
464 * If the list of values is an associative array, the selected item must be
465 * a string.
466 *
467 * @author  Tom N Harris <tnharris@whoopdedo.org>
468 */
469function form_makeMenuField($name, $values, $selected='', $label=null, $id='', $class='', $attrs=array()) {
470  if (is_null($label)) $label = $name;
471  $options = array();
472  reset($values);
473  // FIXME: php doesn't know the difference between a string and an integer
474  if (is_string(key($values))) {
475    foreach ($values as $val=>$text) {
476      $options[] = array($val,$text, (!is_null($selected) && $val==$selected));
477    }
478  } else {
479    if (is_integer($selected)) $selected = $values[$selected];
480    foreach ($values as $val) {
481      if (is_array($val))
482        @list($val,$text) = $val;
483      else
484        $text = null;
485      $options[] = array($val,$text,$val===$selected);
486    }
487  }
488  $elem = array('_elem'=>'menufield', '_options'=>$options, '_text'=>$label, '_class'=>$class,
489                'id'=>$id, 'name'=>$name);
490  return array_merge($elem, $attrs);
491}
492
493/**
494 * form_makeListboxField
495 *
496 * Create a form element for a list box with label.
497 * The list of values can be strings, arrays of (value,text),
498 * or an associative array with the values as keys and labels as values.
499 * Items are selected by supplying its value or an array of values.
500 *
501 * @author  Tom N Harris <tnharris@whoopdedo.org>
502 */
503function form_makeListboxField($name, $values, $selected='', $label=null, $id='', $class='', $attrs=array()) {
504  if (is_null($label)) $label = $name;
505  $options = array();
506  reset($values);
507  if (is_null($selected) || $selected == '')
508    $selected = array();
509  elseif (!is_array($selected))
510    $selected = array($selected);
511  // FIXME: php doesn't know the difference between a string and an integer
512  if (is_string(key($values))) {
513    foreach ($values as $val=>$text) {
514      $options[] = array($val,$text,in_array($val,$selected));
515    }
516  } else {
517    foreach ($values as $val) {
518      if (is_array($val))
519        @list($val,$text) = $val;
520      else
521        $text = null;
522      $options[] = array($val,$text,in_array($val,$selected));
523    }
524  }
525  $elem = array('_elem'=>'listboxfield', '_options'=>$options, '_text'=>$label, '_class'=>$class,
526                'id'=>$id, 'name'=>$name);
527  return array_merge($elem, $attrs);
528}
529
530/**
531 * form_tag
532 *
533 * Print the HTML for a generic empty tag.
534 * Requires '_tag' key with name of the tag.
535 * Attributes are passed to buildAttributes()
536 *
537 * @author  Tom N Harris <tnharris@whoopdedo.org>
538 */
539function form_tag($attrs) {
540  return '<'.$attrs['_tag'].' '.buildAttributes($attrs,true).'/>';
541}
542
543/**
544 * form_opentag
545 *
546 * Print the HTML for a generic opening tag.
547 * Requires '_tag' key with name of the tag.
548 * Attributes are passed to buildAttributes()
549 *
550 * @author  Tom N Harris <tnharris@whoopdedo.org>
551 */
552function form_opentag($attrs) {
553  return '<'.$attrs['_tag'].' '.buildAttributes($attrs,true).'>';
554}
555
556/**
557 * form_closetag
558 *
559 * Print the HTML for a generic closing tag.
560 * Requires '_tag' key with name of the tag.
561 * There are no attributes.
562 *
563 * @author  Tom N Harris <tnharris@whoopdedo.org>
564 */
565function form_closetag($attrs) {
566  return '</'.$attrs['_tag'].'>';
567}
568
569/**
570 * form_openfieldset
571 *
572 * Print the HTML for an opening fieldset tag.
573 * Uses the '_legend' key.
574 * Attributes are passed to buildAttributes()
575 *
576 * @author  Tom N Harris <tnharris@whoopdedo.org>
577 */
578function form_openfieldset($attrs) {
579  $s = '<fieldset '.buildAttributes($attrs,true).'>';
580  if (!is_null($attrs['_legend'])) $s .= '<legend>'.$attrs['_legend'].'</legend>';
581  return $s;
582}
583
584/**
585 * form_closefieldset
586 *
587 * Print the HTML for a closing fieldset tag.
588 * There are no attributes.
589 *
590 * @author  Tom N Harris <tnharris@whoopdedo.org>
591 */
592function form_closefieldset() {
593  return '</fieldset>';
594}
595
596/**
597 * form_hidden
598 *
599 * Print the HTML for a hidden input element.
600 * Uses only 'name' and 'value' attributes.
601 * Value is passed to formText()
602 *
603 * @author  Tom N Harris <tnharris@whoopdedo.org>
604 */
605function form_hidden($attrs) {
606  return '<input type="hidden" name="'.$attrs['name'].'" value="'.formText($attrs['value']).'" />';
607}
608
609/**
610 * form_wikitext
611 *
612 * Print the HTML for the wiki textarea.
613 * Requires '_text' with default text of the field.
614 * Text will be passed to formText(), attributes to buildAttributes()
615 *
616 * @author  Tom N Harris <tnharris@whoopdedo.org>
617 */
618function form_wikitext($attrs) {
619  // mandatory attributes
620  unset($attrs['name']);
621  unset($attrs['id']);
622  return '<textarea name="wikitext" id="wiki__text" '
623         .buildAttributes($attrs,true).'>'.NL
624         .formText($attrs['_text'])
625         .'</textarea>';
626}
627
628/**
629 * form_button
630 *
631 * Print the HTML for a form button.
632 * If '_action' is set, the button name will be "do[_action]".
633 * Other attributes are passed to buildAttributes()
634 *
635 * @author  Tom N Harris <tnharris@whoopdedo.org>
636 */
637function form_button($attrs) {
638  $p = (!empty($attrs['_action'])) ? 'name="do['.$attrs['_action'].']" ' : '';
639  return '<input '.$p.buildAttributes($attrs,true).'/>';
640}
641
642/**
643 * form_field
644 *
645 * Print the HTML for a form input field.
646 *   _class : class attribute used on the label tag
647 *   _text  : Text to display before the input. Not escaped.
648 * Other attributes are passed to buildAttributes() for the input tag.
649 *
650 * @author  Tom N Harris <tnharris@whoopdedo.org>
651 */
652function form_field($attrs) {
653  $s = '<label class="'.$attrs['_class'].'"';
654  if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
655  $s .= '><span>'.$attrs['_text'].'</span>';
656  $s .= ' <input '.buildAttributes($attrs,true).'/></label>';
657  if (preg_match('/(^| )block($| )/', $attrs['_class']))
658    $s .= '<br />';
659  return $s;
660}
661
662/**
663 * form_fieldright
664 *
665 * Print the HTML for a form input field. (right-aligned)
666 *   _class : class attribute used on the label tag
667 *   _text  : Text to display after the input. Not escaped.
668 * Other attributes are passed to buildAttributes() for the input tag.
669 *
670 * @author  Tom N Harris <tnharris@whoopdedo.org>
671 */
672function form_fieldright($attrs) {
673  $s = '<label class="'.$attrs['_class'].'"';
674  if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
675  $s .= '><input '.buildAttributes($attrs,true).'/>';
676  $s .= ' <span>'.$attrs['_text'].'</span></label>';
677  if (preg_match('/(^| )block($| )/', $attrs['_class']))
678    $s .= '<br />';
679  return $s;
680}
681
682/**
683 * form_textfield
684 *
685 * Print the HTML for a text input field.
686 *   _class : class attribute used on the label tag
687 *   _text  : Text to display before the input. Not escaped.
688 * Other attributes are passed to buildAttributes() for the input tag.
689 *
690 * @author  Tom N Harris <tnharris@whoopdedo.org>
691 */
692function form_textfield($attrs) {
693  // mandatory attributes
694  unset($attrs['type']);
695  $s = '<label class="'.$attrs['_class'].'"';
696  if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
697  $s .= '><span>'.$attrs['_text'].'</span> ';
698  $s .= '<input type="text" '.buildAttributes($attrs,true).'/></label>';
699  if (preg_match('/(^| )block($| )/', $attrs['_class']))
700    $s .= '<br />';
701  return $s;
702}
703
704/**
705 * form_passwordfield
706 *
707 * Print the HTML for a password input field.
708 *   _class : class attribute used on the label tag
709 *   _text  : Text to display before the input. Not escaped.
710 * Other attributes are passed to buildAttributes() for the input tag.
711 *
712 * @author  Tom N Harris <tnharris@whoopdedo.org>
713 */
714function form_passwordfield($attrs) {
715  // mandatory attributes
716  unset($attrs['type']);
717  $s = '<label class="'.$attrs['_class'].'"';
718  if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
719  $s .= '><span>'.$attrs['_text'].'</span> ';
720  $s .= '<input type="password" '.buildAttributes($attrs,true).'/></label>';
721  if (preg_match('/(^| )block($| )/', $attrs['_class']))
722    $s .= '<br />';
723  return $s;
724}
725
726/**
727 * form_checkboxfield
728 *
729 * Print the HTML for a checkbox input field.
730 *   _class : class attribute used on the label tag
731 *   _text  : Text to display after the input. Not escaped.
732 * Other attributes are passed to buildAttributes() for the input tag.
733 *
734 * @author  Tom N Harris <tnharris@whoopdedo.org>
735 */
736function form_checkboxfield($attrs) {
737  // mandatory attributes
738  unset($attrs['type']);
739  $s = '<label class="'.$attrs['_class'].'"';
740  if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
741  $s .= '><input type="checkbox" '.buildAttributes($attrs,true).'/>';
742  $s .= ' <span>'.$attrs['_text'].'</span></label>';
743  if (preg_match('/(^| )block($| )/', $attrs['_class']))
744    $s .= '<br />';
745  return $s;
746}
747
748/**
749 * form_radiofield
750 *
751 * Print the HTML for a radio button input field.
752 *   _class : class attribute used on the label tag
753 *   _text  : Text to display after the input. Not escaped.
754 * Other attributes are passed to buildAttributes() for the input tag.
755 *
756 * @author  Tom N Harris <tnharris@whoopdedo.org>
757 */
758function form_radiofield($attrs) {
759  // mandatory attributes
760  unset($attrs['type']);
761  $s = '<label class="'.$attrs['_class'].'"';
762  if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
763  $s .= '><input type="radio" '.buildAttributes($attrs,true).'/>';
764  $s .= ' <span>'.$attrs['_text'].'</span></label>';
765  if (preg_match('/(^| )block($| )/', $attrs['_class']))
766    $s .= '<br />';
767  return $s;
768}
769
770/**
771 * form_menufield
772 *
773 * Print the HTML for a drop-down menu.
774 *   _options : Array of (value,text,selected) for the menu.
775 *              Text can be omitted. Text and value are passed to formText()
776 *              Only one item can be selected.
777 *   _class : class attribute used on the label tag
778 *   _text  : Text to display before the menu. Not escaped.
779 * Other attributes are passed to buildAttributes() for the input tag.
780 *
781 * @author  Tom N Harris <tnharris@whoopdedo.org>
782 */
783function form_menufield($attrs) {
784  $attrs['size'] = '1';
785  $s = '<label class="'.$attrs['_class'].'"';
786  if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
787  $s .= '><span>'.$attrs['_text'].'</span>';
788  $s .= ' <select '.buildAttributes($attrs,true).'>'.NL;
789  if (!empty($attrs['_options'])) {
790    $selected = false;
791    for($n=0;$n<count($attrs['_options']);$n++){
792      @list($value,$text,$select) = $attrs['_options'][$n];
793      $p = '';
794      if (!is_null($text))
795        $p .= ' value="'.formText($value).'"';
796      else
797        $text = $value;
798      if (!empty($select) && !$selected) {
799        $p .= ' selected="selected"';
800        $selected = true;
801      }
802      $s .= '<option'.$p.'>'.formText($text).'</option>';
803    }
804  } else {
805    $s .= '<option></option>';
806  }
807  $s .= NL.'</select></label>';
808  if (preg_match('/(^| )block($| )/', $attrs['_class']))
809    $s .= '<br />';
810  return $s;
811}
812
813/**
814 * form_listboxfield
815 *
816 * Print the HTML for a list box.
817 *   _options : Array of (value,text,selected) for the list.
818 *              Text can be omitted. Text and value are passed to formText()
819 *   _class : class attribute used on the label tag
820 *   _text  : Text to display before the menu. Not escaped.
821 * Other attributes are passed to buildAttributes() for the input tag.
822 *
823 * @author  Tom N Harris <tnharris@whoopdedo.org>
824 */
825function form_listboxfield($attrs) {
826  $s = '<label class="'.$attrs['_class'].'"';
827  if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
828  $s .= '><span>'.$attrs['_text'].'</span> ';
829  $s = '<select '.buildAttributes($attrs,true).'>'.NL;
830  if (!empty($attrs['_options'])) {
831    foreach ($attrs['_options'] as $opt) {
832      @list($value,$text,$select) = $opt;
833      $p = '';
834      if (!is_null($text))
835        $p .= ' value="'.formText($value).'"';
836      else
837        $text = $value;
838      if (!empty($select)) $p .= ' selected="selected"';
839      $s .= '<option'.$p.'>'.formText($text).'</option>';
840    }
841  } else {
842    $s .= '<option></option>';
843  }
844  $s .= NL.'</select></label>';
845  if (preg_match('/(^| )block($| )/', $attrs['_class']))
846    $s .= '<br />';
847  return $s;
848}
849