klenwell information services : Paste20090110

Klenwell Form Helper: options to table


For converting a radio group to columns in CakePhp. For more information, see http://www.klenwell.com/press/2009/01/cakephp-radio-select-columns/

helper code

<?php

class KlenwellFormHelper extends Helper
{  
    var $name = 'klenwellForm';
   
    var $before_marker = '<!-- _before_ -->';
    var $after_marker = '<!-- _after_ -->';
    var $separator_marker = '<!-- _separator_ -->';
   
    var $table_class = 'klenwell-option-table';


    function options_to_table($input, $num_cols=2)
    {
        /* Converts an input list into a table.  Requires before, after, and
           separator options be set like so:
         
            print $klenwellFormHelper->input_to_table(
                $form->input('Model.field', array('type'=>'radio',
                                 'legend'=>'Label',
                                 'value'=>$selected_value,
                                 'before' => $klenwellFormHelper->before_marker,
                                 'after' => $klenwellFormHelper->after_marker,
                                 'separator' => $klenwellFormHelper->separator_marker,
                                 'options'=>$Model->field_options));
            );
        */

       
        // slice up form input method output at markers
        // sanity check
        if ( strpos($input, $this->before_marker) === false ||
             strpos($input, $this->after_marker) === false ||
             strpos($input, $this->separator_marker) === false )
        {
            trigger_error('unable to convert list to table, missing before, after, or between marker', E_USER_WARNING);
            return $this->output("<!-- Unable to convert to table / missing marker -->\n{$input}");
        }
       
        // get top, bottom, and middle chunks
        list($top, $trunk) = explode($this->before_marker, $input);
        list($middle, $bottom) = explode($this->after_marker, $trunk);
       
        // get option list
        $OptionList = explode($this->separator_marker, $middle);
        $num_options = count($OptionList);
       
        // cakephp doesn't cooperate with its before and after placement so we
        // have to do some tweaks here
        $ftag1 = '<fieldset>';
        $ftag2 = '</fieldset>';
        $legend_regex = '%<legend>.*</legend>%U';
       
        if ( strpos($OptionList[0], $ftag1) !== false )
        {
            $OptionList[0] = str_replace($ftag1, '', $OptionList[0]);
            $top .= $ftag1;
        }
        if ( $legend = preg_match($legend_regex, $OptionList[0], $Match) )
        {
            $OptionList[0] = str_replace($Match[0], '', $OptionList[0]);
            $top .= $Match[0];
        }
        if ( strpos($OptionList[$num_options-1], $ftag2) !== false )
        {
            $OptionList[$num_options-1] = str_replace($ftag2, '', $OptionList[$num_options-1]);
            $bottom = $ftag2 . $bottom;
        }
       
        // divvy options into columns (wrote this code a while ago and seems to work)
        for( $i = 1; $i <= $num_cols; $i++ )
        {
            $COL[$i] = ceil( $num_options/($num_cols+1-$i) );
            $num_options = $num_options - $COL[$i];
        }
       
        // add tags to columns
        $opt_num = 0;
        $table_cells = '';
        foreach ( $COL as $n => $num_in_col )
        {
            $col_list = '';
            while( $num_in_col > 0 )
            {
                $col_list .= "<li>{$OptionList[$opt_num]}</li>\n";
                $num_in_col--;
                $opt_num++;
            }
           
            $table_cells .= <<<XHTML
<td class="col-$n">
<ul>
$col_list
</ul>
</td>
XHTML;
        }
       
        // build table
        $middle = <<<XHTML
<table class="{$this->table_class}">
<tr>
$table_cells
</tr>
</table>
XHTML;
       
        // reassemble complete element
        $output = <<<XHTML
$top
$middle
$bottom

XHTML;
       
        // return
        return $this->output($output);
    }
}

?>


usage

for usage in the view file
<?php
    print $klenwellForm->options_to_table(
        $form->input( 'Model.field2', array(
                        'type'=>'radio',
                        'legend'=>$legend,
                        'value'=>$RainbowList_value,
                        'before' => $klenwellForm->before_marker,
                        'after' => $klenwellForm->after_marker,
                        'separator' => $klenwellForm->separator_marker,
                        'options' => $RainbowList,
                        )
                    ),
        $num_cols=3
    );
?>


CategoryPastebin