ObjectForm

Derek Jones edited this page Jul 5, 2012 · 14 revisions
Clone this wiki locally

Category:Helper::Community | Category:Helper::Forms

The form helper provided with CodeIgniter is a good idea to help view creators in managing forms ; for example, the form_dropdown() function is really time and code length improving, but some function prototypes don't suit me. I hope this new helper will be useful to you as it was for me. I first created it with PHP5 notations, but I revised my jugement to make it PHP4 compatible and share it.

You'll find to complete and commented code at the end of this document. Name it as you want (I've choosen objform_helper.php).

I've reuse the form helper documentation for most of methods description, as they're just equivalents.

Object oriented

The first big difference is that I've coded it as a class instead of a serie of function, because I prefer the object syntax even a views. So once you've loaded the helper, you've to instanciate a Form object:


$this->load->helper('objform');
$viewdata['form'] = new Form();
...

Then you can use the public methods, which are for most of them equivalents to the original form helper.

The second big difference is that its methods don't have the double list of parameters/one array syntax. The second one isn't useful for me (it may be for you of course :-)).

Changelog

Dates are in iso format so no ambiguity ;-) (I'm french, my natural format is dd/mm/yyyy) 20070227 - integrated foxzgerald's update for multiple selection on listbox

Methods list

open()

open($action, $post = true, $name = '', $id = false, $attributes = null, $append = true)

Creates an opening form tag with a base URL built from your config preferences. It will optionally let you choose between the get and post methods, and add attributes. The last three parameters are common to all element definition methods, see The 3 magic parameters at the end for an explaination of their use.

open_multipart()

open_multipart($action, $name = '', $id = false, $attributes = null, $append = true)

This method is absolutely identical to the open() method above except that it adds a multipart attribute, which is necessary if you would like to use the form to upload files with. The post method is also automatically set.

close()

close($append = false)

Produces a closing </form> tag. The only advantage to using this function is it permits you use the last of the 3 common parameters, and being consistent with the helper usage.

hidden()

hidden($name, $value = '', $id = false, $attributes = null, $append = true)

Lets you generate hidden input fields.

text()

text($name = '', $value = '', $id = false, $attributes = null, $append = true)

Lets you generate a standard text input field.

password()

password($name = '', $value = '', $id = false, $attributes = null, $append = true)

This method is identical in all respects to the text() method above except that is sets it as a "password" type.

upload()

upload($name = '', $value = '', $id = false, $attributes = null, $append = true)

This method is identical in all respects to the text() method above except that is sets it as a "file" type, allowing it to be used to upload files.

textarea()

textarea($name = '', $value = '', $id = false, $attributes = null, $append = true)

This method isn't finished yet, I'll edit the document when it's be done (the rows and cols should be accessible as parameters).

dropdown()

dropdown($name = '', $options = array(), $selected = '', $id = false, $attributes = null, $append = true)

Lets you create a standard drop-down field. The first parameter will contain the name of the field, the second parameter will contain an associative array of options, and the third parameter will contain the value you wish to be selected.

listbox()

listbox($name = '', $options = array(), $size = -1, $selected = '', $id = false, $attributes = null, $append = true)

This method is identical in all respects to the dropdown() method above except that is sets it as a "plain" select element, passing it the number of element displayed ($size).

checkbox()

checkbox($name = '', $value = '', $checked = true, $id = false, $attributes = null, $append = true)

Lets you generate a checkbox field. The third parameter can be a string value instead of a boolean, and will be in this case compared to the value parameter.

radio()

radio($name = '', $value = '', $selected = false, $id = false, $attributes = null, $append = true)

This method is identical in all respects to the checkbox() method above except that is sets it as a "radio" type.

submit()

submit($name = '', $value = '', $id = false, $attributes = null, $append = true)

Lets you generate a standard submit button.

reset()

reset($name = '', $value = '', $id = false, $attributes = null, $append = true)

This method is identical in all respects to the submit() method above except that is sets it as a "reset" type.

Other helper methods

post()

post($item, $default = '')

Shortcut to get $_POST[] items, providing a default value if not set.

protect()

protect($str)

Protect values from html processing (it's a strict equivalent to form_prep() from the form helper).

The 3 magic parameters

The last parameters found on almost all methods:

  • id : id attribute
  • attributes : additional attributes
  • append : string to append after the element are computed, to make the life of the view coder easier.

$id

This parameter tells if an 'id' attribute must be set, and if so, it's value.

If it's a string value, it will be use nearly 'as is' (see The id prefix below). If it's a boolean and is false (the default), the attribute isn't set, if it's a boolean and is true, the id attribute will have the same value as the name attribute (nearly, see The id prefix).

Thus, putting and id attribute equals to the name one is as easy as specifying 'true' to the method.

$attributes

This parameter is just an associative array which contains additional parameters to set.

$append

Depending on how you terminate the line containing your method call, a newline may or may not be output. Additionaly, you may want to add some string after the creation of the element.

If $append is a string, it will be use 'as is'. If it's a boolean and is false, nothing will be appended. If it's a boolean and is true (the default), a unique newline character ('\n') will be added.

The id prefix

To avoid id conflicts, you may want to distinguish ids from form names, but it's not cool to loose the 'magic id generation' just for this reason. So you can specify a prefix that will be added to all element ids. This's done by giving an argument to the object constructor:

Form($prefix = '')

For example, this:

$form = new Form('create_');
...
$form->open('user/create', true, 'form', true);

will generate


&lt;form method="post" action="http://your.site-url.com/user/create" name="form" id="create_form"&gt;

The complete class

&lt;?php

/**
 * The Form class is an alternative to the CI provided form helper, in an
 * object way, and with some different behaviors.
 * 
 * @author Richard 'riri' Gill <richard@houbathecat.info>
 * @license public domain
 * 
 * To use it, just load the 'objform' helper like any other, and create the
 * Form object with: &lt;?php $form = new Form(); ?&gt;.
 */
class Form {

    /**
     * Stored prefix from the constructor.
     * 
     * @access private
     * @see Form()
     */
    var $_prefix = '';

    /**
     * Reference to the current controller global instance.
     * 
     * @access private
     */
    var $_ci = null;

    /**
     * Constructor. You can optionally pass a 'prefix' if you use the 'id'
     * attribute for form elements. This prefix will be addded to any id
     * generated by the form methods.
     *
     * @access public 
     * @param string prefix id prefix for elements
     * @see _make_id()
     */
    function Form($prefix = '') {

        $this->_prefix = $prefix;
        $this->_ci =& get_instance();
    }

    /**
     * Shortcut to deal with $_POST[]. If $_POST[$item] is defined, it will
     * return its value, the $default value (which defaults to '') otherwise.
     *
     * @access public 
     * @param string item $_POST[] item
     * @param mixed default default value if $_POST[$item] isn't set
     * @return mixed post item or default value
     */
    function post($item, $default = '') {

        return (isset($_POST[$item]) ? $_POST[$item] : $default);
    }

    /**
     * Protect values from html processing (equivalent to form_prep() from
     * the form helper).
     * 
     * @access public
     * @param string str the string to transform
     * @return string the transformed string
     */
    function protect($str) {

        if ($str == '') {
            return '';
        }
        return str_replace(array("'", '"'), array("&#39;", "&quot;"), htmlspecialchars($str));
    }


    /**
     * Create the form open tag (equivalent to form_open() from the form helper).
     * 
     * @access public
     * @param string action action the form will perform
     * @param boolean post post or get ?
     * @param string name form name attribute
     * @param mixed id form id attribute (see _make_id())
     * @param array attributes additional attributes in an associative array
     * @param mixed append things to append after the element (see _make_append())
     * @return string form open tag element
     */
    function open($action, $post = true, $name = '', $id = false, $attributes = null, $append = true) {

        $post = ($post) ? 'post' : 'get';
        return '&lt;form method="'.$post.'" action="'.$this-&gt;_ci->config->site_url($action).'"' .
            $this->_parse_entry($name, null, $id, $attributes) .
            '>' .
            $this->_make_append($append);
    }

    /**
     * Create the form open tag for multipart datas (equivalent to form_open_multipart()
     * from the form helper). The post method is automatically set.
     *
     * @access public
     * @param string action action the form will perform
     * @param string name form name attribute
     * @param mixed id form id attribute (see _make_id())
     * @param array attributes additional attributes in an associative array
     * @param mixed append things to append after the element (see _make_append())
     * @return string form open tag element
     */
    function open_multipart($action, $name = '', $id = false, $attributes = null, $append = true) {

        $attributes['enctype'] = 'multipart/form-data';
        return $this->open($action, true, $name, $id, $attributes, $append);
    }

    /**
     * Create the form closing tag (equivalent to form_close() from the form helper).
     * 
     * @access public
     * @param mixed append things to append after the element (see _make_append())
     * @return string form closing tag element
     */
    function close($append = false) {

        return '&lt;/form&gt;'.$this->_make_append($append);
    }

    /**
     * Create a hidden input (equivalent to form_hidden() from the form helper).
     * 
     * @access public
     * @param string name input name attribute
     * @param string value input value attribute
     * @param mixed id input id attribute (see _make_id())
     * @param array attributes additional attributes in an associative array
     * @param mixed append things to append after the element (see _make_append())
     * @return string computed element
     */
    function hidden($name, $value = '', $id = false, $attributes = null, $append = true) {

        return '&lt;input type="hidden"' .
            $this-&gt;_parse_entry($name, $value, $id, $attributes) .
            ' />'.$this->_make_append($append);
    }

    /**
     * Create a text input (equivalent to form_input() from the form helper).
     * 
     * @access public
     * @param string name input name attribute
     * @param string value input value attribute
     * @param mixed id input id attribute (see _make_id())
     * @param array attributes additional attributes in an associative array
     * @param mixed append things to append after the element (see _make_append())
     * @return string computed element
     */
    function text($name = '', $value = '', $id = false, $attributes = null, $append = true) {

        return '&lt;input type="text"' .
            $this-&gt;_parse_entry($name, $value, $id, $attributes) .
            ' />' .
            $this->_make_append($append);
    }

    /**
     * Create a password input (equivalent to form_password() from the form helper).
     * 
     * @access public
     * @param string name input name attribute
     * @param string value input value attribute
     * @param mixed id input id attribute (see _make_id())
     * @param array attributes additional attributes in an associative array
     * @param mixed append things to append after the element (see _make_append())
     * @return string computed element
     */
    function password($name = '', $value = '', $id = false, $attributes = null, $append = true) {

        return '&lt;input type="password"' .
            $this-&gt;_parse_entry($name, $value, $id, $attributes) .
            ' />' .
            $this->_make_append($append);
    }

    /**
     * Create a file upload input (equivalent to form_upload() from the form helper).
     * 
     * @access public
     * @param string name input name attribute
     * @param string value input value attribute
     * @param mixed id input id attribute (see _make_id())
     * @param array attributes additional attributes in an associative array
     * @param mixed append things to append after the element (see _make_append())
     * @return string computed element
     */
    function upload($name = '', $value = '', $id = false, $attributes = null, $append = true) {

        return '&lt;input type="file"' .
            $this-&gt;_parse_entry($name, $value, $id, $attributes) .
            ' />' .
            $this->_make_append($append);
    }

    /**
     * Create a textarea input (equivalent to form_textarea() from the form helper).
     * 
     * @access public
     * @param string name input name attribute
     * @param string value input value attribute
     * @param mixed id input id attribute (see _make_id())
     * @param array attributes additional attributes in an associative array
     * @param mixed append things to append after the element (see _make_append())
     * @return string computed element
     */
    function textarea($name = '', $value = '', $id = false, $attributes = null, $append = true) {

        return '&lt;input type="textarea"' .
            $this-&gt;_parse_entry($name, $value, $id, $attributes) .
            ' />' .
            $this->_make_append($append);
    }

    /**
     * Create a dropdown box (equivalent to form_dropdown() from the form helper).
     * 
     * @access public
     * @param string name input name attribute
     * @param array options array of defined options
     * @param string selected the value that should be selected
     * @param mixed id input id attribute (see _make_id())
     * @param array attributes additional attributes in an associative array
     * @param mixed append things to append after the element (see _make_append())
     * @return string computed element
     */
    function dropdown($name = '', $options = array(), $selected = '', $id = false, $attributes = null, $append = true) {

        $entry = '<select' .
            $this->_parse_entry($name, null, $id, $attributes) . '>';
        foreach ($options as $key => $group) {
            if (!is_array($group)) {
                $grouplabel = '';
                $group = array($key => $group);
            }
            else {
                $grouplabel = $key;
                $entry .= '<optgroup label="' . $grouplabel . '">';
            }
            foreach ($group as $value => $label) {
                $entry .= '<option value="' . $value . '"' .
                    $this->_input_set($value, $selected, 'selected') . '>' .
                    $label . '</option>';
            }
            if ($grouplabel != '') {
                $entry .= '</optgroup>';
            }
        }
        return $entry . '</select>' . $this->_make_append($append);
    }

    /**
     * Create a list box (<select> with the size attribute).
     * 
     * @access public
     * @param string name input name attribute
     * @param array options array of defined options
     * @param integer size number of displayed items (defaults to all)
     * @param string selected the value that should be selected, or an array of for multiple selections
     * @param mixed id input id attribute (see _make_id())
     * @param array attributes additional attributes in an associative array
     * @param mixed append things to append after the element (see _make_append())
     * @return string computed element
     */
    function listbox($name = '', $options = array(), $size = -1, $selected = '', $id = false, $attributes = null, $append = true) {

        if (!(is_array($attributes))) {
            $attributes = array();
        }
        if ($size == -1) {
            $size = count($options);
        }
        if (!array_key_exists('size', $attributes)) {
            $attributes['size'] = $size;
        }
    if (is_array($selected) && !array_key_exists('multiple', $attributes)) {
        $attributes['multiple'] = 'multiple';
    }
        return $this->dropdown($name, $options, $selected, $id, $attributes, $append);
    }

    /**
     * Create a check box (equivalent to form_checkbox() from the form helper).
     * 
     * @access public
     * @param string name input name attribute
     * @param string value input value attribute
     * @param mixed checked checked or not if boolean or if equals the value 
     * @param mixed id input id attribute (see _make_id())
     * @param array attributes additional attributes in an associative array
     * @param mixed append things to append after the element (see _make_append())
     * @return string computed element
     */
    function checkbox($name = '', $value = '', $checked = true, $id = false, $attributes = null, $append = true) {

        return '&lt;input type="checkbox"' .
            $this-&gt;_parse_entry($name, $value, $id, $attributes) .
            $this->_input_set($value, $checked, 'checked') .
            ' />' .
            $this->_make_append($append);
    }

    /**
     * Create a check box (equivalent to form_checkbox() from the form helper).
     * 
     * @access public
     * @param string name input name attribute
     * @param string value input value attribute
     * @param mixed selected selected (checked) or not if boolean or if equals the value 
     * @param mixed id input id attribute (see _make_id())
     * @param array attributes additional attributes in an associative array
     * @param mixed append things to append after the element (see _make_append())
     * @return string computed element
     */
    function radio($name = '', $value = '', $selected = false, $id = false, $attributes = null, $append = true) {

        return '&lt;input type="radio"' .
            $this-&gt;_parse_entry($name, $value, $id, $attributes) .
            $this->_input_set($value, $selected, 'checked') .
            ' />' .
            $this->_make_append($append);
    }

    /**
     * Create a submit input button (equivalent to form_submit() from the form helper).
     * 
     * @access public
     * @param string name input name attribute
     * @param string value input value attribute
     * @param mixed id input id attribute (see _make_id())
     * @param array attributes additional attributes in an associative array
     * @param mixed append things to append after the element (see _make_append())
     * @return string computed element
     */
    function submit($name = '', $value = '', $id = false, $attributes = null, $append = true) {

        return '&lt;input type="submit"' .
            $this-&gt;_parse_entry($name, $value, $id, $attributes) .
            ' />' .
            $this->_make_append($append);
    }

    /**
     * Create a reset input button
     * 
     * @access public
     * @param string name input name attribute
     * @param string value input value attribute
     * @param mixed id input id attribute (see _make_id())
     * @param array attributes additional attributes in an associative array
     * @param mixed append things to append after the element (see _make_append())
     * @return string computed element
     */
    function reset($name = '', $value = '', $id = false, $attributes = null, $append = true) {

        return '&lt;input type="reset"' .
            $this-&gt;_parse_entry($name, $value, $id, $attributes) .
            ' />' .
            $this->_make_append($append);
    }

    /**
     * Take the $id parameter from public methods and output the computed result
     * based on the following rules:
     * - boolean and false, or empty : nothing
     * - boolean and true : equals the $name argument
     * - other values : the specified argument (prefixed if defined by the constructor)
     * 
     * @access private
     * @param string name the $name parameter from public methods
     * @param mixed id the $id parameter from public methods
     * @return string computed id
     */

    function _make_id($name, $id) {

        if ($id === false) {
            return '';
        }
        if ($id === true) {
            $id = $name;
        }
        return ($id != '') ? $this->_prefix . $id : '';
    }

    /**
     * Take the $append parameter from public methods and output the computed
     * result based on the following rules:
     * - boolean and false : nothing
     * - boolean and true : newline
     * - other value : the specified argument
     * 
     * @access private
     * @param mixed append the $append parameter from public methods
     * @return string computed append string
     */
    function _make_append($append) {

        if ($append === false) {
            return '';
        }
        if ($append === true) {
            return "\n";
        }
        return $append;
    }

    /**
     * Output a string of type 'attr="attr"' if $have is boolean and true
     * or equals to $should.
     * 
     * @access private
     * @param mixed should the value $have should have if not boolean
     * @param mixed $have boolean or value to test against $should
     * @param string put the attribute 'pair' to compute
     * @return string the attribute pair or nothing 
     */
    function _input_set($should, $have, $put) {

    if (is_array($have)) {
        $have = in_array($should, $have);
    }
        if (!is_bool($have)) {
            $have = ($have === $should);
        }
        return ($have) ? ' ' . $put . '="' . $put . '"' : '';
    }

    /**
     * Generic method to compute common public method arguments.
     * 
     * @access private
     * @param string name name attribute
     * @param string value value attribute
     * @param mixed id computed by _make_id()
     * @param array attributes array of attributes to add
     * @return string list of computed attributes
     */
    function _parse_entry($name, $value, $id, $attributes) {

        if (!is_array($attributes)) {
            $attributes = array();
        }

        if ($name != '') {
            $attributes['name'] = $name;
        }
        if (is_string($value)) {
            $attributes['value'] = $this->protect($value);
        }
        if ($id != '') {
            $attributes['id'] = $this->_make_id($name, $id);
        }

        $result = '';
        foreach ($attributes as $key => $val) {
            $result .= ' ' . $key . '="' . $val . '"';
        }
        return $result;
    }

}
?&gt;

A little modification for supporting multiple selection in listbox()

riri:this section could be removed as I integrated your modification ;-)

// After modification ...
// $default_selected_array will make option A and C to be selected as default.
$options = array ( 1=> "option A", 2 => "option B", 3 => "option C");
$default_selected_array = array (1, 3);  // maybe comes from some db querying results

$form->listbox('example', $options, -1, $default_selected);

_input_set()

    function _input_set($should, $have, $put) {     
        //------------------
        if (is_array($have)) {
            $have = in_array($should, $have);   // exam if value exists in array $should
        }
        //------------------
        if (!is_bool($have)) {
            $have = ($have === $should);
        }
        return ($have) ? ' ' . $put . '="' . $put . '"' : '';
    }

listbox()

    function listbox($name = '', $options = array(), $size = -1, $selected = '', $attributes = null, $id = false, $append = true) {
        if (!(is_array($attributes))) {
            $attributes = array();
        }
        if ($size == -1) {
            $size = count($options);
        }
        if (!array_key_exists('size', $attributes)) {
            $attributes['size'] = $size;
        }
        //------------------
        if (is_array($selected) && !array_key_exists('multiple', $attributes)) {
            $attributes['multiple'] = 'multiple';                                                 
        }
        //------------------
        return $this->dropdown($name, $options, $selected, $attributes, $id, $append);
    }