Sam Bernard

forms

Cakephp Model-less Form Helper

Posted by Sam Bernard on Fri, Mar 11 2011 23:50:00

Below is a simple helper I've creating to help with generating forms, using field names and options stored in a database. It's actually a modified version of the helper I created for my Cakeforms plugin- an easy to use form plugin for Cakephp/Croogo that basically allows people to create forms for their Croogo site without having to write any code. I'll post about it when I get the time to clean it up and update the git repo.

This helper assumes you are passing an array of fields with the following options:

$formField['FormField'] = array(
    array(
        'name' => 'field_name', //required
        'label' => 'field_label',
        'type' => 'type', //required. Options: fieldset, text, textbox, disabled, textonly, select, checkbox, radio,
        'default' => 'default_value',
        'options' => array('option1' => 'value', //options for checkbox, select and radio
                           'option2' => 'value')
    )

I actually store all these values in a database table- in my model's afterFind() function I convert options from a comma separated list to an associative array.

Below is a basic version of the helper. Put this in your app/views/helpers/ folder and call it cakeform.php. You can download the file here: cakeform.php

class CakeformHelper extends AppHelper {
    public $helpers = array('Html', 'Form', 'Javascript');

/**
 * used in generating form fieldsets
 *
 * @access public
 */
    public $openFieldset = false;

/**
 * Generates form HTML
 *
 * @param array $formData
 * @param mixed $action
 *
 * @return string Form Html
 * @access public
 */
    function insert($formFields, $action){

            $out .= $this->Form->create('Form', array('url' => $action));

            if(isset($formFields['FormField'])){
                foreach($formFields['FormField'] as $field){
                    $out .= $this->field($field);
                }
            }

            if($this->openFieldset == true){
                    $out .= "</fieldset>";
            }

            $out .= $this->Form->end('Submit');

            return $this->output($out);
    }

/**
 * Generates appropriate html per field
 *
 * @param array $field Field to process
 * @parram array $custom_options Custom $form->input options for field
 *
 * @return string field html
 * @access public
 */
    function field($field, $custom_options = array()){
        $options = array();
        $out = '';

        if(!empty($field['type'])){
                switch($field['type']){
                    case 'fieldset':
                        if($this->openFieldset == true){
                                $out .= "</fieldset>";
                        }

                        $out .=  "<fieldset>";
                        $this->openFieldset = true;

                        if(!empty($field['name'])){
                                $out .= "<legend>".Inflector::humanize($field['name'])."</legend>";
                                $out .= $this->Form->hidden('fs_' . $field['name'], array('value' => $field['name']));
                        }
                    break;

                    case 'textonly':
                        $out = $this->Html->para('textonly', $field['label']);
                    break;

                    default:
                        $options['type'] = $field['type'];
                        if(in_array($field['type'], array('select', 'checkbox', 'radio'))){

                                if($field['type'] == 'checkbox'){
                                    if(count($field['options']) > 1){
                                            $options['type'] = 'select';
                                            $options['multiple'] = 'checkbox';
                                            $options['options'] = $field['options'];
                                    } else {
                                        $options['value'] = $field['name'];
                                    }
                                } else {
                                    $options['options'] = $field['options'];
                                    $options['empty'] = 'select one';
                                }

                        }

                        if(!empty($field['depends_on']) && !empty($field['depends_value'])){
                            $options['class'] = 'dependent';
                            $options['dependsOn'] = $field['depends_on'];
                            $options['dependsValue'] = $field['depends_value'];
                        }

                        if(!empty($field['label'])){
                                $options['label'] = $field['label'];

                                if($field['type'] == 'radio'){
                                    $options['legend'] = $field['label'];
                                }
                        }

                        if($field['type'] == 'radio' && count($field['options']) == 2 ){
                            $options['div'] = 'input radio bool';
                            $options['legend'] = false;
                            $options['before'] = $this->Html->div('radio-label', $field['label']);
                        }

                        if(!empty($field['default']) && empty($this->data['Form'][$field['name']])){
                                $options['value'] = $field['default'];
                        }

                        $options = Set::merge($custom_options, $options);
                        $out .= $this->Form->input($field['name'], $options);
                        break;
                }
        }
        return $out;
    }
}