Skip to content
World Wide Web Server edited this page Jul 4, 2012 · 28 revisions

Category:Libraries::Data Presentation

The Form library is a complete replacement for the Form helper. It reads an XML document and converts it to an array (via the Xml_Library).

[b]Updates:[/b]

2006-11-04:

  • Made validate() set the form values, no need to set them manually
  • Tweaked the valid types and attributes

[b]Features:[/b]

  • Built in validation using CI Validation
  • 1 call data retrieval
  • XHTML 1.0 output code
  • written for PHP5 ([b]not[/b] PHP4 compatible)

[b]Example Usage:[/b] [code]$this->load->library('form'); $this->form->load('login'); // Relative to APPPATH/data/forms/, ".xml" appended if ($data = $this->form->post_data()) { print_r($data); } else { print $this->form->build(); }[/code]

[b]Library:[/b] [code]<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/***

*/

class Form {

public function Form () { /*** * @constructor / $obj =& get_instance(); $obj->load->library('xml'); $this->ci =& $obj; } /** END ***/

/*** Public variables ***/ public $error = ''; public $set_error = ''; public $output = '';

/*** Internal variables ***/ private $ci; private $rules; private $data; private $set_data; private $elements; private $action;

public function load ($name) { /*** * @public * Load a form definition for parsing */ if (! $this->ci->xml->load ("data/forms/$name")) { $this->error = "Failed to load form: $name"; return false; }

$data = $this->ci->xml->parse ();
if (! is_array($data)) {
  $this->error = "No form data found in /data/forms/$name.xml";
  return false;
}
else {
  $data = $data['form'][0];

  $this->data     = $data;
  $this->action   = $data['__attrs']['action'];
  $this->elements = $this->get_fields($data);
}

return true;

} /*** END load ***/

private function get_fields ($array) { /*** * @private * Extract the rules and field names from the data */ $return = array();

foreach ($array as $key => $val) {
  if ($key == 'fieldset' && is_array ($val)) {
    $return = array_merge ($return, $this->get_fields ($val));
  }
  else {
    if (! is_numeric ($key) && $key != '__attrs' && $key != 'fieldset') {
      $return[] = $key;

      foreach ($val as $_key => $_val) {
        if (isset ($_val['__attrs']) && isset ($_val['__attrs']['rules'])) {
          $this->rules[$key] = $_val['__attrs']['rules'];
        }
      }
    }
  }
}

return array_unique ($return);

} /*** END get_fields ***/

public function set_action ($location) { /*** * @public * Set the form action */

$this->action = $location;
return true;

} /** END action ***/

public function set ($element, $key, $value = false) { /*** * @public * Set an attribute of an element, or a new elemenet */ if (is_array ($key)) { foreach($key as $_key => $_value) { $this->set($element, $_key, $_value); }

  return true;
}

$this->set_data[$element][$key] = $value;
return true;

} /*** END set ***/

public function post_data ($validate = true) { /*** * @public * Return all the post data from the loaded form */ if ($validate == true && !$this->validate ()) { return false; } if (! is_array($this->elements)) { return false; }

$data = array ();
foreach ($this->elements as $elem) {
  $data[$elem] = $this->ci->input->post($elem);
}

return $data;

} /*** END post_data ***/

public function validate ($name = false) { /*** * @public * Validates a form based on the rules found in the definition */ if ($name != false && ! $this->load ($name)) { return false; } elseif (! is_array ($this->rules)) { return false; }

$this->ci->load->library ('validation');
$this->ci->validation->set_rules ($this->rules);

if ($this->ci->validation->run())  {
  return true;
}
else {
  foreach ($this->post_data (false) as $key => $val) {
    if ($val != false) { // Set default values
      $this->set($key, 'value', $val);
    }
  }

  $this->set_error = '';
  foreach ($this->ci->validation->_error_array as $error) {
    $alt = (isset ($alt) && $alt == '')
      ? ' alt'
      : '';

    $this->set_error .= "\t<p class=\"error$alt\">$error</p>\n";
  }
}

return false;

} /*** END validate ***/

private function build_group ($group, $depth = 0) { static $first_run;

// Set the valid attributes and type values
$valid_attr = array(
  'type', 'maxlength', 'value',
  'selected', 'rows', 'cols',
  'onclick', 'onmouseover', 'onmouseout', 'onchange'
  );
$valid_type = array(
  'text', 'textarea', 'password',
  'dropdown', 'radio', 'checkbox',
  'submit', 'button'
  );
$tabs = repeater("\t", $depth);

$html  = sprintf ("$tabs".'<fieldset><legend>%s</legend>'."\n", $group['__attrs']['name']);
if ($first_run !== false) {
  $html .= "$tabs". preg_replace("|\n\t+|", "\n$tabs\t", $this->set_error) ."\n";
  $first_run = false;
}

$html .= "$tabs\t".'<ol class="form">'."\n";

foreach ($group as $name => $val) {
  if ($name == '__attrs') {
    continue;
  }
  elseif ($name == 'fieldset') {
    foreach ($val as $_group) {
      $html .= "$tabs\t<li>\n". $this->build_group ($_group, $depth+2) ."$tabs\t</li>\n";
    }
  }
  else {
    foreach ($val as $index => $def) {
      foreach ($def as $key => $val) {
        if ($key == '__attrs') {
          unset ($def[$key]);
          continue;
        }

        $def[$key] = $val[0];
      }

      // Skips defs that have no type attribute
      if (! isset($def['type']) || ! in_array ($def['type'], $valid_type)) {
        continue;
      }

      // Externally set data is present, merge with stored efinition
      if (isset ($this->set_data[$name]) && is_array ($this->set_data[$name])) {
        $def = array_merge($def, $this->set_data[$name]);
      }

      // Choose a label
      $label = isset($def['label'])
        ? ucwords($def['label'])
        : ucwords($name);

      $label = strip_tags($label);

      // Create the id and name attributes
      $idname = sprintf('name="%s" id="%s"', $name, $name);

      // Add "*" on required items
      $label = isset ($def['required']) && $def['required'] == true
        ? "$label <em>*</em>"
        : $label;

      $row  = "";
      $row .= "$tabs\t<li>\n";
      $row .= $def['type'] != 'submit'
        ? "$tabs\t\t<label>$label</label>\n"
        : "";

      // Handle non-input elements
      switch ($def['type']) {
      case 'textarea':
        $input  = "$tabs\t\t&lt;textarea $idname %s&gt;". $def['value'] ."&lt;/textarea&gt;\n";
        unset ($def['type'], $def['value']);
        break;
      case 'dropdown':
        $options = "";
        foreach ($def['options'] as $_key => $_val) {
          $options = "$tabs\t\t\t<option value=\"$_val\">$_key</option>\n";
        }

        $input = "$tabs\t\t<select $idname %s >\n$options</select>\n";
        unset ($def['type'], $def['options']);
        break;
      default:
        $input = "$tabs\t\t&lt;input $idname %s /&gt;\n";
      }

      // Parse attributes
      $attributes = '';
      foreach ($def as $attr => $val) {
        if (in_array ($attr, $valid_attr)) {
          $attributes .= " $attr=\"$val\" ";
        }
      }
      $row .= sprintf($input, $attributes);

      $row .= "$tabs\t</li>\n";
      $html .= "$row";
    }
  }

}
$html .= "$tabs\t".'</ol>'."\n";
$html .= "$tabs".'</fieldset>'."\n";

return $html;

}

public function build ($name = false) { /*** * @public * Convert a form definition into an XHTML form */ if ($name != false && ! $this->load ($name)) { return false; } elseif (! is_array ($this->data)) { return false; } $this->ci->load->helper('string');

$out =& $this->output;
$out  = '';
$out .= sprintf("".'&lt;form action="%s" id="%s" method="post"&gt;'."\n",
  site_url($this->action),
  strtolower(preg_replace('|\W|', '_', $this->data['__attrs']['name']))
  );

foreach ($this->data['fieldset'] as $group) {
  $out .= $this->build_group($group);
}

$out .= "&lt;/form&gt;\n";

$this->output = $out;
return $out;

} /*** END build ***/

}

?>[/code]

[b]Sample Form:[/b] [code]<?xml version="1.0" encoding="UTF-8" ?> <form action="user/login" name="user_login">

text 32 true password 32 true submit Login </form>[/code]
Clone this wiki locally