Revision [8909]

This is an old revision of ArrayToColumns made by JavaWoman on 2005-06-07 11:24:11.

 

Generating Columns from an Array


See also:
This page presents new code for the WikkaCore Wikka Core to generate columns of items from an array of items to be presented - without using a table for layout.

Why?


In many cases we get an array back from some procedure and want to display the result in the form of a number of easy to read columns. The current Wikka code now does this "manually" and generates a table layout which is not only very structural code but also not very accessible. (Example: the CategoryActionInfo Category action can generate its output in "columns" but they need to be read horizontally rather than vertically - making it hard to "scan" so a particular name is hard to find - and the code generated is a layout table.)

Using a standard way to generate columns is more efficient, can ensure consistent and structural code and makes it easier to write methods that need columns of items as output.

How?


Two separate methods were written to make it easy to generate well-structured columns with 'hooks' for styling: the first does nothing but generate a list from an array (with an id); the second wraps that in a bit of code with a heading and a bit of text instead of the list if the array happens to be empty.

The Code


makeCols()

This method does the hard work of creating columnar output from an array, using floated divs instead of a layout table. It requires the makeId() method to be already present - see GenerateUniqueId.

Add the following code in the //MISC section right after the makeMemberList() method (see ArrayToList for that):

makeCols()
  1.     /**
  2.      * Build vertically-arranged columns from an array.
  3.      *
  4.      * Given an array and number of columns, this method builds vertically-
  5.      * arranged columns (meaning they are read vertically, one by one)
  6.      * implemented as floated divs. Column width is derived from the
  7.      * specified number of columns, implemented as an embedded style because
  8.      * it's dynamically generated; left float is added to the style (hardcoded
  9.      * for now but alignment could become an option later).
  10.      *
  11.      * @author      {@link http://wikka.jsnx.com/JavaWoman JavaWoman}
  12.      * @copyright   Copyright © 2005, Marjolein Katsma
  13.      * @license     http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
  14.      * @version     0.3
  15.      *
  16.      * @todo    - make alignment configurable
  17.      *          - class as extra parameter (for each column)
  18.      *          - replace clear: both style at end with a class
  19.      *          - support for internationalization (replace hard-coded strings)
  20.      *
  21.      * @access  public
  22.      *
  23.      * @param   array   $array  required: flat array with content items; must be array but may be empty
  24.      * @param   integer $cols   optional: number of columns to generate; default: 1
  25.      *                          (will be cast to positive integer)
  26.      * @return  string  generated divs (or empty string if array was empty)
  27.      */
  28.     function makeCols($array,$cols=1)
  29.     {
  30.         // validate/treat input
  31.         if (!is_array($array))
  32.         {
  33.             return '<p class="error">Could not generate columns: array required</p>'."\n";      # @@@ i18n
  34.         }
  35.         $cols = abs((int)$cols);                                                # cast to positive integer
  36.         // build columns
  37.         $count = count($array);
  38.         $width = (int) (100 / $cols);
  39.         $lines = ($count % $cols == 0) ? (int)($count / $cols) : (int)(($count + $cols) / $cols);
  40.         $line = 0;
  41.         $out = '';
  42.         // data columns
  43.         foreach ($array as $val)
  44.         {
  45.             if (($line++ % $lines) == 0) $out .= "\n".' <div style="width: '.$width.'%; float: left;">'."\n";
  46.             $out .= '       '.$val.'<br />'."\n";
  47.             if (($line % $lines) == 0) $out .= "    </div>";
  48.         }
  49.         if ($count > 0)
  50.         {
  51.             if (($line % $lines) != 0) $out .= "    </div>";
  52.             $out .= '<br style="clear: both;">'."\n";
  53.         }
  54.         // return result
  55.         return $out;
  56.     }


makeMemberCols()

This method is a wrapper around the makeCols() method: it wraps the output in a div and adds a heading or outputs a paragraph of text in case the array turns out to be empty. It's meant for cases where items are to be presented as "members" of a collection; the heading is used to indicate the number of members.

As with the ArrayToList makeMemberList() method there is deliberately no 'outer' div with an id: this is so a wrapper div may be created with a single heading containing several occurrences of the output of this method. Such a wrapper should be generated in the calling code.

Add the following code in the //MISC section right after the makeCols() method:

makeMemberCols()
  1.     /**
  2.      * Display members of a collection in vertical columns; a heading precedes
  3.      * the columns; alternatively output is just a paragraph of text in case the
  4.      * array provided turns out to be empty.
  5.      *
  6.      * There is deliberately no 'outer' div with an id: this is so a div may be
  7.      * created with a single heading containing several occurrences of the
  8.      * output of this method. Such a wrapper should be generated in the calling code.
  9.      *
  10.      * @author      {@link http://wikka.jsnx.com/JavaWoman JavaWoman}
  11.      * @copyright   Copyright © 2005, Marjolein Katsma
  12.      * @license     http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
  13.      * @version     0.5
  14.      *
  15.      * @access  public
  16.      * @uses    makeId()
  17.      * @uses    makeCols()
  18.      *
  19.      * @param   array   $array      required: flat array with collection items
  20.      * @param   string  $hd         required: heading for the whole
  21.      * @param   string  $hdid       required: id for the heading
  22.      * @param   string  $txtnone    required: text to display when the array is empty
  23.      * @return  string  div containing heading and list, or paragraph
  24.      */
  25.     function makeMemberCols($array,$cols,$hd,$hdid,$txtnone)
  26.     {
  27.         $count = count($array);
  28.         $out = '';
  29.         if ($count > 0)
  30.         {
  31.             $out .= '   <h6 id="'.$this->makeId('hn',$hdid).'">'.$hd.'</h6>'."\n";
  32.             $out .= $this->makeCols($array,$cols);
  33.         }
  34.         else
  35.         {
  36.             $out  = '   <p>'.$txtnone.'</p>'."\n";
  37.         }
  38.         return $out;
  39.     }



When and where to use



Status


As can be seen from the @version numbers and @todo items in the docblocks, the code is far from "finished". An additional idea that just came up on TheLounge #wikka is to be able to specify the level of the heading generated by makeMemberCols() (given that a page should already contain a h1 and h2 heading, only 3-6 should be allowed). However, the methods are quite functional to use as is.


CategoryDevelopmentCore
There is one comment on this page. [Display comment]
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki