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