[ Index ]
 

Code source de b2evolution 2.1.0-beta

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/blogs/inc/_core/ui/forms/ -> _form.class.php (source)

   1  <?php
   2  /**

   3   * This file implements the Fast Form handling class.

   4   *

   5   * This file is part of the evoCore framework - {@link http://evocore.net/}

   6   * See also {@link http://sourceforge.net/projects/evocms/}.

   7   *

   8   * @copyright (c)2003-2007 by Francois PLANQUE - {@link http://fplanque.net/}

   9   * Parts of this file are copyright (c)2004 by PROGIDISTRI - {@link http://progidistri.com/}.

  10   * Parts of this file are copyright (c)2004-2005 by Daniel HAHLER - {@link http://thequod.de/contact}.

  11   *

  12   * {@internal License choice

  13   * - If you have received this file as part of a package, please find the license.txt file in

  14   *   the same folder or the closest folder above for complete license terms.

  15   * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)

  16   *   then you must choose one of the following licenses before using the file:

  17   *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php

  18   *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php

  19   * }}

  20   *

  21   * {@internal Open Source relicensing agreement:

  22   * Daniel HAHLER grants Francois PLANQUE the right to license

  23   * Daniel HAHLER's contributions to this file and the b2evolution project

  24   * under any OSI approved OSS license (http://www.opensource.org/licenses/).

  25   *

  26   * PROGIDISTRI grants Francois PLANQUE the right to license

  27   * PROGIDISTRI's contributions to this file and the b2evolution project

  28   * under any OSI approved OSS license (http://www.opensource.org/licenses/).

  29   * }}

  30   *

  31   * @package evocore

  32   *

  33   * {@internal Below is a list of authors who have contributed to design/coding of this file: }}

  34   * @author blueyed: Daniel HAHLER

  35   * @author fplanque: Francois PLANQUE.

  36   * @author fsaya: Fabrice SAYA-GASNIER / PROGIDISTRI

  37   * @author mbruneau: Marc BRUNEAU / PROGIDISTRI

  38   *

  39   * @todo Provide buffering of whole Form to be able to add onsubmit-JS to enable/disabled

  40   *       (group) checkboxes again and other useful stuff.

  41   *

  42   * NOTE: we use an member array ($_common_params) for exchanging params between functions.

  43   * This will most probably cause problems, when nesting inputs. This should be refactored

  44   * to use a field_name-based member array. (blueyed)

  45   *

  46   * @version $Id: _form.class.php,v 1.16 2007/11/02 02:39:57 fplanque Exp $

  47   */
  48  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  49  
  50  load_funcs( '_core/ui/_uiwidget.class.php' );
  51  
  52  /**

  53   * Form class

  54   *

  55   * @package evocore

  56   */
  57  class Form extends Widget
  58  {
  59      /**

  60       * Output HTML or just return it?

  61       * @var boolean

  62       */
  63      var $output = true;
  64  
  65      /**

  66       * Remember number of open tags that need to be handled in {@link end_form()}.

  67       *

  68       * @var array

  69       */
  70      var $_opentags = array( 'fieldset' => 0 );
  71  
  72      /**

  73       * Suffix for LABELs.

  74       * @var string

  75       */
  76      var $label_suffix = ':';
  77  
  78  
  79      /**

  80       * Common params shared between methods.

  81       *

  82       * These can all be used with the $field_params argument of the functions.

  83       *

  84       * - 'note': The note associated with the field.

  85       * - 'note_format': The format of the note. %s gets replaced by the note.

  86       * - 'label': The label for the field.

  87       * - 'required': is the element required to be filled/checked? This will add a visual hint (boolean; default: false)

  88       *

  89       * @see handle_common_params()

  90       * @var array

  91       */
  92      var $_common_params = array();
  93  
  94      /**

  95       * This is the default note format, where {@link handle_common_params()} falls

  96       * back to, when not given with $field_params.

  97       * @todo This might be used in switch_layout().

  98       * @var string

  99       */
 100      var $note_format = ' <span class="notes">%s</span>';
 101  
 102      /**

 103       * This is a buffer for hidden fields. We'll display all of them just before the end of form </form>. This avoids having them caught in between table rows.

 104       *

 105       * @var string

 106       */
 107      var $hiddens = array();
 108  
 109      /**

 110       * Do we need to add javascript for check/uncheck all functionality

 111       */
 112      var $check_all = false;
 113  
 114      /**

 115       * Additional Javascript to append to the form, in {@link Form::end_form()}.

 116       *

 117       * @access protected

 118       * @var array

 119       */
 120      var $append_javascript = array();
 121  
 122      /**

 123       * Display param errors with fields, appended to the note?

 124       * @var boolean

 125       */
 126      var $disp_param_err_messages_with_fields = true;
 127  
 128      /**

 129       * Stack of previous used layouts

 130       * @see Form::switch_layout()

 131       * @var array

 132       */
 133      var $saved_layouts;
 134      var $saved_templates;
 135  
 136  
 137      /**

 138       * Constructor

 139       *

 140       * @param string the action destination of the form (NULL for pagenow)

 141       * @param string the name of the form (will be used as an ID)

 142       * @param string the action to execute when the form is submitted

 143       * @param string the method used to send data

 144       * @param string the form layout : 'fieldset', 'table' or '' (NULL means: if there is an {@link $AdminUI} object get it from there, otherwise use 'fieldset')

 145       */
 146  	function Form( $form_action = NULL, $form_name = '', $form_method = 'post', $layout = NULL, $enctype = '' )
 147      {
 148          global $AdminUI, $pagenow;
 149  
 150          $this->form_name = $form_name;
 151          $this->form_action = (is_null($form_action) ? $pagenow : $form_action );
 152          $this->form_method = $form_method;
 153          $this->enctype = $enctype;
 154  
 155          if( is_null( $layout ) || $layout == 'split' || $layout == 'none' )
 156          {
 157              if( is_object($AdminUI) )
 158              { // Get default skin setting:
 159                  $template = $AdminUI->get_template( 'Form' );
 160                  $layout = $template['layout'];
 161              }
 162              else
 163              {    // This happens for comment forms for example...
 164                  $layout = 'fieldset';
 165              }
 166          }
 167          elseif( $layout == 'compact' )
 168          {
 169              $template = $AdminUI->get_template( 'compact_form' );
 170              $layout = $template['layout'];
 171          }
 172  
 173          if( !isset($template) && $layout == 'fieldset' )
 174          {    // happens on login screen and after $layout setting above
 175              $template = array(
 176                  'layout' => 'fieldset',
 177                  'formstart' => '<div>',// required before (no_)title_fmt for validation
 178                  'title_fmt' => '<span style="float:right">$global_icons$</span><h2>$title$</h2>'."\n",
 179                  'no_title_fmt' => '<span style="float:right">$global_icons$</span>'."\n",
 180                  'fieldset_begin' => '<fieldset $fieldset_attribs$>'."\n"
 181                                                          .'<legend $title_attribs$>$fieldset_title$</legend>'."\n",
 182                  'fieldset_end' => '</fieldset>'."\n",
 183                  'fieldstart' => '<fieldset $ID$>'."\n",
 184                  'labelstart' => '<div class="label">',
 185                  'labelend' => "</div>\n",
 186                  'labelempty' => '<div class="label"></div>', // so that IE6 aligns DIV.input correcctly
 187                  'inputstart' => '<div class="input">',
 188                  'infostart' => '<div class="info">',
 189                  'inputend' => "</div>\n",
 190                  'fieldend' => "</fieldset>\n\n",
 191                  'buttonsstart' => '<fieldset><div class="input">',
 192                  'buttonsend' => "</div></fieldset>\n\n",
 193                  'formend' => '</div>',
 194              );
 195          }
 196  
 197          $this->saved_layouts = array($layout);
 198          $this->saved_templates = array($template);
 199          $this->switch_layout( NULL );    // "restore" saved layout.

 200  
 201      }
 202  
 203  
 204      /**

 205       * @param string|NULL the form layout : 'fieldset', 'table' or ''; NULL to restore previsouly saved layout

 206       */
 207  	function switch_layout( $layout )
 208      {
 209          if( $layout == NULL )
 210          { // we want to restore previous layout:
 211              if( count($this->saved_layouts) )
 212              {
 213                  $this->layout = array_shift($this->saved_layouts);
 214                  // Temporary hack:

 215                  $template = array_shift($this->saved_templates);
 216                  if( !empty($template ) )
 217                  {
 218                      //pre_dump($template);

 219                      $this->template =     $template;
 220                      $this->formstart =    $template['formstart'];
 221                      $this->title_fmt =    $template['title_fmt'];
 222                      $this->no_title_fmt = $template['no_title_fmt'];
 223                      $this->fieldstart =   $template['fieldstart'];
 224                      $this->labelstart =   $template['labelstart'];
 225                      $this->labelend =     $template['labelend'];
 226                      $this->labelempty =   $template['labelempty'];
 227                      $this->inputstart =   $template['inputstart'];
 228                      $this->infostart =    $template['infostart'];
 229                      $this->inputend =     $template['inputend'];
 230                      $this->fieldend =     $template['fieldend'];
 231                      $this->buttonsstart = $template['buttonsstart'];
 232                      $this->buttonsend =   $template['buttonsend'];
 233                      $this->formend =      $template['formend'];
 234                  }
 235              }
 236          }
 237          else
 238          { // We want to switch to a new layout
 239              array_unshift( $this->saved_layouts, $this->layout );
 240              $this->layout = $layout;
 241  
 242              switch( $this->layout )
 243              {
 244                  case 'table':
 245                      $this->formstart = '<table cellspacing="0" class="fform">'."\n";
 246                      // Note: no thead in here until you can safely add a tbody to the rest of the content...

 247                      $this->title_fmt = '<tr class="formtitle"><th colspan="2"><div class="results_title">'
 248                                                              .'<span class="right_icons">$global_icons$</span>'
 249                                                              .'$title$</div></th></tr>'."\n";
 250                      $this->no_title_fmt = '<tr><th colspan="2"><span class="right_icons">$global_icons$</span></th></tr>'."\n";
 251                      $this->fieldstart = '<tr $ID$>'."\n";
 252                      $this->labelstart = '<td class="label">';
 253                      $this->labelend = "</td>\n";
 254                      $this->labelempty = '<td class="label">&nbsp;</td>'."\n";
 255                      $this->inputstart = '<td class="input">';
 256                      $this->infostart = '<td class="info">';
 257                      $this->inputend = "</td>\n";
 258                      $this->fieldend = "</tr>\n\n";
 259                      $this->buttonsstart = '<tr class="buttons"><td colspan="2">';
 260                      $this->buttonsend = "</td></tr>\n";
 261                      $this->formend = "</table>\n";
 262                      break;
 263  
 264                  case 'fieldset':
 265                      $this->formstart = '<div>';// required before (no_)title_fmt for validation

 266                      $this->title_fmt = '<span style="float:right">$global_icons$</span><h2>$title$</h2>'."\n";
 267                      $this->no_title_fmt = '<span style="float:right">$global_icons$</span>'."\n";
 268                      $this->fieldstart = '<fieldset $ID$>'."\n";
 269                      $this->labelstart = '<div class="label">';
 270                      $this->labelend = "</div>\n";
 271                      $this->labelempty = '<div class="label"></div>'; // so that IE6 aligns DIV.input correcctly

 272                      $this->inputstart = '<div class="input">';
 273                      $this->infostart = '<div class="info">';
 274                      $this->inputend = "</div>\n";
 275                      $this->fieldend = "</fieldset>\n\n";
 276                      $this->buttonsstart = '<fieldset><div class="input">';
 277                      $this->buttonsend = "</div></fieldset>\n\n";
 278                      $this->formend = '</div>';
 279                      break;
 280  
 281                  case 'chicago':        // Temporary dirty hack
 282                      $this->formstart = '<div>';// required before (no_)title_fmt for validation

 283                      $this->title_fmt = '<span style="float:right">$global_icons$</span><h2>$title$</h2>'."\n";
 284                      $this->no_title_fmt = '<span style="float:right">$global_icons$</span>'."\n";
 285                      $this->fieldstart = '<fieldset $ID$>'."\n";
 286                      $this->labelstart = '<div class="label">';
 287                      $this->labelend = "</div>\n";
 288                      $this->labelempty = '<div class="label"></div>'; // so that IE6 aligns DIV.input correcctly

 289                      $this->inputstart = '<div class="input">';
 290                      $this->infostart = '<div class="info">';
 291                      $this->inputend = "</div>\n";
 292                      $this->fieldend = "</fieldset>\n\n";
 293                      $this->buttonsstart = '<fieldset><div class="input">';
 294                      $this->buttonsend = "</div></fieldset>\n\n";
 295                      $this->formend = '</div>';
 296                      break;
 297  
 298                  case 'linespan':
 299                      $this->formstart = '';
 300                      $this->title_fmt = '<span style="float:right">$global_icons$</span><h2>$title$</h2>'."\n";
 301                      $this->no_title_fmt = '<span style="float:right">$global_icons$</span>&nbsp;'."\n";
 302                      $this->fieldstart = '<div class="tile" $ID$>';
 303                      $this->labelstart = '<strong>';
 304                      $this->labelend = "</strong>\n";
 305                      $this->labelempty = '';
 306                      $this->inputstart = '';
 307                      $this->infostart = '';
 308                      $this->inputend = "\n";
 309                      $this->fieldend = "</div>\n";
 310                      $this->buttonsstart = '';
 311                      $this->buttonsend = "\n";
 312                      $this->formend = '';
 313                      break;
 314  
 315                  case 'blockspan':
 316                      $this->formstart = '';
 317                      $this->title_fmt = '$title$'."\n"; // TODO: icons

 318                      $this->no_title_fmt = '';          //           "

 319                      $this->fieldstart = '<span class="block" $ID$>';
 320                      $this->labelstart = '';
 321                      $this->labelend = "\n";
 322                      $this->labelempty = '';
 323                      $this->inputstart = '';
 324                      $this->infostart = '';
 325                      $this->inputend = "\n";
 326                      $this->fieldend = '</span>'.get_icon( 'pixel' )."\n";
 327                      $this->buttonsstart = '';
 328                      $this->buttonsend = "\n";
 329                      $this->formend = '';
 330                      break;
 331  
 332                  default:
 333                      // "none" (no layout)

 334                      $this->formstart = '';
 335                      $this->title_fmt = '$title$'."\n"; // TODO: icons

 336                      $this->no_title_fmt = '';          //           "

 337                      $this->fieldstart = ''; // fp> shall we still use $ID$ here ?

 338                      $this->labelstart = '';
 339                      $this->labelend = "\n";
 340                      $this->labelempty = '';
 341                      $this->inputstart = '';
 342                      $this->infostart = '';
 343                      $this->inputend = "\n";
 344                      $this->fieldend = "\n";
 345                      $this->buttonsstart = '';
 346                      $this->buttonsend = "\n";
 347                      $this->formend = '';
 348              }
 349  
 350          }
 351      }
 352  
 353  
 354      /**

 355       * Start an input field.

 356       *

 357       * A field is a fielset containing a label div and an input div.

 358       *

 359       * @uses $_common_params

 360       * @param string The name of the field

 361       * @param string The field label

 362       * @param boolean Reset {@link $_common_params}? This should be used if you build a field by yourself.

 363       * @return The generated HTML

 364       */
 365  	function begin_field( $field_name = NULL, $field_label = NULL, $reset_common_params = false )
 366      {
 367          if( $reset_common_params )
 368          {
 369              $this->_common_params = array();
 370          }
 371          // Remember these, to make them available to get_label()

 372          if( isset($field_name) )
 373          {
 374              $this->_common_params['name'] = $field_name;
 375          }
 376          if( isset($field_label) )
 377          {
 378              $this->_common_params['label'] = $field_label;
 379          }
 380  
 381          // Start the new form field and inject an automatic DOM id

 382          // This is useful to show/hide the whole field by JS.

 383          if( !empty(    $this->_common_params['id'] ) )
 384          {
 385              $ffield_id = 'id="ffield_'.$this->_common_params['id'].'" ';
 386          }
 387          else
 388          {    // No ID in case there's no id/name given for a field.
 389              $ffield_id = '';
 390          }
 391          $r = str_replace( '$ID$', $ffield_id, $this->fieldstart );
 392  
 393          if( isset($this->_common_params['field_prefix']) )
 394          {
 395              $r .= $this->_common_params['field_prefix'];
 396          }
 397  
 398          $r .= $this->get_label();
 399  
 400          $r .= $this->inputstart;
 401  
 402          return $r;
 403      }
 404  
 405  
 406      /**

 407       * End an input field.

 408       *

 409       * A field is a fielset containing a label div and an input div.

 410       *

 411       * @param string Field's note to display. (deprecated)

 412       * @param string Format of the field's note (%s gets replaced with the note). (deprecated)

 413       * @return The generated HTML

 414       */
 415  	function end_field( $field_note = NULL, $field_note_format = NULL )
 416      {
 417          if( isset($field_note) ) // Note: allow "0" as a note
 418          { // deprecated - should get set by calling handle_common_params()
 419              $this->_common_params['note'] = $field_note;
 420          }
 421          if( isset($field_note_format) )
 422          { // deprecated - should get set by calling handle_common_params()
 423              $this->_common_params['note_format'] = $field_note_format;
 424          }
 425  
 426          $r = '';
 427  
 428          if( !empty($this->_common_params['note']) )
 429          { // We have a note
 430              $r .= sprintf( $this->_common_params['note_format'], $this->_common_params['note'] );
 431          }
 432  
 433          if( isset($this->_common_params['field_suffix']) )
 434          {
 435              $r .= $this->_common_params['field_suffix'];
 436          }
 437  
 438          $r .= $this->inputend.$this->fieldend;
 439  
 440          return $r;
 441      }
 442  
 443  
 444      /**

 445       * Builds a fieldset tag. This is a fieldset element by default, but a th element

 446       * for table layout.

 447       *

 448       * @param string the title of the fieldset

 449       * @param string the field params to the fieldset

 450       *               additionally 'legend_params' can be used to give an array of field params

 451       * @return true|string true (if output) or the generated HTML if not outputting

 452       */
 453  	function begin_fieldset( $title = '', $field_params = array() )
 454      {
 455          if( !isset($field_params['class']) )
 456          {
 457              $field_params['class'] = 'fieldset';
 458          }
 459  
 460          switch( $this->layout )
 461          {
 462              case 'table':
 463                  $r = '<tr'.get_field_attribs_as_string($field_params).'><th colspan="2">'."\n";
 464                  // NOTE: empty THs can be rendered and/or are DHTML scriptable

 465  
 466                  if( $title != '' )
 467                  { // there is a title to display
 468                      $r .= $title;
 469                  }
 470  
 471                  $r .= "</th></tr>\n";
 472                  break;
 473  
 474              default:
 475                  if( ! empty($field_params['legend_params']) )
 476                  {    // We have params specifically passed for the title
 477                      $legend_params = $field_params['legend_params'];
 478                      unset( $field_params['legend_params'] );
 479                  }
 480  
 481                  $r = str_replace( '$fieldset_attribs$', get_field_attribs_as_string($field_params), $this->template['fieldset_begin'] );
 482                  // $r = '<fieldset'.get_field_attribs_as_string($field_params).'>'."\n";

 483  
 484                  $r = str_replace( '$fieldset_title$', $title, $r );
 485  
 486                  if( empty($legend_params) )
 487                  { // there are no legend_params, remove the placeholder
 488                      $r = str_replace( '$title_attribs$', '', $r );
 489                  }
 490                  else
 491                  {
 492                      $r = str_replace( '$title_attribs$', get_field_attribs_as_string($legend_params), $r );
 493                  }
 494  
 495                  $this->_opentags['fieldset']++;
 496          }
 497  
 498          return $this->display_or_return( $r );
 499      }
 500  
 501  
 502      /**

 503       * Ends a fieldset.

 504       *

 505       * @return true|string true (if output) or the generated HTML if not outputting

 506       */
 507  	function end_fieldset()
 508      {
 509          switch( $this->layout )
 510          {
 511              case 'table':
 512                  $r = '';
 513                  break;
 514  
 515              default:
 516                  $r = $this->template['fieldset_end'];
 517                  $this->_opentags['fieldset']--;
 518          }
 519  
 520          return $this->display_or_return( $r );
 521      }
 522  
 523  
 524      /**

 525       * Builds a text (or password) input field.

 526       *

 527       * Note: please use {@link Form::password_input()} for password fields.

 528       *

 529       * @param string The name of the input field. This gets used for id also, if no id given in $field_params.

 530       * @param string Initial value

 531       * @param integer Size of the input field

 532       * @param string Label displayed with the field

 533       * @param string "help" note (Should provide something useful, otherwise leave it empty)

 534       * @param array Extended attributes/params.

 535       *                 - 'maxlength': if not set, $field_size gets used (use '' to disable it)

 536       *                 - 'class': the CSS class to use for the <input> element

 537       *                 - 'type': 'text', 'password' (defaults to 'text')

 538       *                 - 'force_to': 'UpperCase' (JS onchange handler)

 539       *                 - NOTE: any other attributes will be used as is (onchange, onkeyup, id, ..).

 540       * @return true|string true (if output) or the generated HTML if not outputting

 541       */
 542  	function text_input( $field_name, $field_value, $field_size, $field_label, $field_note = '', $field_params = array() )
 543      {
 544          $field_params['value'] = $field_value;
 545  
 546          if( !empty($field_note) )
 547          {
 548              $field_params['note'] = $field_note;
 549          }
 550  
 551          if( !empty($field_size) )
 552          {
 553              if( !isset($field_params['maxlength']) )
 554              { // maxlength defaults to size
 555                  $field_params['maxlength'] = $field_size;
 556              }
 557  
 558              $field_params['size'] = $field_size;
 559          }
 560  
 561          if( !isset($field_params['type']) )
 562          { // type defaults to "text"
 563              $field_params['type'] = 'text';
 564          }
 565  
 566          if( isset($field_params['force_to']) )
 567          {
 568              if( $field_params['force_to'] == 'UpperCase' )
 569              { // Force input to uppercase (at front of onchange event)
 570                  $field_params['onchange'] = 'this.value = this.value.toUpperCase();'
 571                      .( empty($field_params['onchange']) ? '' : ' '.$field_params['onchange'] );
 572              }
 573              unset($field_params['force_to']); // not a html attrib

 574          }
 575  
 576          // Give it a class, so it can be selected for CSS in IE6

 577          if( empty($field_params['class']) ) $field_params['class'] = 'form_text_input';
 578          else $field_params['class'] .= ' form_text_input';
 579  
 580          $field_params['name'] = $field_name;
 581          $field_params['label'] = $field_label;
 582          return $this->input_field( $field_params );
 583      }
 584  
 585  
 586      /**

 587       * Builds a text (or password) input field.

 588       *

 589       * Note: please use {@link Form::password()} for password fields

 590       *

 591       * @param string the name of the input field

 592       * @param string initial value

 593       * @param integer size of the input field

 594       * @param string label displayed in front of the field

 595       * @param string note displayed with field

 596       * @param integer max length of the value (if 0 field_size will be used!)

 597       * @param string the CSS class to use

 598       * @param string input type (only 'text' or 'password' makes sense)

 599       * @return mixed true (if output) or the generated HTML if not outputting

 600       */
 601  	function text( $field_name, $field_value, $field_size, $field_label, $field_note = '',
 602                                              $field_maxlength = 0, $field_class = '', $inputtype = 'text', $force_to = '' )
 603      {
 604          $field_params = array();
 605  
 606          if( $field_maxlength !== 0 )
 607          {
 608              $field_params['maxlength'] = $field_maxlength;
 609          }
 610          if( $field_class !== '' )
 611          {
 612              $field_params['class'] = $field_class;
 613          }
 614          if( $inputtype !== 'text' )
 615          {
 616              $field_params['type'] = $inputtype;
 617          }
 618          if( $force_to !== '' )
 619          {
 620              $field_params['force_to'] = $force_to;
 621          }
 622  
 623          return $this->text_input( $field_name, $field_value, $field_size, $field_label, $field_note, $field_params );
 624      }
 625  
 626  
 627      /**

 628       * Builds a password input field.

 629       *

 630       * Calls the text_input() method with type == 'password'.

 631       *

 632       * @param string The name of the input field. This gets used for id also, if no id given in $field_params.

 633       * @param string Initial value

 634       * @param integer Size of the input field

 635       * @param string Label displayed in front of the field

 636       * @param string Note displayed with field

 637       * @param integer Max length of the value (if 0 field_size will be used!)

 638       * @param string Extended attributes, see {@link text_input()}.

 639       * @return mixed true (if output) or the generated HTML if not outputting

 640       */
 641  	function password_input( $field_name, $field_value, $field_size, $field_label, $field_params = array() )
 642      {
 643          $field_params['type'] = 'password';
 644  
 645          return $this->text_input( $field_name, $field_value, $field_size, $field_label, '', $field_params );    // TEMP: Note already in params

 646      }
 647  
 648  
 649      /**

 650       * Builds a password input field.

 651       *

 652       * Calls the text() method with a 'password' parameter.

 653       *

 654       * @param string the name of the input field

 655       * @param string initial value

 656       * @param integer size of the input field

 657       * @param string label displayed in front of the field

 658       * @param string note displayed with field

 659       * @param integer max length of the value (if 0 field_size will be used!)

 660       * @param string the CSS class to use

 661       * @return mixed true (if output) or the generated HTML if not outputting

 662       */
 663  	function password( $field_name, $field_value, $field_size, $field_label, $field_note = '',
 664                                              $field_maxlength = 0 , $field_class = '' )
 665      {
 666          $field_params = array( 'type' => 'password' );
 667  
 668          if( $field_maxlength !== 0 )
 669          {
 670              $field_params['maxlength'] = $field_maxlength;
 671          }
 672          if( !empty($field_class) )
 673          {
 674              $field_params['class'] = $field_class;
 675          }
 676  
 677          return $this->text_input( $field_name, $field_value, $field_size, $field_label, $field_note, $field_params );
 678      }
 679  
 680  
 681      /**

 682       * Builds a date input field.

 683       *

 684       * @param string the name of the input field

 685       * @param string initial value (ISO datetime (YYYY-MM-DD HH:MM:SS)

 686       *               or erroneous if the field is in error state)

 687       * @param string label displayed in front of the field

 688       * @param array Optional params. Additionally to {@link $_common_params} you can use:

 689       *              - date_format: Format of the date (string, PHP format, default taken from {@link locale_datefmt()})

 690       *              - add_date_format_note: If true, date format note gets prepended to the field's note

 691       * @return mixed true (if output) or the generated HTML if not outputting

 692       */
 693  	function date_input( $field_name, $field_value, $field_label, $field_params = array() )
 694      {
 695          global $month, $weekday_letter;
 696  
 697          if( empty($field_params['date_format']) )
 698          {    // Use locale date format:
 699              $date_format = locale_datefmt();
 700          }
 701          else
 702          {
 703              $date_format = $field_params['date_format'];
 704          }
 705          // Don't keep that attrib in the list:

 706          unset( $field_params['date_format'] );
 707  
 708          // Convert PHP date format to JS library date format (date.js):

 709          // NOTE: when editing/extending this here, you probably also have to adjust param_check_date()!

 710          $js_date_format = preg_replace_callback( '~(\\\)?(\w)~', create_function( '$m', '
 711              if( $m[1] == "\\\" ) return "\\\".$m[0]; // leave escaped

 712              switch( $m[2] )
 713              {
 714                  case "d": return "dd"; // day, 01-31

 715                  case "j": return "d"; // day, 1-31

 716                  case "l": return "EE"; // weekday (name)

 717                  case "D": return "E"; // weekday (abbr)

 718                  case "e": return ""; // weekday letter, not supported

 719  
 720                  case "m": return "MM"; // month, 01-12

 721                  case "n": return "M"; // month, 1-12

 722                  case "F": return "MMM"; // full month name; "name or abbr" in date.js

 723                  case "M": return "NNN"; // month name abbr

 724  
 725                  case "y": return "yy"; // year, 00-99

 726                  case "Y": return "yyyy"; // year, XXXX

 727                  default:
 728                      return $m[0];
 729              }' ), $date_format );
 730          #pre_dump( $js_date_format );

 731  
 732          if( param_has_error( $field_name ) )
 733          { // There is an error message for this field:
 734  
 735              // We do not try to format the date, we keep the erroneous date.

 736              //echo 'error on '.$field_name.' keep erroneous entry intact ';

 737  
 738              $field_params['value'] = trim(substr( $field_value, 0, 10 ));
 739          }
 740          else
 741          { // Make the date value clean for display:
 742  
 743              // The date value may be compact, in this case we have to decompact it

 744              if( preg_match( '/^[0-9]+$/', $field_value ) )
 745              {    // The date is compact, so we decompact it
 746                  $field_value = decompact_date( $field_value );
 747              }
 748  
 749              // Get DATE part of datetime and format it to locale format:

 750              $field_params['value'] = mysql2date( $date_format, $field_value );
 751          }
 752  
 753  
 754          if( !empty($field_params['add_date_format_note']) )
 755          { // Prepend $date_format to note
 756              $field_params['note'] = empty($field_params['note'])
 757                  ? '('.$date_format.')'
 758                  : '('.$date_format.') '.$field_params['note'];
 759          }
 760          unset( $field_params['add_date_format_note'] );
 761  
 762  
 763          if( !isset($field_params['size']) )
 764          { // Get size out of $date_format if not explicitly set
 765              $field_params['size'] = strlen( $js_date_format );
 766          }
 767  
 768          /*

 769          dh> do not use maxlength by default. Makes no sense IMHO and fails with dateformats like "j \d\e F, Y"

 770          if( !isset($field_params['maxlength']) )

 771          {

 772              $field_params['maxlength'] = $field_params['size'];

 773          }

 774          */
 775  
 776          // Give it a class, so it can be selected for CSS in IE6

 777          if( empty($field_params['class']) ) $field_params['class'] = 'form_date_input';
 778          else $field_params['class'] .= ' form_date_input';
 779  
 780  
 781          $this->handle_common_params( $field_params, $field_name, $field_label );
 782  
 783          $r = $this->begin_field()
 784                  .'<script type="text/javascript">
 785                          //<![CDATA[

 786                          var cal_'.$field_name.' = new CalendarPopup();
 787                          cal_'.$field_name.'.showYearNavigation();
 788                          cal_'.$field_name.'.showNavigationDropdowns();
 789                          // cal_'.$field_name.'.showYearNavigationInput();

 790                          // MonthNames get set through MONTH_NAMES

 791                     cal_'.$field_name.'.setDayHeaders( '
 792                              ."'".T_($weekday_letter[0])."',"
 793                              ."'".T_($weekday_letter[1])."',"
 794                              ."'".T_($weekday_letter[2])."',"
 795                              ."'".T_($weekday_letter[3])."',"
 796                              ."'".T_($weekday_letter[4])."',"
 797                              ."'".T_($weekday_letter[5])."',"
 798                              ."'".T_($weekday_letter[6])."' );\n"
 799                  .' cal_'.$field_name.'.setWeekStartDay('.locale_startofweek().');
 800                          cal_'.$field_name.".setTodayText('".TS_('Today')."');
 801                          //]]>

 802                      </script>\n"
 803                  .$this->get_input_element($field_params, false)
 804                  .'<a href="#" onclick="cal_'.$field_name.".select(document.getElementById('".$field_name."'), 'anchor_".$field_name."', '".$js_date_format."');"
 805                  .' return false;" name="anchor_'.$field_name.'" id="anchor_'.$this->get_valid_id($field_name).'" title="'.T_('Select date').'">'
 806                  .get_icon( 'calendar', 'imgtag', array( 'title'=>T_('Select date') ) ).'</a>';
 807  
 808          $r .= $this->end_field();
 809  
 810          return $this->display_or_return( $r );
 811      }
 812  
 813  
 814      /**

 815       * Builds a date input field.

 816       *

 817       * @param string the name of the input field

 818       * @param string initial value (ISO datetime)

 819       * @param string label displayed in front of the field

 820       * @param string date format (php format)

 821       * @return mixed true (if output) or the generated HTML if not outputting

 822       */
 823  	function date( $field_name, $field_value, $field_label, $date_format = NULL )
 824      {
 825          $field_params = array( 'date_format' => $date_format, 'type' => 'text' );
 826  
 827          return $this->date_input( $field_name, $field_value, $field_label, $field_params );
 828      }
 829  
 830  
 831      /**

 832       * Builds a time input field.

 833       *

 834       * @param string The name of the input field

 835       * @param string Initial value (ISO datetime)

 836       * @param string Label displayed in front of the field

 837       * @param array Optional params. Additionally to {@link $_common_params} you can use:

 838       *              - 'time_format': Format of the time (string, default 'hh:mm:ss')

 839       * @return mixed true (if output) or the generated HTML if not outputting

 840       */
 841  	function time_input( $field_name, $field_value, $field_label, $field_params = array() )
 842      {
 843          if( isset($field_params['time_format']) )
 844          {
 845              $field_format = '('.$field_params['time_format'].')';
 846              unset( $field_params['time_format'] ); // not an attribute

 847          }
 848          else
 849          {
 850              $field_format = '(hh:mm:ss)';
 851          }
 852  
 853          // Prepend format to note

 854          if( isset($field_params['note']) )
 855          {
 856              $field_params['note'] = $field_format.' '.$field_params['note'];
 857          }
 858          else
 859          {
 860              $field_params['note'] = $field_format;
 861          }
 862  
 863          $field_size = strlen($field_format);
 864  
 865          // Get time part of datetime:

 866          $field_value = substr( $field_value, 11, 8 );
 867  
 868          return $this->text_input( $field_name, $field_value, $field_size, $field_label, '', $field_params ); // TEMP: Note already in params

 869      }
 870  
 871  
 872      /**

 873       * Builds a time input field.

 874       *

 875       * @param string the name of the input field

 876       * @param string initial value (ISO datetime)

 877       * @param string label displayed in front of the field

 878       * @return mixed true (if output) or the generated HTML if not outputting

 879       */
 880  	function time( $field_name, $field_value, $field_label, $field_format = 'hh:mm:ss' )
 881      {
 882          $field_params = array( 'time_format' => $field_format );
 883  
 884          return $this->time_input( $field_name, $field_value, $field_label, $field_params );
 885      }
 886  
 887  
 888      /**

 889       * Builds a time select input field

 890       *

 891       * @param string field name

 892       * @param string initial value (ISO datetime or time only)

 893       * @param string precison xmn or xsec (x:integer) for the options minutes or secondes

 894       * @param string field label to be display before the field

 895       * @param string note to be displayed after the field

 896       * @param string CSS class for select

 897       * @param string Javascript to add for onchange event (trailing ";").

 898       */
 899  	function time_select( $field_name, $field_value = NULL, $precision = '5mn', $field_label, $field_note = NULL, $field_class = NULL, $field_onchange = NULL )
 900      {
 901          preg_match( '#([0-9]+)(mn|s)#', $precision, $matches );
 902  
 903          if( !isset( $matches[1] ) && !isset( $matches[2] ) )
 904          {    // precison has a bad format
 905              return;
 906          }
 907  
 908          $field_params = array(
 909          'note' => $field_note,
 910          'class' => $field_class,
 911          'onchange' => $field_onchange );
 912  
 913          /***  instantiate the precison for the minutes and secondes select options  ****/

 914  
 915          if( $matches[2] == 'mn' )
 916          {
 917              $precision_mn = $matches[1];
 918              $precision_s = 0;
 919              // convert the precision in sec

 920              $precision *= 60;
 921          }
 922          else
 923          {
 924              $precision_mn = 1;
 925              $precision_s = $matches[1];
 926          }
 927  
 928          // Check if field value is only a time

 929          if( strlen( $field_value ) <= 8 )
 930          {    // Add date part:
 931              $field_value = '2000-01-01 '.$field_value;
 932          }
 933  
 934          /***  set round time with the precision  ***/

 935          // Get nb sec since unix...

 936          $nbsec = mysql2timestamp( $field_value );
 937          $modulo =  $nbsec % $precision;
 938  
 939          if( $modulo < ( $precision / 2 ) )
 940          { // The round time is before
 941              $nbsec -= $modulo;
 942          }
 943          else
 944          { // The round time is after
 945              $nbsec += $precision - $modulo;
 946          }
 947  
 948          /******************************************************/

 949  
 950          $this->handle_common_params( $field_params, $field_name, $field_label );
 951  
 952          $r = $this->begin_field();
 953  
 954          /**********   select options for the hours *************/

 955  
 956          $field_params['name'] = $field_name . '_h';
 957          $field_params['id'] = $field_params['name'];
 958          // Get Hour part of datetime:

 959          $hour = date( 'H', $nbsec );
 960  
 961          $r .= $this->_number_select(  $hour, 23 , 1, $field_params);
 962  
 963          /*********  select options for the minutes *************/

 964  
 965          $field_params['name'] = $field_name . '_mn';
 966          $field_params['id'] = $field_params['name'];
 967          // Get Minute part of datetime:

 968          $minute = date('i',$nbsec);
 969  
 970          $r .= ':'.$this->_number_select(  $minute, 59, $precision_mn, $field_params);
 971  
 972          if( $precision_s )
 973          {/*********  select options for the minutes  ***********/
 974  
 975              $field_params['name'] = $field_name . '_s';
 976              $field_params['id'] = $field_params['name'];
 977              // Get Secondes part of datetime:

 978              $seconde = substr( $field_value, 17, 2 );
 979  
 980              $r .=':'.$this->_number_select(  $seconde, 59, $precision_s, $field_params);
 981          }
 982  
 983          $r .= $this->end_field();
 984  
 985          return $this->display_or_return( $r );
 986      }
 987  
 988  
 989      /**

 990       * Buil a select input field number

 991       * @access private

 992       *

 993       * @param string     field value of selected

 994       * @param integer maximum value for the input select

 995       * @param integer increment for the loop (precision)

 996       * @param array params

 997       */
 998  	function _number_select( $field_value, $max, $precision = 1, $field_params )
 999      {
1000              $r    =    '<select'.get_field_attribs_as_string( $field_params ).'>';
1001  
1002              for( $i=0; $i <= $max ; $i += $precision)
1003              {
1004                  $val = sprintf( '%02d', $i );
1005                  $r .= '<option value="'.$val.'"'.
1006                                  ($field_value == $val ? ' selected="selected"' : '') .
1007                                  '>'    .$val.'</option>';
1008              }
1009  
1010              $r .= '</select>';
1011  
1012              return $r;
1013      }
1014  
1015  
1016      /**

1017       * Builds a duration input field.

1018       *

1019       * @todo @Francois: please check API and change as appropriate.

1020       *

1021       * @param string the name of the input field

1022       * @param string initial value (seconds)

1023       * @param string label displayed in front of the field

1024       * @param array Optional params. Additionally to {@link $_common_params} you can use:

1025       *              - minutes_step ( default = 15 );

1026       * @return mixed true (if output) or the generated HTML if not outputting

1027       */
1028  	function duration_input( $field_prefix, $duration, $field_label, $field_params = array() )
1029      {
1030          $this->handle_common_params( $field_params, $field_prefix, $field_label );
1031  
1032          $r = $this->begin_field();
1033  
1034          $days = floor( $duration / 86400 ); // 24 hours

1035          $r .= "\n".'<select name="'.$field_prefix.'_days" id="'.$this->get_valid_id($field_prefix).'_days">';
1036          $r .= '<option value="0"'.( 0 == $days ? ' selected="selected"' : '' ).">---</option>\n";
1037          for( $i = 1; $i <= 30; $i++ )
1038          {
1039              $r .= '<option value="'.$i.'"'.( $i == $days ? ' selected="selected"' : '' ).'>'.$i."</option>\n";
1040          }
1041          $r .= '</select>'.T_('days')."\n";
1042  
1043          $hours = floor( $duration / 3600 ) % 24;
1044          $r .= "\n".'<select name="'.$field_prefix.'_hours" id="'.$this->get_valid_id($field_prefix).'_hours">';
1045          $r .= '<option value="0"'.( 0 == $hours ? ' selected="selected"' : '' ).">---</option>\n";
1046          for( $i = 1; $i <= 23; $i++ )
1047          {
1048              $r .= '<option value="'.$i.'"'.( $i == $hours ? ' selected="selected"' : '' ).'>'.$i."</option>\n";
1049          }
1050          $r .= '</select>'.T_('hours')."\n";
1051  
1052          $minutes = floor( $duration / 60 ) % 60;
1053          $minutes_step = ( empty($field_params['minutes_step']) ? 15 : $field_params['minutes_step'] );
1054          $r .= "\n".'<select name="'.$field_prefix.'_minutes" id="'.$this->get_valid_id($field_prefix).'_minutes">';
1055          for( $i = 0; $i <= 59 ; $i += $minutes_step )
1056          {
1057              $r .= '<option value="'.$i.'"'.( ($minutes>=$i && $minutes<($i+$minutes_step)) ? ' selected="selected"' : '' ).'>'
1058                          .($i == 0 ? '---' : substr('0'.$i,-2))."</option>\n";
1059          }
1060          $r .= '</select>'.T_('minutes')."\n";
1061  
1062          $r .= $this->end_field();
1063  
1064          return $this->display_or_return( $r );
1065      }
1066  
1067  
1068      /**

1069       * Builds a duration input field.

1070       *

1071       * @param string the name of the input field

1072       * @param string initial value (seconds)

1073       * @param string label displayed in front of the field

1074       * @return mixed true (if output) or the generated HTML if not outputting

1075       */
1076  	function duration( $field_prefix, $duration, $field_label )
1077      {
1078          return $this->duration_input( $field_prefix, $duration, $field_label );
1079      }
1080  
1081  
1082      /**

1083       * Build a select to choose a weekday.

1084       *

1085       * @uses select_input_options()

1086       *

1087       * @return true|string

1088       */
1089  	function dayOfWeek_input( $field_name, $field_value, $field_label, $field_params = array() )
1090      {
1091          global $weekday_abbrev;
1092  
1093          $field_options = '';
1094  
1095          foreach( $weekday_abbrev as $lNumber => $lWeekday )
1096          {
1097              $field_options .= '<option';
1098  
1099              if( $field_value == $lNumber )
1100              {
1101                  $field_options .= ' selected="selected"';
1102              }
1103              $field_options .= ' value="'.$lNumber.'">'.T_($lWeekday).'</option>';
1104          }
1105  
1106          return $this->select_input_options( $field_name, $field_options, $field_label, '', $field_params );
1107      }
1108  
1109  
1110      /**

1111       * Build a select to choose a weekday.

1112       *

1113       * @return true|string

1114       */
1115  	function dayOfWeek( $field_name, $field_value, $field_label, $field_note = NULL, $field_class = NULL )
1116      {
1117          $field_params = array();
1118          if( isset($field_note) )
1119          {
1120              $field_params['note'] = $field_note;
1121          }
1122  
1123          if( isset($field_class) )
1124          {
1125              $field_params['class'] = $field_class;
1126          }
1127  
1128          return $this->dayOfWeek_input( $field_name, $field_value, $field_label, $field_params );
1129      }
1130  
1131  
1132      /**

1133       * Builds a checkbox field

1134       *

1135       * @param string the name of the checkbox

1136       * @param boolean indicating if the checkbox must be checked by default

1137       * @param string label

1138       * @param array Optional params. Additionally to {@link $_common_params} you can use:

1139       *              'value': the value attribute of the checkbox (default 1)

1140       * @return mixed true (if output) or the generated HTML if not outputting

1141       */
1142  	function checkbox_input( $field_name, $field_checked, $field_label, $field_params = array() )
1143      {
1144          $field_params['name'] = $field_name;
1145          $field_params['label'] = $field_label;
1146          $field_params['type'] = 'checkbox';
1147  
1148          if( !isset($field_params['value']) )
1149          {
1150              $field_params['value'] = 1;
1151          }
1152  
1153          if( $field_checked )
1154          {
1155              $field_params['checked'] = 'checked';
1156          }
1157  
1158          if( !isset($field_params['class']) )
1159          {
1160              $field_params['class'] = 'checkbox';
1161          }
1162  
1163          return $this->input_field( $field_params );
1164      }
1165  
1166  
1167      /*

1168       * EXPERIMENTAL: simpler method of obtaining basic checkboxes

1169       */
1170  	function checkbox_basic_input( $field_name, $field_checked, $field_label, $field_params = array() )
1171      {
1172          $field_params['name'] = $field_name;
1173          $field_params['type'] = 'checkbox';
1174  
1175          if( !isset($field_params['value']) )
1176          {
1177              $field_params['value'] = 1;
1178          }
1179  
1180          if( $field_checked )
1181          {
1182              $field_params['checked'] = 'checked';
1183          }
1184  
1185          if( !isset($field_params['class']) )
1186          {
1187              $field_params['class'] = 'checkbox';
1188          }
1189  
1190          echo '<label>';
1191          echo $this->get_input_element($field_params);
1192          echo $field_label;
1193          echo '</label>';
1194      }
1195  
1196  
1197      /**

1198       * Builds a checkbox field

1199       *

1200       * @param string the name of the checkbox

1201       * @param boolean indicating if the checkbox must be checked

1202       * @param string label

1203       * @param string note

1204       * @param string CSS class

1205       * @param string value to use

1206       * @param boolean an optional indicating whether the box is disabled or not

1207       * @return mixed true (if output) or the generated HTML if not outputting

1208       */
1209  	function checkbox( $field_name, $field_checked, $field_label, $field_note = '',
1210                                              $field_class = '', $field_value = 1, $field_disabled = false )
1211      {
1212          $field_params = array();
1213  
1214          if( $field_note !== '' )
1215          {
1216              $field_params['note'] = $field_note;
1217          }
1218          if( $field_class !== '' )
1219          {
1220              $field_params['class'] = $field_class;
1221          }
1222          if( $field_value !== 1 )
1223          {
1224              $field_params['value'] = $field_value;
1225          }
1226          if( $field_disabled != false )
1227          {
1228              $field_params['disabled'] = 'disabled';
1229          }
1230  
1231          return $this->checkbox_input( $field_name, $field_checked, $field_label, $field_params );
1232      }
1233  
1234  
1235      /**

1236       * Return links to check and uncheck all check boxes of the form

1237       */
1238  	function check_all()
1239      {
1240          // Need to add event click on links at the form end.

1241          $this->check_all = true;
1242  
1243          // fp> This is "name=" and I mean it!!! The JS is looking for all elements with this name!

1244          return '<a name="check_all_nocheckchanges" href="'.regenerate_url().'">'
1245                  //.T_('Check all').' '

1246                  .get_icon( 'check_all', 'imgtag', NULL, true )
1247                  .'</a> | <a name="uncheck_all_nocheckchanges" href="'.regenerate_url().'">'
1248                  //.T_('Uncheck all').' '

1249                  .get_icon( 'uncheck_all', 'imgtag', NULL, true ).'</a> '.'&nbsp;';
1250      }
1251  
1252  
1253      /**

1254       * Builds the form field

1255       *

1256       * @param string the class to use for the form tag

1257       * @param string title to display on top of the form

1258       * @param array Additional params to the form element. See {@link $_common_params}.

1259       *              These may override class members.

1260       * @return mixed true (if output) or the generated HTML if not outputting

1261       */
1262  	function begin_form( $form_class = NULL, $form_title = '', $form_params = array() )
1263      {
1264          $this->handle_common_params( $form_params, NULL /* "name" attribute is deprecated in xhtml */ );
1265  
1266          if( ! empty($this->form_name) )
1267          {
1268              $form_params['id'] = $this->form_name;
1269          }
1270  
1271          // Set non-mandatory attributes if given in $form_params

1272          if( !isset($form_params['enctype']) && !empty( $this->enctype ) )
1273          {
1274              $form_params['enctype'] = $this->enctype;
1275          }
1276  
1277          if( !isset($form_params['class']) && !empty( $form_class ) )
1278          {
1279              $form_params['class'] = $form_class;
1280          }
1281  
1282          if( !isset($form_params['method']) )
1283          {
1284              $form_params['method'] = $this->form_method;
1285          }
1286  
1287          if( !isset($form_params['action']) )
1288          {
1289              $form_params['action'] = $this->form_action;
1290          }
1291  
1292          if( !empty($form_params['bozo_start_modified']) )
1293          {
1294              $bozo_start_modified = true;
1295              unset( $form_params['bozo_start_modified'] );
1296          }
1297  
1298          $r = "\n\n<form".get_field_attribs_as_string($form_params).">\n";
1299  
1300          // $r .= '<div>'; // for XHTML (dh> removed 'style="display:inline"' because it's buggy with FireFox 1.0.x, at least at the "Write" admin page; see http://forums.b2evolution.net/viewtopic.php?t=10130)

1301          // fp> inline was needed for inline forms like the DELETE confirmation.

1302          // fp> why does XHTML require all forms to have an embedded DIV?

1303  
1304          $r .= $this->formstart;
1305  
1306          if( empty($form_title) )
1307          {
1308              $r .= $this->replace_vars( $this->no_title_fmt );
1309          }
1310          else
1311          {
1312              $this->title = $form_title;
1313  
1314              $r .= $this->replace_vars( $this->title_fmt );
1315          }
1316  
1317          // Initialization of javascript vars used to create parent_child select lists

1318          // TODO: does this make sense to add it to every form??

1319          $r .= '<script type="text/javascript">
1320                              var nb_dynamicSelects = 0;
1321                              var tab_dynamicSelects = Array();
1322                          </script>';
1323  
1324          global $UserSettings;
1325          if( isset($UserSettings) && $UserSettings->get( 'control_form_abortions' )
1326              && preg_match( '#^(.*)_checkchanges#', $this->form_name ) )
1327          { // This form will trigger the bozo validator, preset a localized bozo confirm message:
1328  
1329              $r .= '<script type="text/javascript">
1330                      if( typeof bozo == "object" )
1331                      {    // If Bozo validator is active:
1332                          bozo.confirm_mess = \'';
1333              if( empty( $this->title ) )
1334              { // No form title:
1335                  $r .= TS_( 'You have modified this form but you haven\'t submitted it yet.\nYou are about to lose your edits.\nAre you sure?' );
1336              }
1337              else
1338              { // with form title:
1339                  $r .= sprintf( TS_( 'You have modified the form \"%s\"\nbut you haven\'t submitted it yet.\nYou are about to lose your edits.\nAre you sure?' ), $this->title );
1340              }
1341  
1342              $r .= '\';';
1343  
1344              if(    !empty($bozo_start_modified) )
1345              {
1346                  $r .= '
1347                      // Update number of changes for this form:

1348                      bozo.tab_changes["'.$this->form_name.'"] = 1;
1349                      // Update Total # of changes:

1350                      bozo.nb_changes++;
1351                  ';
1352              }
1353  
1354  
1355              $r .='    }
1356                  </script>';
1357          }
1358  
1359          return $this->display_or_return( $r );
1360      }
1361  
1362  
1363      /**

1364       * Ends the form, optionally displays buttons and closes all open fieldsets.

1365       *

1366       * @param array Optional array to display the buttons before the end of the form, see {@link buttons_input()}

1367       * @return true|string true (if output) or the generated HTML if not outputting.

1368       */
1369  	function end_form( $buttons = array() )
1370      {
1371          $r = '';
1372          if( !empty( $buttons ) )
1373          {
1374              $save_output = $this->output;
1375              $this->output = 0;
1376  
1377              $r .= $this->buttons( $buttons ); // converts old-style to new style, through convert_button_to_field_params()

1378  
1379              $this->output = $save_output;
1380          }
1381  
1382          while( $this->_opentags['fieldset']-- > 0 )
1383          {
1384              $r .= "\n</fieldset>\n";
1385          }
1386  
1387          $r .= $this->formend;
1388  
1389  
1390          // Display all buffered hidden fields in a 0 height DIV (for XHTML):

1391          $r .= '<div style="height:0">'.implode( '', $this->hiddens ).'</div>';
1392  
1393          // $r .= '</div>';

1394          $r .= "\n</form>\n\n";
1395  
1396          // When the page loads, Initialize all the parent child select lists + other javascripts

1397          $r .= '
1398              <script type="text/javascript">
1399                  //<![CDATA[

1400                  if( typeof addEvent == "function" && typeof init_dynamicSelect == "function" )
1401                  {
1402                      addEvent( window, "load", init_dynamicSelect, false );
1403                      ';
1404                      if( $this->check_all )
1405                      { // Init check_all event on check_all links
1406                          $r .= 'addEvent( window, "load", init_check_all, false );';
1407                      }
1408                      $r .= '
1409                  }
1410                  ';
1411  
1412                  if( $this->append_javascript )
1413                  { // Append Javascript that we have added
1414                      $r .= implode( "\n", $this->append_javascript );
1415                  }
1416                  $r .= '
1417                  //]]>

1418              </script>';
1419  
1420          // Reset (in case we re-use begin_form! NOTE: DO NOT REUSE begin_form, it's against the spec.)

1421          $this->hiddens = array();
1422  
1423          return $this->display_or_return( $r );
1424      }
1425  
1426  
1427      /**

1428       * Builds a checkbox list

1429       *

1430       * the two-dimension array must indicate, for each checkbox:

1431       *  - the name,

1432       *  - the value,

1433       *  - the comment to put between <input> and <br />

1434       *  - a boolean indicating whether the box must be checked or not

1435       *  - an optional boolean indicating whether the box is disabled or not

1436       *  - an optional note

1437       *  - 'required': is the box required to be checked (boolean; default: false)

1438       *

1439       * @todo Transform to $field_params schema.

1440       * @param array a two-dimensional array containing the parameters of the input tag

1441       * @param string name

1442       * @param string label

1443       * @param boolean true to surround checkboxes if they are required

1444       * @param boolean true add a surround_check span, used by check_all mouseover

1445       * @return mixed true (if output) or the generated HTML if not outputting

1446       */
1447  	function checklist( $options, $field_name, $field_label, $required = false, $add_highlight_spans = false )
1448      {
1449          $field_params = array();
1450          $field_params['type'] = 'checkbox';
1451          $this->handle_common_params( $field_params, $field_name, $field_label );
1452  
1453          $r = $this->begin_field( $field_name, $field_label );
1454  
1455          foreach( $options as $option )
1456          { //loop to construct the list of 'input' tags
1457  
1458              $loop_field_name = $option[0];
1459  
1460              $loop_field_note = isset($option[5]) ? $option[5] : '';
1461  
1462              $r .= '<label class="">';
1463  
1464              if( $add_highlight_spans )
1465              { // Need it to highlight checkbox for check_all and uncheck_all mouseover
1466                  $r .= '<span name="surround_check" class="checkbox_surround_init">';
1467                  $after_field_highlight = '</span>';
1468              }
1469              else
1470              {
1471                  $after_field_highlight = '';
1472              }
1473  
1474              $after_field = '';
1475              if( param_has_error( $field_name ) )
1476              { // There is an error message for this field, we want to mark the checkboxes with a red border:
1477                  $r .= '<span class="checkbox_error">';
1478                  $after_field .= '</span>';
1479              }
1480              if( $required )
1481              {    //this field is required
1482                  $r .= '<span class="checkbox_required">';
1483                  $after_field .= '</span>';
1484              }
1485  
1486              $r .= "\t".'<input type="checkbox" name="'.$loop_field_name.'" value="'.$option[1].'" ';
1487              if( $option[3] )
1488              { //the checkbox has to be checked by default
1489                  $r .= ' checked="checked" ';
1490              }
1491              if( isset( $option[4] ) && $option[4] )
1492              { // the checkbox has to be disabled
1493                  $r .= ' disabled="disabled" ';
1494              }
1495              $r .= ' class="checkbox" />';
1496  
1497              $r .= $after_field;
1498  
1499              $r .= $after_field_highlight;
1500  
1501              $r .= ' '.$option[2];
1502  
1503              $r .='</label>';
1504  
1505              if( !empty($loop_field_note) )
1506              { // We want to display a note:
1507                  $r .= ' <span class="notes">'.$loop_field_note.'</span>';
1508              }
1509              $r .= "<br />\n";
1510          }
1511  
1512          $r .= $this->end_field();
1513  
1514          return $this->display_or_return( $r );
1515      }
1516  
1517  
1518      /**

1519       * Display a select field and populate it with a callback function.

1520       *

1521       * @param string field name

1522       * @param string default field value

1523       * @param callback callback function

1524       * @param string field label to be display before the field

1525       * @param array Optional params. Additionally to {@link $_common_params} you can use:

1526       *              Nothing yet.

1527       * @return mixed true (if output) or the generated HTML if not outputting

1528       */
1529  	function select_input( $field_name, $field_value, $field_list_callback, $field_label, $field_params = array() )
1530      {
1531          $field_options = call_user_func( $field_list_callback, $field_value );
1532  
1533          return $this->select_input_options( $field_name, $field_options, $field_label, '', $field_params );
1534      }
1535  
1536  
1537      /**

1538       * Display a select field and populate it with a callback function.

1539       *

1540       * @param string field name

1541       * @param string default field value

1542       * @param callback callback function

1543       * @param string field label to be display before the field

1544       * @param string note to be displayed after the field

1545       * @param string CSS class for select

1546       * @param string Javascript to add for onchange event (trailing ";").

1547       * @return mixed true (if output) or the generated HTML if not outputting

1548       */
1549  	function select(
1550          $field_name,
1551          $field_value,
1552          $field_list_callback,
1553          $field_label,
1554          $field_note = '',
1555          $field_class = '',
1556          $field_onchange = NULL )
1557      {
1558          $field_params = array();
1559          if( $field_note !== '' )
1560          {
1561              $field_params['note'] = $field_note;
1562          }
1563          if( $field_class !== '' )
1564          {
1565              $field_params['class'] = $field_class;
1566          }
1567          if( isset($field_onchange) )
1568          {
1569              $field_params['onchange'] = $field_onchange;
1570          }
1571  
1572          return $this->select_input( $field_name, $field_value, $field_list_callback, $field_label, $field_params );
1573      }
1574  
1575  
1576      /**

1577       * Display a select field and populate it with a cache object by using a callback

1578       * method.

1579       *

1580       * @uses select_input_options()

1581       * @param string Field name

1582       * @param string Default field value

1583       * @param DataObjectCache Cache containing values for list

1584       * @param string Field label to be display with the field

1585       * @param array Optional params. Additionally to {@link $_common_params} you can use:

1586       *              - 'allow_none': allow to select [none] in list (boolean, default false)

1587       *              - 'object_callback': Object's callback method name (string, default 'get_option_list')

1588       *              - 'loop_object_method': The method on the objects inside the callback (string, default NULL)

1589       * @return mixed true (if output) or the generated HTML if not outputting

1590       */
1591  	function select_input_object( $field_name, $field_value, & $field_object, $field_label, $field_params = array() )
1592      {
1593          if( isset($field_params['allow_none']) )
1594          {
1595              $allow_none = $field_params['allow_none'];
1596              unset( $field_params['allow_none'] );
1597          }
1598          else
1599          {
1600              $allow_none = false;
1601          }
1602  
1603          if( isset($field_params['object_callback']) )
1604          {
1605              $field_object_callback = $field_params['object_callback'];
1606              unset( $field_params['object_callback'] );
1607          }
1608          else
1609          {
1610              $field_object_callback = 'get_option_list';
1611          }
1612  
1613          if( isset($field_params['loop_object_method']) )
1614          {
1615              $field_options = $field_object->$field_object_callback( $field_value, $allow_none, $field_params['loop_object_method'] );
1616          }
1617          else
1618          {
1619              $field_options = $field_object->$field_object_callback( $field_value, $allow_none );
1620          }
1621  
1622          if( isset($field_params['note']) )
1623          {
1624              $field_note = $field_params['note'];
1625              unset( $field_params['note'] );
1626          }
1627          else
1628          {
1629              $field_note = '';
1630          }
1631  
1632          return $this->select_input_options( $field_name, $field_options, $field_label, $field_note, $field_params );
1633      }
1634  
1635  
1636      /**

1637       * Display a select field and populate it with a cache object.

1638       *

1639       * @uses select_input_object()

1640       * @param string field name

1641       * @param string default field value

1642       * @param DataObjectCache Cache containing values for list

1643       * @param string field label to be display before the field

1644       * @param string note to be displayed after the field

1645       * @param boolean allow to select [none] in list

1646       * @param string CSS class for select

1647       * @param string Object's callback method name.

1648       * @param string Javascript to add for onchange event (trailing ";").

1649       * @return mixed true (if output) or the generated HTML if not outputting

1650       */
1651  	function select_object(
1652          $field_name,
1653          $field_value,
1654          & $field_object,
1655          $field_label,
1656          $field_note = '',
1657          $allow_none = false,
1658          $field_class = '',
1659          $field_object_callback = 'get_option_list',
1660          $field_onchange = NULL )
1661      {
1662          $field_params = array(
1663              'note' => $field_note,
1664              'allow_none' => $allow_none,
1665              'class' => $field_class,
1666              'object_callback' => $field_object_callback,
1667              'onchange' => $field_onchange );
1668  
1669          return $this->select_input_object( $field_name, $field_value, $field_object, $field_label, $field_params  );
1670      }
1671  
1672  
1673      /**

1674       * Display a select field and populate it with a cache object.

1675       *

1676       * @param string field name

1677       * @param string string containing options '<option>...</option>'

1678       * @param string field label to be display before the field

1679       * @param string "help" note (Should provide something useful, otherwise leave it empty)

1680       * @param array Optional params. Additionally to {@link $_common_params} you can use:

1681       *              - 'label': Field label to be display before the field

1682       *              - 'class': CSS class for select

1683       * @return mixed true (if output) or the generated HTML if not outputting

1684       */
1685  	function select_input_options( $field_name, $field_options, $field_label, $field_note = '', $field_params = array() )
1686      {
1687          $this->handle_common_params( $field_params, $field_name, $field_label );
1688  
1689          $r = $this->begin_field();
1690          if( !empty( $field_params['parent'] ) )
1691          {// need to display an arrow to show that this select list options has a preselection from a parent
1692              $r .= get_icon( 'parent_childto_arrow' );
1693          }
1694  
1695          $r .="\n<select".get_field_attribs_as_string($field_params).'>'
1696               .$field_options
1697               ."</select>\n";
1698  
1699          $r .= $this->end_field( $field_note );
1700  
1701          if( !empty( $field_params['parent'] ) )
1702          { // Set up the dynamic preselection array from the parent to this select list options
1703              $r .= "<script type='text/javascript'>
1704                                  tab_dynamicSelects[nb_dynamicSelects] = Array();
1705                                  tab_dynamicSelects[nb_dynamicSelects]['parent'] = '".$field_params['parent']."';
1706                                  tab_dynamicSelects[nb_dynamicSelects]['child'] = '$field_name';
1707                                  nb_dynamicSelects++;
1708                              </script>";
1709          }
1710  
1711          return $this->display_or_return( $r );
1712      }
1713  
1714  
1715      /**

1716       * Display a select field and populate it with a cache object.

1717       *

1718       * @uses select_input_options()

1719       * @param string field name

1720       * @param string string containing options

1721       * @param string field label to be display before the field

1722       * @param string note to be displayed after the field

1723       * @param string CSS class for select

1724       * @param string Javascript to add for onchange event (trailing ";").

1725       * @return mixed true (if output) or the generated HTML if not outputting

1726       */
1727  	function select_options(
1728          $field_name,
1729          $field_options,
1730          $field_label,
1731          $field_note = NULL,
1732          $field_class = NULL,
1733          $field_onchange = NULL )
1734      {
1735          $field_params = array(
1736              'note' => $field_note,
1737              'class' => $field_class,
1738              'onchange' => $field_onchange,
1739               );
1740  
1741          return $this->select_input_options( $field_name, $field_options, $field_label, '', $field_params );
1742      }
1743  
1744  
1745      /**

1746       * This is a stub for {@link select_input_options()} which builds the required list

1747       * of <option> elements from a given list of options ($field_options) and

1748       * the selected value ($field_value).

1749       *

1750       * @uses select_input_options()

1751       * @param string field name

1752       * @param mixed Initial value

1753       * @param array Options. If an associative key (string) is used, this gets the value attribute.

1754       *              NOTE: numeric strings get converted to integers by PHP!

1755       * @param string Field label to be display before the field

1756       * @param string Note

1757       * @param array Optional params. Additionally to {@link $_common_params} you can use:

1758       *              - 'value': The selected value

1759       *              - 'force_keys_as_values': Use the key of $field_options for "value" attrib always.

1760       *              - Plus all of {@link select_input_options()}.

1761       * @return mixed true (if output) or the generated HTML if not outputting

1762       */
1763  	function select_input_array( $field_name, $field_value, $field_options, $field_label, $field_note = NULL, $field_params = array() )
1764      {
1765          if( isset($field_params['force_keys_as_values']) )
1766          {
1767              $force_keys_as_values = $field_params['force_keys_as_values'];
1768              unset($field_params['force_keys_as_values']); // not an attribute to <select>

1769          }
1770          else
1771          {
1772              $force_keys_as_values = false;
1773          }
1774  
1775          // Build $options_list

1776          $options_list = '';
1777  
1778          foreach( $field_options as $l_key => $l_option )
1779          {
1780              // Get the value attribute from key if is_string():

1781              $l_value = ($force_keys_as_values || is_string($l_key)) ? $l_key : $l_option;
1782  
1783              $options_list .= '<option value="'.format_to_output($l_value, 'formvalue').'"';
1784  
1785              if( (string)$l_value == (string)$field_value ) // cast to string so "1,2" is != 1
1786              {
1787                  $options_list .= ' selected="selected"';
1788              }
1789  
1790              $options_list .= '>'.format_to_output($l_option).'</option>';
1791          }
1792  
1793          return $this->select_input_options( $field_name, $options_list, $field_label, $field_note, $field_params );
1794      }
1795  
1796  
1797      /**

1798       * Combo box

1799       * Display a select options list with an option 'new',

1800       * and when this one is seleted, display a combo input text to add a new value

1801       *

1802       * @param string field name

1803       * @param string field value

1804       * @param string containing options

1805       * @param string field label

1806       * @param array Optional params

1807       *

1808       * @return mixed true (if output) or the generated HTML if not outputting

1809       */
1810  	function combo_box( $field_name, $field_value, $field_options, $field_label, $field_params = array() )
1811      {
1812          if( param_has_error( $field_name) )
1813          {    // There is an error on the combo, so we need to set the combo input text class to 'field_error'
1814              $input_class = 'field_error';
1815          }
1816          else
1817          {
1818              if( isset( $field_params['required'] ) && $field_params['required'] )
1819              {    // The field is required, so update its class:
1820                  $input_class = ' field_required';
1821              }
1822              else
1823              {
1824                  $input_class = '';
1825              }
1826          }
1827          unset($field_params['required']); // already handled above, do not pass to handle_common_params()

1828  
1829          // Set onchange event on the select, when the select changes, we check the value to display or hide an input text after it

1830          $field_params['onchange']= 'check_combo( this.id, this.options[this.selectedIndex].value, "'.$input_class.'")';
1831  
1832          $this->handle_common_params( $field_params, $field_name, $field_label );
1833  
1834          $r = $this->begin_field();
1835  
1836          // Select option to add after the select list a combo input text:

1837          $option_new  = '<option value="new">'.T_('New').': </option>'."\n";
1838  
1839          // Add the new option to the select list:

1840          $field_options = $option_new . $field_options;
1841  
1842          // Select list

1843          $r .="\n<select".get_field_attribs_as_string($field_params).'>'
1844               .$field_options
1845               ."</select>\n";
1846  
1847          if( $field_options == $option_new  || $input_class == 'field_error' || !$field_value )
1848          {    // The list is empty or there is an error on the combo or no field value, so we have to display the input text:
1849              $visible = 'inline';
1850          }
1851          else
1852          { // Hide the input text:
1853              $visible = 'none' ;
1854          }
1855  
1856          $r .= '<input type="text" id="'.$field_name.'_combo" name="'.$field_name.'_combo" size="30" class="'.$input_class.'" style="display:'.$visible.'">';
1857  
1858          if( $visible == 'none' )
1859          { // The input text is hidden, so if no javascript activated, we always display input text:
1860              $r .= '<script type="text/javascript"></script>'; // We need <script> tag here to use a <noscript> tag when javascript is deactivated:

1861              $r .= '<noscript>
1862                              <input type="text" id="'.$field_name.'_combo" name="'.$field_name.'_combo" size="30" class="'.$input_class.'">
1863                          </noscript>';
1864          }
1865  
1866          $r .= $this->end_field();
1867  
1868          return $this->display_or_return( $r );
1869      }
1870  
1871  
1872      /**

1873       * Build a text area.

1874       *

1875       * @param string Name of the field

1876       * @param string Value of the field

1877       * @param integer Number of rows

1878       * @param string Label for the field

1879       * @param array Optional params. Additionally to {@link $_common_params} you can use:

1880       *              - 'cols': Number of columns (integer, default 50)

1881       */
1882  	function textarea_input( $field_name, $field_value, $field_rows, $field_label, $field_params = array() )
1883      {
1884          global $rsc_url;
1885  
1886          if( !isset($field_params['cols']) )
1887          {
1888              $field_params['cols'] = 50;
1889          }
1890  
1891          if( !isset($field_params['note_format']) )
1892          { // Default note_format for <textarea>:
1893              $field_params['note_format'] = '<br/><span class="notes">%s</span>';
1894          }
1895  
1896          $this->handle_common_params( $field_params, $field_name, $field_label );
1897  
1898          // Give it a class, so it can be selected for CSS in IE6

1899          if( empty($field_params['class']) ) $field_params['class'] = 'form_textarea_input';
1900          else $field_params['class'] .= ' form_textarea_input';
1901  
1902          if( isset($field_params['maxlength']) )
1903          { // attach event to the textarea to accomplish max length:
1904              $this->append_javascript['textarea_maxlength'.$field_name] = '
1905                  if( typeof jQuery == "function" )
1906                  {
1907                  $("#'.$field_params['id'].'").bind( "keyup", function(event)
1908                      {
1909                          if( this.value.length > '.$field_params['maxlength'].' )
1910                          {
1911                              this.value = this.value.substr(0,'.$field_params['maxlength'].');
1912                              event.preventDefault();
1913                          }
1914                      } );
1915                  }';
1916              unset($field_params['maxlength']); // not a HTML attribute for textarea

1917          }
1918  
1919          $r = $this->begin_field()
1920              // NOTE: The following pixel is needed to avoid the dity IE textarea expansion bug

1921              // see http://fplanque.net/2003/Articles/iecsstextarea/index.html

1922              .'<img src="'.$rsc_url.'img/blank.gif" width="1" height="1" alt="" />'
1923              .'<textarea'
1924              .get_field_attribs_as_string( $field_params )
1925              .' rows="'.$field_rows.'">'
1926              .format_to_output( $field_value, 'formvalue' )
1927              .'</textarea>'
1928              // NOTE: this one is for compensating the previous pixel in case of center aligns.

1929              .'<img src="'.$rsc_url.'img/blank.gif" width="1" height="1" alt="" />'
1930              .$this->end_field();
1931  
1932          return $this->display_or_return( $r );
1933      }
1934  
1935  
1936      /**

1937       * Build a text area.

1938       *

1939       * @uses textarea_input()

1940       *

1941       * @param string

1942       * @param string

1943       * @param integer

1944       * @param string

1945       * @param string

1946       * @param integer

1947       * @param string

1948       */
1949  	function textarea( $field_name, $field_value, $field_rows, $field_label,
1950                                                  $field_note = '', $field_cols = 50 , $field_class = '' )
1951      {
1952          $field_params = array(
1953              'note' => $field_note,
1954              'cols' => $field_cols,
1955              'class' => $field_class );
1956  
1957          return $this->textarea_input( $field_name, $field_value, $field_rows, $field_label, $field_params );
1958      }
1959  
1960  
1961      /**

1962       * Builds an info field.

1963       * An info field is a fieldset containing a label div and an info div.

1964       *

1965       * {@internal

1966       * NOTE: we don't use {@link begin_field()} here, because the label is meant

1967       * to be always on the left and this avoids fiddling with the <label> tag.

1968       * }}

1969       *

1970       * @param string the field label

1971       * @param string the field info

1972       * @param array Optional params. Additionally to {@link $_common_params} you can use:

1973       *              - 'format_info': Format of info content, see {@link format_to_output()} (string, default 'htmlbody')

1974       * @return mixed true (if output) or the generated HTML if not outputting

1975       */
1976  	function info_field( $field_label, $field_info, $field_params = array() )
1977      {
1978          if( isset($field_params['format_info']) )
1979          {
1980              $format_info = $field_params['format_info'];
1981              unset($field_params['format_info']); // not an HTML element

1982          }
1983          else
1984          {
1985              $format_info = 'htmlbody';
1986          }
1987  
1988          if( !isset($field_params['note_format']) )
1989          { // Default field_note for info:
1990              $field_params['note_format'] = ' <small class="notes">%s</small>';
1991          }
1992  
1993          $this->handle_common_params( $field_params, NULL, $field_label );
1994  
1995          $r = $this->fieldstart;
1996  
1997          if( strlen($field_label) )
1998          {
1999              $r .= $this->labelstart.$field_label;
2000              $r .= $this->label_suffix;
2001              $r .= $this->labelend;
2002          }
2003          else
2004          { // Empty label:
2005              $r .= $this->labelempty;
2006          }
2007  
2008          $r .= $this->infostart;
2009  
2010          // PAYLOAD:

2011          $r .= format_to_output( $field_info, $format_info );
2012  
2013  
2014          // Taken from end_field() - but we use $infoend:

2015          if( !empty($this->_common_params['note']) )
2016          { // We have a note
2017              $r .= sprintf( $this->_common_params['note_format'], $this->_common_params['note'] );
2018          }
2019  
2020          if( isset($this->_common_params['field_suffix']) )
2021          {
2022              $r .= $this->_common_params['field_suffix'];
2023          }
2024  
2025          $r .= ( isset($this->infoend) ? $this->infoend : $this->inputend ).$this->fieldend;
2026  
2027          return $this->display_or_return( $r );
2028      }
2029  
2030  
2031      /**

2032       * Builds an info field.

2033       * An info field is a fieldset containing a label div and an info div.

2034       *

2035       * @param string the field label

2036       * @param string the field info

2037       * @param string see {@link format_to_output()}

2038       * @return mixed true (if output) or the generated HTML if not outputting

2039       */
2040  	function info( $field_label, $field_info, $field_note = NULL, $format = 'htmlbody' )
2041      {
2042          $field_params = array(
2043              'note' => $field_note,
2044              'format_info' => $format );
2045  
2046          return $this->info_field( $field_label, $field_info, $field_params );
2047      }
2048  
2049  
2050      /**

2051       * Builds a button list.

2052       *

2053       * The array contains an associative array for each button (params to {@link button_input()}.

2054       *

2055       * @param array a two-dimension array containing the elements of the input tags

2056       * @return mixed true (if output) or the generated HTML if not outputting

2057       */
2058  	function buttons_input( $buttons = array() )
2059      {
2060          $r = '';
2061          $hidden = true; // boolean that tests if the buttons are all hidden

2062  
2063          $save_output = $this->output;
2064          $this->output = false;
2065  
2066          foreach( $buttons as $l_button )
2067          {
2068              if( !isset($l_button['type']) || $l_button['type'] != 'hidden' )
2069              { // not a hidden button
2070                  $hidden = false;
2071              }
2072  
2073              $r .= $this->button_input( $l_button );
2074          }
2075          /*

2076          else

2077          { // Default: Save and Reset

2078              $r .= $this->get_input_element( array(

2079                  'type' => 'submit',

2080                  'value' => T_('Save !'),

2081                  'class' => 'SaveButton',

2082                  'input_prefix => "\t\t\t" );

2083              $r .= $this->get_input_element( array(

2084                  'type' => 'reset',

2085                  'value' => T_('Reset'),

2086                  'class' => 'ResetButton',

2087                  'input_prefix => "\t\t\t" );

2088          }*/
2089  
2090          $this->output = $save_output;
2091  
2092          if( ! $hidden )
2093          { // there are not only hidden buttons : additional tags
2094              $r = $this->buttonsstart.$r.$this->buttonsend;
2095          }
2096  
2097          return $this->display_or_return( $r );
2098      }
2099  
2100  
2101      /**

2102       * Builds a button list.

2103       *

2104       * Array entries with numeric (deprecated) keys are converted to their equivalent string indexes.

2105       *

2106       * the two-dimension array must contain :

2107       *  - the button type

2108       *  - the name (optional)

2109       *  - the value (optional)

2110       *  - the class (optional)

2111       *  - the onclick attribute (optional)

2112       *  - the style (optional)

2113       *

2114       * @param array a two-dimension array containing the elements of the input tags

2115       * @param boolean to select or not the default display

2116       * @return mixed true (if output) or the generated HTML if not outputting

2117       */
2118  	function buttons( $buttons = array() )
2119      {
2120          $buttons_list = array();
2121  
2122          foreach( $buttons as $l_button )
2123          {
2124              $buttons_list[] = $this->convert_button_to_field_params( $l_button );
2125          }
2126  
2127          return $this->buttons_input( $buttons_list );
2128      }
2129  
2130  
2131      /**

2132       * Builds a button.

2133       *

2134       * Array entries with numeric (deprecated) keys are converted to their equivalent string indexes.

2135       *

2136       * @param array Optional params. Additionally to {@link $_common_params} you can use:

2137       *              - type: The type attribute (string, default 'submit')

2138       * @return mixed true (if output) or the generated HTML if not outputting

2139       */
2140  	function button_input( $field_params = array() )
2141      {
2142          if( empty($field_params['type']) )
2143          { // default type
2144              $field_params['type'] = 'submit';
2145          }
2146  
2147          if( !isset($field_params['input_prefix']) )
2148          { // default prefix
2149              $field_params['input_prefix'] = "\t\t\t";
2150          }
2151  
2152          return $this->display_or_return( $this->get_input_element( $field_params ) );
2153      }
2154  
2155  
2156      /**

2157       * Builds a button

2158       *

2159       * the array must contain :

2160       *  - the button type

2161       *  - the name (optional)

2162       *  - the value (optional)

2163       *  - the class (optional)

2164       *  - the onclick attribute (optional)

2165       *  - the style (optional)

2166       *

2167       * @param array a two-dimension array containing the elements of the input tags

2168       * @return mixed true (if output) or the generated HTML if not outputting

2169       */
2170  	function button( $options )
2171      {
2172          $field_params = $this->convert_button_to_field_params( $options );
2173  
2174          if( empty($field_params['type']) )
2175          {
2176              $field_params['type'] = 'submit'; // default type

2177          }
2178  
2179          return $this->button_input( $field_params );
2180      }
2181  
2182  
2183      /**

2184       * Convert a deprecated, numeric button array to a field_params array.

2185       *

2186       * @deprecated

2187       * @param array A button array like button() and buttons() are getting.

2188       * @return array The button array converted to a string indexed button array (field_params).

2189       */
2190  	function convert_button_to_field_params( $options )
2191      {
2192          $field_params = array();
2193  
2194          foreach( array_keys($options) as $l_key )
2195          {
2196              if( is_int($l_key) )
2197              {
2198                  switch( $l_key )
2199                  {
2200                      case 0: $field_params['type'] = $options[0]; break;
2201                      case 1: $field_params['name'] = $options[1]; break;
2202                      case 2: $field_params['value'] = $options[2]; break;
2203                      case 3: $field_params['class'] = $options[3]; break;
2204                      case 4: $field_params['onclick'] = $options[4]; break;
2205                      case 5: $field_params['style'] = $options[5]; break;
2206                  }
2207              }
2208              else
2209              {
2210                  $field_params[$l_key] = $options[$l_key];
2211              }
2212          }
2213  
2214          return $field_params;
2215      }
2216  
2217  
2218      /**

2219       * Builds an hidden input tag, overwriting any previous hidden values (except for "foo[]").

2220       *

2221       * @param string Field name

2222       * @param string Field value

2223       * @param array Optional params. This is e.g. useful for "id".

2224       *              See {@link $_common_params}.

2225       */
2226  	function hidden( $field_name, $field_value, $field_params = array() )
2227      {
2228          if( is_array( $field_value ) )
2229          { // this happens for example when we've POSTed an array (for PHP it's an array then)
2230              foreach( $field_value as $l_key => $l_value )
2231              {
2232                  // Recursion:

2233                  $this->hidden( $field_name.'['.$l_key.']', $l_value, $field_params );
2234              }
2235          }
2236          else
2237          {
2238              $field_params['name'] = $field_name;
2239              $field_params['type'] = 'hidden';
2240              $field_params['value'] = $field_value;
2241  
2242              if( strpos($field_name, '[]') )
2243              { // array-style name or we don't want to overwrite, just add it:
2244                  $this->hiddens[] = $this->get_input_element( $field_params );
2245              }
2246              else
2247              {
2248                  if( isset($this->existing_hiddens[$field_name]) )
2249                  {
2250                      unset($this->hiddens[$this->existing_hiddens[$field_name]]);
2251                  }
2252  
2253                  // add the field and remember that it already exists:

2254                  end($this->hiddens);
2255                  $key = key($this->hiddens)+1;
2256                  $this->hiddens[$key] = $this->get_input_element( $field_params );
2257                  $this->existing_hiddens[$field_name] = $key;
2258              }
2259          }
2260      }
2261  
2262  
2263      /**

2264       * Add the "ctrl" param, used in the backoffice, as a hidden field.

2265       */
2266  	function hidden_ctrl()
2267      {
2268          global $ctrl;
2269          if( !empty( $ctrl) )
2270          {
2271              $this->hidden( 'ctrl', $ctrl );
2272          }
2273      }
2274  
2275  
2276      /**

2277       * Builds a list of hidden inputs.

2278       *

2279       * @param array Array of parameters to {@link hidden()}:

2280       *               - 0: field_name

2281       *               - 1: field_value

2282       *               - 2: field_params

2283       * @return mixed true (if output) or the generated HTML if not outputting

2284       */
2285  	function hiddens( $hiddens )
2286      {
2287          $save_output = $this->output;
2288          $this->output = false;
2289          foreach( $hiddens as $hidden )
2290          {
2291              $this->hidden( $hidden[0], $hidden[1], isset($hidden[2]) ? $hidden[2] : array() );
2292          }
2293          $this->output = $save_output;
2294      }
2295  
2296  
2297      /**

2298       * Builds a list of hidden inputs from an array where the keys are the field names.

2299       *

2300       * It supports array values (one-dimensional) and generates appropriate key-value pairs.

2301       *

2302       * @uses Form::hidden()

2303       * @param array associative array ( name => value ) of hidden fields.

2304       * @param array|NULL A list of keys to ignore.

2305       */
2306  	function hiddens_by_key( $hiddens, $exclude = NULL )
2307      {
2308          if( $this->output )
2309          { // only save output once, if necessary (recursion!)
2310              $save_output = $this->output;
2311              $this->output = false;
2312          }
2313          foreach( $hiddens as $l_name => $l_value )
2314          {
2315              if( isset($exclude) && in_array( $l_name, $exclude ) )
2316              {
2317                  continue;
2318              }
2319              if( is_array( $l_value ) )
2320              { // this happens for example when we've POSTed an array (for PHP it's an array then)
2321                  foreach( $l_value as $ll_key => $ll_value )
2322                  {
2323                      // Recursion:

2324                      $this->hiddens_by_key( array( $l_name.'['.$ll_key.']' => $ll_value ), $exclude );
2325                  }
2326              }
2327              else
2328              {
2329                  $this->hidden( $l_name, $l_value );
2330              }
2331          }
2332  
2333          if( isset($save_output) )
2334          {
2335              $this->output = $save_output;
2336          }
2337      }
2338  
2339  
2340      /**

2341       * Builds a submit input tag

2342       *

2343       * the array must contain :

2344       *  - the name (optional)

2345       *  - the value (optional)

2346       *  - the class (optional)

2347       *  - the onclick attribute (optional)

2348       *  - the style (optional)

2349       *

2350       * @todo Use <div class="input"> for layout == 'fieldset' (property).

2351       * @param array Optional params. Additionally to {@link $_common_params} you can use:

2352       *              Nothing yet.

2353       * @return mixed true (if output) or the generated HTML if not outputting

2354       */
2355  	function submit_input( $field_params = array() )
2356      {
2357          $field_params['type'] = 'submit';
2358  
2359          return $this->button_input( $field_params );
2360      }
2361  
2362  
2363      /**

2364       * Builds a submit input tag

2365       *

2366       * the array must contain :

2367       *  - the name (optional)

2368       *  - the value (optional)

2369       *  - the class (optional)

2370       *  - the onclick attribute (optional)

2371       *  - the style (optional)

2372       *

2373       * @param array an array containing the elements of the input tags

2374       * @return mixed true (if output) or the generated HTML if not outputting

2375       */
2376  	function submit( $options )
2377      {
2378          array_unshift( $options, 'submit' );
2379  
2380          return $this->button( $options );
2381      }
2382  
2383  
2384      /**

2385       * Generate set of radio options.

2386       *

2387       * @param string The name of the radio options

2388       * @param string The checked option's value

2389       * @param array of arrays The radio options

2390       *        Keys:

2391       *         - 'value' (required)

2392       *         - 'label' (required)

2393       *         - 'note'

2394       *         - 'type' (default: "radio")

2395       *         - 'class' (default: "radio")

2396       *         - 'checked' (default: 'value' gets compared to $field_value)

2397       *         - 'name' (default: $field_name)

2398       *         - 'suffix' (gets used after the radio's label)

2399       *         - Plus everything for {@link get_input_element()} )

2400       * @param string Label

2401       * @param array Optional params. Additionally to {@link $_common_params} you can use:

2402       *              - lines: Options on seperate lines (DIVs) (boolean, default false)

2403       *              NOTE: these params/attribs get used as default for every INPUT field,

2404       *                    overridden by $field_options

2405       * @return mixed true (if output) or the generated HTML if not outputting

2406       */
2407  	function radio_input( $field_name, $field_value, $field_options, $field_label, $field_params = array() )
2408      {
2409          if( isset($field_params['lines']) )
2410          {
2411              $field_lines = $field_params['lines'];
2412              unset($field_params['lines']); // no HTML attribute

2413          }
2414          else
2415          {
2416              $field_lines = false;
2417          }
2418  
2419          if( !isset($field_params['note_format']) )
2420          { // Default field_note for radios:
2421              $field_params['note_format'] = '<span class="notes">%s</span>';
2422              if( $field_lines )
2423              {
2424                  $field_params['note_format'] = '<div>'.$field_params['note_format'].'</div>';
2425              }
2426          }
2427  
2428          $field_params['id'] = false; // No ID attribute for the label

2429          $this->handle_common_params( $field_params, $field_name, $field_label );
2430          unset($field_params['id']);  // unset, so it gets handled correctly as default below

2431  
2432          $r = $this->begin_field();
2433  
2434          /*

2435           * Build options list:

2436           */
2437          $count_options = 0; // used for unique IDs (label/radio)

2438          foreach( $field_options as $loop_radio )
2439          {
2440              // Merge defaults from $field_params:

2441              $loop_radio = array_merge( $field_params, $loop_radio );
2442  
2443              if( $field_lines ) $r .= "<div>\n";
2444  
2445              // Defaults:

2446              if( ! isset($loop_radio['type']) )  $loop_radio['type'] = 'radio';
2447              if( ! isset($loop_radio['class']) ) $loop_radio['class'] = 'radio';
2448              if( ! isset($loop_radio['name']) )  $loop_radio['name'] = $field_name;
2449              if( ! isset($loop_radio['id']) )
2450              { // build unique id:
2451                  $loop_radio['id'] = $this->get_valid_id($field_params['name'].'_radio_'.(++$count_options));
2452              }
2453  
2454              if( isset($loop_radio['checked']) )
2455              { // convert boolean:
2456                  if( $loop_radio['checked'] ) $loop_radio['checked'] = 'checked';
2457              }
2458              elseif( $field_value == $loop_radio['value'] )
2459              { // Current selection:
2460                  $loop_radio['checked'] = 'checked';
2461              }
2462  
2463              // Unset non-HTML attribs:

2464              $label = $loop_radio['label'];
2465              $note = isset($loop_radio['note']) ? $loop_radio['note'] : null;
2466              $suffix = isset($loop_radio['suffix']) ? $loop_radio['suffix'] : '';
2467              unset($loop_radio['label'], $loop_radio['note'], $loop_radio['suffix']);
2468  
2469              // the radio element:

2470              $r .= $this->get_input_element( $loop_radio, false );
2471  
2472              // the label:

2473              $r .= '<label class="radiooption" for="'.$loop_radio['id'].'">'.$label.'</label>';
2474  
2475              if( ! empty($note) )
2476              { // Add a note for the current radio option:
2477                  $r .= '<span class="notes">'.$note.'</span>';
2478              }
2479  
2480              // optional text for radio option (like additional fieldsets or input boxes)

2481              $r .= $suffix;
2482  
2483              // Split radio options by whitespace:

2484              $r .= "\n";
2485  
2486              if( $field_lines ) $r .= "</div>\n";
2487          }
2488  
2489          $r .= $this->end_field();
2490  
2491          return $this->display_or_return( $r );
2492      }
2493  
2494  
2495      /**

2496       * Generate set of radio options.

2497       *

2498       * @param string the name of the radio options

2499       * @param string the checked option

2500       * @param array of arrays the radio options (0: value, 1: label, 2: notes, 3: additional HTML [input field, ..], 4: attribs for <input tag> )

2501       * @param string label

2502       * @param boolean options on seperate lines (DIVs)

2503       * @param string notes

2504       * @return mixed true (if output) or the generated HTML if not outputting

2505       */
2506  	function radio( $field_name, $field_value, $field_options, $field_label, $field_lines = false, $field_note = '' )
2507      {
2508          $new_field_options = array();
2509  
2510          foreach( $field_options as $l_key => $l_options )
2511          {
2512              $new_field_options[$l_key] = array(
2513                  'value' => $l_options[0],
2514                  'label' => $l_options[1] );
2515  
2516              if( isset($l_options[2]) )
2517              {
2518                  $new_field_options[$l_key]['note'] = $l_options[2];
2519              }
2520              if( isset($l_options[4]) )
2521              { // Convert "inline attribs" to "params" array
2522                  preg_match_all( '#(\w+)=[\'"](.*)[\'"]#', $l_options[4], $matches, PREG_SET_ORDER );
2523  
2524                  foreach( $matches as $l_set_nr => $l_match )
2525                  {
2526                      $new_field_options[$l_key][$l_match[1]] = $l_match[2];
2527                  }
2528              }
2529  
2530              if( isset($l_options[3]) )
2531              {
2532                  $new_field_options[$l_key]['suffix'] = $l_options[3];
2533              }
2534          }
2535  
2536          $field_params = array( 'lines' => $field_lines, 'note' => $field_note );
2537  
2538          return $this->radio_input( $field_name, $field_value, $new_field_options, $field_label, $field_params );
2539      }
2540  
2541  
2542      /**

2543       * Generate a general input field.

2544       *

2545       * This is the base function for text_input(), checkbox_input(), ..

2546       *

2547       * @uses get_input_element() to generate the <input> element

2548       *

2549       * @param array Optional params. Additionally to {@link $_common_params} you can use:

2550       *              - see {@link get_input_element()}

2551       * @return true|string true (if output) or the generated HTML if not outputting

2552       */
2553  	function input_field( $field_params = array() )
2554      {
2555          $element = $this->get_input_element($field_params);
2556  
2557          $r = $this->begin_field()
2558                  .$element
2559                  .$this->end_field();
2560  
2561          return $this->display_or_return( $r );
2562      }
2563  
2564  
2565      /**

2566       * Generate a general input element.

2567       *

2568       * @param array Optional params.

2569       *    Additionally to {@link $_common_params} you can use:

2570       *    - input_prefix: Text before <input /> (string, default '')

2571       *    - input_suffix: Text after <input /> (string, default "\n")

2572       *    - input_help: Gets used as default value on empty input (type=text)

2573       *      elements. It gets attached through JavaScript (onfocus, onblur and form.onsubmit).

2574       *

2575       * @return string The <input /> element.

2576       */
2577  	function get_input_element( $field_params = array(), $parse_common = true )
2578      {
2579          if( $parse_common )
2580          {
2581              $this->handle_common_params( $field_params );
2582          }
2583  
2584          if( isset($field_params['input_prefix']) )
2585          {
2586              $input_prefix = $field_params['input_prefix'];
2587              unset($field_params['input_prefix']); // no HTML attribute

2588          }
2589          else
2590          {
2591              $input_prefix = '';
2592          }
2593  
2594          if( isset($field_params['input_suffix']) )
2595          {
2596              $input_suffix = $field_params['input_suffix'];
2597              unset($field_params['input_suffix']); // no HTML attribute

2598          }
2599          else
2600          {
2601              $input_suffix = "\n";
2602          }
2603  
2604          if( isset($field_params['input_help']) && ( empty($field_params['type']) || $field_params['type'] == 'text' ) )
2605          {
2606              $this->append_javascript[] = 'input_decorated_help( "'.$field_params['id'].'", "'.format_to_output($field_params['input_help'], 'formvalue').'" );';
2607  
2608              unset($field_params['input_help']); // no HTML attribute

2609          }
2610  
2611          $r = $input_prefix
2612              .'<input'.get_field_attribs_as_string( $field_params ).' />'
2613              .$input_suffix;
2614  
2615          return $r;
2616      }
2617  
2618  
2619      /**

2620       * Convert a given string (e.g. fieldname) to a valid HTML id.

2621       *

2622       * @static

2623       * @return string

2624       */
2625  	function get_valid_id( $id )
2626      {
2627          static $id_count = 0;
2628          if( substr( $id, -2 ) == '[]' )
2629          {
2630              $id = substr( $id, 0, -2 ).'_A'.(++$id_count);
2631          }
2632          return str_replace( array( '[', ']' ), '_', $id );
2633      }
2634  
2635  
2636      /**

2637       * Get the label of a field. This is used by {@link begin_field()} or {@link end_field()},

2638       *

2639       * @access protected

2640       * @return string

2641       */
2642  	function get_label()
2643      {
2644          $r = '';
2645  
2646          $label = $this->_common_params['label'];
2647  
2648          if( strlen($label) )
2649          {
2650              $r .= $this->labelstart
2651                  .'<label'
2652                  .( !empty($this->_common_params['id'])
2653                      ? ' for="'.format_to_output( $this->_common_params['id'], 'htmlattr' ).'"'
2654                      : '' )
2655                  .'>'
2656                  .format_to_output($label, 'htmlbody');
2657  
2658              $r .= $this->label_suffix;
2659  
2660              $r .= '</label>'
2661                  .$this->labelend;
2662          }
2663          else
2664          { // Empty label:
2665              $r .= $this->labelempty;
2666          }
2667  
2668          return $r;
2669      }
2670  
2671  
2672      /**

2673       * Extract common params out of $field_params into {@link $_common_params} and unsets them in $field_params.

2674       *

2675       * Also handles adding errors to the note.

2676       *

2677       * @access protected

2678       * @param array An array passed to a field generating function like {@link text_input()}. By reference!

2679       * @param string|NULL The name of the field. If not empty it gets used to build the id attribute.

2680       */
2681  	function handle_common_params( & $field_params, $field_name = NULL, $field_label = NULL )
2682      {
2683          #pre_dump( 'handle_common_params (before)', $field_params );

2684  
2685          $this->_common_params = array(); // Reset

2686  
2687          // Copy optional variables, if given:

2688          if( isset($field_name) )
2689          {
2690              $field_params['name'] = $field_name;
2691          }
2692          if( isset($field_label) )
2693          {
2694              $field_params['label'] = $field_label;
2695          }
2696  
2697          if( isset($field_params['note']) )
2698          {
2699              $this->_common_params['note'] = $field_params['note'];
2700              unset($field_params['note']); // no HTML attribute

2701          }
2702          else
2703          {
2704              $this->_common_params['note'] = NULL;
2705          }
2706  
2707          if( isset($field_params['note_format']) )
2708          {
2709              $this->_common_params['note_format'] = $field_params['note_format'];
2710              unset($field_params['note_format']); // no HTML attribute

2711          }
2712          else
2713          {
2714              $this->_common_params['note_format'] = $this->note_format;
2715          }
2716  
2717          if( isset($field_params['label']) )
2718          {
2719              $this->_common_params['label'] = $field_params['label'];
2720              unset($field_params['label']); // no HTML attribute

2721          }
2722          else
2723          {
2724              $this->_common_params['label'] = '';
2725          }
2726  
2727          if( isset($field_params['field_prefix']) )
2728          {
2729              $this->_common_params['field_prefix'] = $field_params['field_prefix'];
2730              unset( $field_params['field_prefix'] );
2731          }
2732  
2733          if( isset($field_params['field_suffix']) )
2734          {
2735              $this->_common_params['field_suffix'] = $field_params['field_suffix'];
2736              unset( $field_params['field_suffix'] );
2737          }
2738  
2739          if( isset($field_params['required']) )
2740          {
2741              $this->_common_params['required'] = $field_params['required'];
2742              unset($field_params['required']);
2743          }
2744  
2745  
2746          if( !empty($field_params['name']) )
2747          {
2748              if( !isset($field_params['id']) )
2749              { // Autogenerate id attrib (not for hidden, radio and submit types)
2750                  if( empty($field_params['type'])
2751                          || ( $field_params['type'] != 'hidden'
2752                                      && $field_params['type'] != 'radio'
2753                                      && $field_params['type'] != 'submit'
2754                                      ) )
2755                  { // Save ID with field_params and _common_params (for get_label())
2756                      $field_params['id'] = $this->_common_params['id'] = $this->get_valid_id($field_params['name']);
2757                  }
2758              }
2759              else
2760              {
2761                  $this->_common_params['id'] = $field_params['id'];
2762              }
2763          }
2764  
2765          // Mark required fields:

2766          if( isset($this->_common_params['required']) && $this->_common_params['required'] )
2767          { // add "field_required" class:
2768              if( isset($field_params['type']) && $field_params['type'] == 'checkbox' )
2769              { // checkboxes need a span
2770                  $field_params['input_prefix'] = ( isset($field_params['input_prefix']) ? $field_params['input_prefix'] : '' ).'<span class="checkbox_required">';
2771                  $field_params['input_suffix'] = '</span>'.( isset($field_params['input_suffix']) ? $field_params['input_suffix'] : '' );
2772              }
2773              else
2774              {
2775                  $field_params['class'] = isset( $field_params['class'] ) ? $field_params['class'].' field_required' : 'field_required';
2776              }
2777          }
2778  
2779          // Error handling:

2780          if( isset($field_params['name']) && param_has_error( $field_params['name'] ) )
2781          { // There is an error message for this field:
2782              if( isset($field_params['type']) && $field_params['type'] == 'checkbox' )
2783              { // checkboxes need a span
2784                  $field_params['input_prefix'] = ( isset($field_params['input_prefix']) ? $field_params['input_prefix'] : '' ).'<span class="checkbox_error">';
2785                  $field_params['input_suffix'] = '</span>'.( isset($field_params['input_suffix']) ? $field_params['input_suffix'] : '' );
2786              }
2787              else
2788              {
2789                  $field_params['class'] = isset( $field_params['class'] ) ? $field_params['class'].' field_error' : 'field_error';
2790              }
2791  
2792              if( $this->disp_param_err_messages_with_fields )
2793              {
2794                  $this->_common_params['note'] .= ' <span class="field_error">'.param_get_error_msg( $field_params['name'] ).'</span>';
2795              }
2796          }
2797  
2798          #pre_dump( 'handle_common_params (after)', $field_params );

2799      }
2800  
2801  
2802      /**

2803       * Display or return, according to {@link $output}.

2804       *

2805       * @return true|string True, if we want to display, the string if not.

2806       */
2807  	function display_or_return( $r )
2808      {
2809          if( $this->output )
2810          {
2811              echo $r;
2812              return true;
2813          }
2814          else
2815          {
2816              return $r;
2817          }
2818      }
2819  
2820  }
2821  
2822  /*

2823   * $Log: _form.class.php,v $

2824   * Revision 1.16  2007/11/02 02:39:57  fplanque

2825   * refactored blog settings / UI

2826   *

2827   * Revision 1.15  2007/11/01 19:52:46  fplanque

2828   * better comment forms

2829   *

2830   * Revision 1.14  2007/10/29 01:24:49  fplanque

2831   * no message

2832   *

2833   * Revision 1.13  2007/10/10 10:52:26  yabs

2834   * validation - linsepan/blockspan/default are probably still invalid

2835   *

2836   * Revision 1.12  2007/10/08 08:31:59  fplanque

2837   * nicer forms

2838   *

2839   * Revision 1.11  2007/10/06 21:04:15  fplanque

2840   * temporary fix

2841   *

2842   * Revision 1.10  2007/09/30 05:00:45  fplanque

2843   * fixes

2844   *

2845   * Revision 1.9  2007/09/29 11:18:35  yabs

2846   * minor bug fix

2847   *

2848   * There's still a problem with the login form that needs fixing

2849   *

2850   * Revision 1.8  2007/09/29 09:48:55  yabs

2851   * minor bug fixes

2852   *

2853   * Revision 1.7  2007/09/29 03:08:24  fplanque

2854   * a little cleanup of the form class, hopefully fixing the plugin screen

2855   *

2856   * Revision 1.6  2007/09/12 21:00:30  fplanque

2857   * UI improvements

2858   *

2859   * Revision 1.5  2007/09/11 08:23:44  yabs

2860   * minor bug fix

2861   *

2862   * Revision 1.4  2007/09/07 20:11:18  fplanque

2863   * Better category selector

2864   *

2865   * Revision 1.3  2007/09/03 16:44:28  fplanque

2866   * chicago admin skin

2867   *

2868   * Revision 1.2  2007/09/02 19:23:42  blueyed

2869   * doc

2870   *

2871   * Revision 1.1  2007/06/25 10:59:01  fplanque

2872   * MODULES (refactored MVC)

2873   *

2874   * Revision 1.82  2007/05/23 09:17:04  blueyed

2875   * Support for stacking in Form::switch_layout()

2876   *

2877   * Revision 1.81  2007/05/15 14:57:24  blueyed

2878   * Fix for Form::select_input_array() "selected"-Handling (cast values to string when comparing)

2879   *

2880   * Revision 1.80  2007/04/26 00:11:07  fplanque

2881   * (c) 2007

2882   *

2883   * Revision 1.79  2007/04/23 15:06:28  blueyed

2884   * radio_input(): Respect "lines" param for "note_format" default value

2885   *

2886   * Revision 1.78  2007/04/20 03:01:12  fplanque

2887   * doc

2888   *

2889   * Revision 1.77  2007/04/16 15:49:59  blueyed

2890   * Minor fixes:

2891   *  - allow "0" as label

2892  fp> once again this should not be documented in the changelog but at the right place in the code

2893  fp> someday it will just get "cleaned up" -> broken again for lack of a comment. Don't complain then...

2894   *  - format-to-output label

2895   *

2896   * Revision 1.76  2007/04/16 15:46:10  blueyed

2897   * Fixed $labelempty for IE6 and "fieldset" layout

2898   *

2899   * Revision 1.75  2007/03/23 14:47:48  blueyed

2900   *  - Display both "required" and "error" states in checklist() and through handle_common_params()

2901   * - "force_keys_as_values" param for select_input_array() (Props A. Becker)

2902   * - cleanup, minor fixes

2903   *

2904   * Revision 1.74  2007/03/23 14:33:23  blueyed

2905   * Re-added $field_params for hidden(), which is needed, e.g. when adding an id to a hidden form element.

2906   *

2907   * Revision 1.73  2007/03/21 01:44:51  fplanque

2908   * item controller: better return to current filterset - step 1

2909   *

2910   * Revision 1.72  2007/03/11 21:29:09  fplanque

2911   * cleanup

2912   *

2913   * Revision 1.71  2007/03/09 15:39:56  blueyed

2914   * radio_input(): Use "checked" param for $field_options if given

2915   *

2916   * Revision 1.70  2007/03/09 15:18:52  blueyed

2917   * Removed bloated "params" usage in Form::radio_input() for $field_options. Now the attribs/params for each radio input are directly in the $field_options entry instead.

2918   *

2919   * Revision 1.69  2007/02/11 15:00:15  fplanque

2920   * keeping JS abstraction.

2921   *

2922   * Revision 1.67  2007/01/24 06:43:25  fplanque

2923   * fix

2924   *

2925   * Revision 1.66  2007/01/23 08:57:36  fplanque

2926   * decrap!

2927   *

2928   * Revision 1.65  2007/01/07 05:25:09  fplanque

2929   * "fixed" regression :/

2930   *

2931   * Revision 1.64  2006/12/22 22:22:20  blueyed

2932   * Unset "maxlength" field_param in textarea_input(): not a html attrib

2933   *

2934   * Revision 1.63  2006/12/13 19:34:25  fplanque

2935   * doc

2936   *

2937   * Revision 1.62  2006/12/13 18:00:35  blueyed

2938   * Allow "0" as note (again) + avoid unnecessary negation

2939   *

2940   * Revision 1.61  2006/12/10 23:17:10  fplanque

2941   * oops

2942   *

2943   * Revision 1.60  2006/12/10 22:17:04  fplanque

2944   * added note support to select_input

2945   *

2946   * Revision 1.59  2006/12/10 12:42:40  blueyed

2947   * "maxlength" handling for textarea fields through javascript

2948   *

2949   * Revision 1.58  2006/12/09 01:55:36  fplanque

2950   * feel free to fill in some missing notes

2951   * hint: "login" does not need a note! :P

2952   *

2953   * Revision 1.57  2006/12/08 02:08:01  uid156866

2954   * MFH: Fixed "Write" page/tab for Firefox 1.0.x

2955   *

2956   * Revision 1.56  2006/12/07 23:13:13  fplanque

2957   * @var needs to have only one argument: the variable type

2958   * Otherwise, I can't code!

2959   *

2960   * Revision 1.55  2006/12/06 19:12:11  fplanque

2961   * not all comments are something "TO DO". Some really just are "comments"

2962   *

2963   * Revision 1.54  2006/12/06 18:48:20  blueyed

2964   * doc

2965   *

2966   * Revision 1.53  2006/12/06 18:06:18  fplanque

2967   * an experiment with JS hiding/showing form parts

2968   *

2969   * Revision 1.52  2006/11/24 18:27:27  blueyed

2970   * Fixed link to b2evo CVS browsing interface in file docblocks

2971   *

2972   * Revision 1.51  2006/11/19 22:17:42  fplanque

2973   * minor / doc

2974   *

2975   * Revision 1.50  2006/11/19 15:52:27  blueyed

2976   * Fixed E_NOTICE with Form::hidden

2977   *

2978   * Revision 1.49  2006/11/18 17:58:57  blueyed

2979   * added DIV.inline and use it additionally for span.line replacement

2980   *

2981   * Revision 1.48  2006/11/16 23:48:56  blueyed

2982   * Use div.line instead of span.line as element wrapper for XHTML validity

2983   *

2984   * Revision 1.47  2006/11/16 20:03:25  blueyed

2985   * Cleanup; added $infoend support

2986   *

2987   * Revision 1.46  2006/11/16 01:49:40  fplanque

2988   * doc

2989   *

2990   * Revision 1.45  2006/11/08 17:47:55  blueyed

2991   * Extra classes 'form_text_input' and 'form_textarea_input' to enable IE6 CSS selection

2992   *

2993   * Revision 1.44  2006/11/05 20:13:57  fplanque

2994   * minor

2995   *

2996   * Revision 1.43  2006/11/03 14:25:24  blueyed

2997   * Made Form::get_valid_id() static

2998   *

2999   * Revision 1.42  2006/10/14 16:07:54  blueyed

3000   * Overwrite previous added hidden fields (by default), when adding hidden inputs.

3001   */
3002  ?>


Généré le : Thu Nov 29 23:58:50 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics