Frames Modems Help Home Page Chipsets Search No Frames
Diary Entries See also Site Info & Diary.
18 December 2001 A PHP Class for building Forms controls...

(see also 11 Nov) (the latest version of the include file is here)

  On 11 November I listed a set of functions to be used as an include file & which allowed easy construction of most Forms controls. Using it afterwards I was struck by how close the listing was to a Class. My work at the time was constructing a PHP file that allowed the /mfc/ & names tables to be displayed, added to & edited. I quickly reached a point where it was necessary to have one or more variants of the same control, according to program flow. This was possible with the previous functions, but clunky. Converting them to a Class allows the properties to be set at one point in the program then the control displayed at a later point. Thus, more options are opened up, the program is smaller, more intuitive, and it works well.

The 11 Nov entry contains a scrap of PHP illustrating how to setup & use an array for the Select class. Below is a scrap of PHP showing creation of (in this instance) an array of CheckBox classes then, later in the program, their display. These checkboxes allow the display of certain names to be turned on or off. tData(), BTW, is a user-function to wrap text in <TD>..</TD> delimiters:

   $row=mysql_query("SELECT * FROM nameTypes ORDER BY name");
   while(list($i,$v)=mysql_fetch_row($row)) {
     $t="names.YID=$i";
     $n=mysql_result(mysql_query("SELECT COUNT(*) FROM names WHERE $t"),0);
     $cChk[$i]=new CheckBox("sYid[]", $i);
     $cChk[$i]->lab=$v." ($n)"; $cChk[$i]->rt=TRUE;
     if(!$HTTP_POST_VARS) $sYid[$i]=$i;
     if(isset($sYid))
      foreach($sYid as $val) if($val==$i) $cChk[$i]->chk=TRUE;
   }
   ...
   foreach($cChk as $val) $q.=$val->show()."<BR>\n";
   echo tData($q);
The Classes use one level of inheritance (all controls inherit from Control). This is quick, but there was a noticeable drop in performance with 2 lots of inheritance. Multiple inheritance (inheriting from 2 or more classes) is NOT supported.

I wanted to have a static Class member ($id - so that it could be incremented automatically) but could not find a way of doing it. It would have been good to have been able to embed all the Controls in Form, with a single show() that would have printed out the entire page, as this would have neatly paved the way to a kind of Visual Basic for PHP, but practicality got the better of me, and I've left it as it is.

 
  <?php
  /* an include file with PHP4 class definitions for use in Form creation

  if both a LABEL and an ID are included the control & LABEL will be
  wrapped in separate TABLE data-delimiters (<TD>..</TD>).
  otherwise these delimiters are NOT included

  the functions include Style Sheet CLASS default definitions
  these will need to be removed or replaced by your own.

  written by Alex Kemp, 30 Nov 2001
  (update 27 Dec 2001 - added isU to prevent multiple Underlines)
  http://www.modem-help.co.uk */

  class Form {
   var $met="GET"; // method, alternate="POST"
   var $name;
   var $url; // string, where control data is sent to

   function Form($nam, $url) {
     $this->name=$nam; $this->url=$url;
   }
   function show() {
     return "<FORM METHOD=$this->met ACTION='$this->url'
      NAME='$this->name'>\n";
   }
  }
  class Control {

   var $acc=NULL; // char, allows short-cut access to form
   var $cls="lnk";// string, style-sheet class
   var $chk=NULL; // anything (is CHECKED) or null
   var $col=NULL; // integer, (TEXTAREA)
   var $dis=NULL; // TRUE (is DISABLED) or NULL
   var $id=NULL; // anything, used only with $lab in controls
   var $inp="INPUT"; // string (or SELECT or TEXTAREA)
   var $is2=TRUE; // (use key+value) or NULL (use value) (SELECT)
   var $isU=TRUE; // (underline $lab) or NULL (do not)
   var $lab=NULL; // string, label identifier (see $id & $rt)
   var $max=NULL; // integer, max allowed input (TEXT & PASSWORD)
   var $mul=NULL; // TRUE (allow multiple selections) or null (SELECT)
   var $nam=NULL; // string, required ALL functions
   var $opt=NULL; // array of Options (SELECT) (see $is2, $mul & $sel)
   var $row=NULL; // integer, (TEXTAREA)
   var $rdo=NULL; // TRUE (is READONLY) or NULL
   var $rt=NULL; // TRUE (Label to right) or NULL (to left)
   var $sel=NULL; // string, to show on first (null-key) option (SELECT)
   var $siz=NULL; // integer
   var $tab=NULL; // integer, tab-order on Form
   var $tit=NULL; // string, TITLE impl as a tooltip on visual browsers
   var $txt=NULL; // string, default entry (TEXTAREA)
   var $typ=NULL; // string, type of INPUT
   var $val=NULL; // mixed (depends on context)

   function show() {
     $ret="<$this->inp";
     if($this->dis) $this->cls="dis";
     if($this->cls) $ret.=" CLASS='$this->cls'";
     if($this->typ) $ret.=" TYPE='$this->typ'";
     if($this->nam) $ret.=" NAME='$this->nam'";
     if($this->col>1) $ret.=" COLS='$this->col'";
     if($this->row>1) $ret.=" ROWS='$this->row'";
     if($this->siz) $ret.=" SIZE='$this->siz'";
     if($this->max) $ret.=" MAXLENGTH='$this->max'";
     if($this->acc && !$this->id) $ret.=" ACCESSKEY='$this->acc'";
     if($this->tab) $ret.=" TABINDEX='$this->tab'";
     if($this->id) $ret.=" ID='$this->id'";
     if($this->tit) $ret.=" TITLE='$this->tit'";
     if($this->val!==NULL && $this->inp!="SELECT")
      $ret.=" VALUE='$this->val'";
     if($this->chk) $ret.=" CHECKED";
     if($this->dis) $ret.=" DISABLED";
     if($this->mul) $ret.=" MULTIPLE";
     if($this->rdo) $ret.=" READONLY";
     $ret.=">";

     if($this->opt) {
      $this->txt="\n";
      if($this->sel)
        $this->txt.="<OPTION SELECTED VALUE=''>$this->sel</OPTION>\n";
      if($this->is2) {
        foreach($this->opt as $key=>$val) {
         $this->txt.="<OPTION";
         if($this->val==$key) $this->txt.=" SELECTED";
         $this->txt.=" VALUE='$key'>$val</OPTION>\n";
        }
      } else {
        foreach ($this->opt as $val) {
         $this->txt.="<OPTION";
         if($this->val==$val) $this->txt.=" SELECTED";
         $this->txt.=">$val</OPTION>\n";
        }
      }
     }

     if($this->inp!="INPUT") $ret.=$this->txt."</$this->inp>";
     if($this->lab) {
      if($this->acc && $this->isU) {
        $this->lab=
        str_replace($this->acc, "<U>$this->acc</U>", $this->lab);
        $this->isU=NULL;
      }
      $label=
        ($this->acc && $this->id)?"LABEL ACCESSKEY='$this->acc'":"LABEL";
      if($this->id) {
        if($this->rt) {
         $ret="<TD CLASS='rat'>$ret</TD>\n".
           "<TD CLASS='lat'>".
           "<$label FOR='$this->id'>$this->lab</LABEL></TD>\n";
        } else {
         $ret="<TD CLASS='rat'>".
           "<$label FOR='$this->id'>$this->lab</LABEL></TD>\n".
           "<TD CLASS='lat'>$ret</TD>\n";
        }
      } else {
        if($this->rt) {
         $ret="<$label>$ret\n$this->lab\n</LABEL>\n";
        } else {
         $ret="<$label>$this->lab\n$ret\n</LABEL>\n";
        }
      }
     }
   return $ret;
   }
  }
  class Checkbox extends Control {

   function Checkbox($nam, $val) {
     $this->nam=$nam; $this->val=$val;
     $this->cls="dis";
     $this->typ="CHECKBOX";
   }
  }
  class Hidden extends Control {

   function Hidden($nam, $val) {
     $this->nam=$nam; $this->val=$val;
     $this->cls=NULL;
     $this->typ="HIDDEN";
   }
  }
  class Password extends Control {

   function Password($nam) {
     $this->nam=$nam;
     $this->typ="PASSWORD";
   }
  }
  class Radio extends Control {

   function Radio($nam, $val) {
     $this->nam=$nam; $this->val=$val;
     $this->cls="dis";
     $this->typ="RADIO";
   }
  }
  class Reset extends Control {

   function Reset() {
     $this->cls="dis";
     $this->typ="RESET";
   }
  }
  class Search extends Control {

   var $rt=NULL; // (textbox to left) or TRUE (to right)
   var $s; // Submit button
   var $t; // Text box

   function Search($nam, $sNam) {
     $this->s=new Submit($sNam);
     $this->s->val="Search";
     $this->t=new Text($nam);
   }
   function show() {
     if($this->rt)
      return $this->s->show()." ".$this->t->show();
     else
      return $this->t->show()." ".$this->s->show();
   }
  }
  class Select extends Control {

   function Select($nam, $opt) {
     $this->nam=$nam; $this->opt=$opt;
     $this->inp="SELECT";
     $this->typ=NULL;
   }
  }
  class Submit extends Control {

   function Submit($nam) {
     $this->nam=$nam;
     $this->cls="dis";
     $this->typ="SUBMIT";
   }
  }
  class Text extends Control {

   function Text($nam) {
     $this->nam=$nam;
     $this->siz=40;
     $this->typ="TEXT";
   }
  }
  class TextArea extends Control {

   function TextArea($nam) {
     $this->nam=$nam;
     $this->col=40;
     $this->inp="TEXTAREA";
     $this->row=5;
     $this->typ=NULL;
   }
  }
?>