Adventure,PHP,framework,page controller,front controller,pattern,object orientated design,software,development,reusability,uml,tutorial,benchmark,brilliant performance,

Search:    
Downloads  |  SVN!  |  Roadmap  |  Forum!  |  Bugtracking  |  Guestbook  |  Backlinks!  |  References!  |  Sitemap  |  Impress  
 
Deutsch | English Adventure PHP Framework  Bookmark @ Technorati Bookmark @ del.icio.us Bookmark @ Mr. Wong Bookmark @ Simpy Bookmark @ Google Bookmark @ Digg.com Adventure PHP Framework Print page 011-Forms

Forms

Rank article:
This article has not yet been ranked. Vote this article first of all!
The adventure php framework supports the dynamic generation and abstraction of forms out-of-the-box. Owing to the generic tag parser forms can be mapped by XML tags in template files and thus are embedded in the DOM tree of the presentation layer. Thereby it is possible to give "internal intelligence" to form elements. This implies automatic filling with the help of an URL parameter and the validation of user inputs. The behaviour of these features can be influenced by configuring the form elements via tag attributes. It is not necessary to implement functionality of these elements for the current application.


1. Construction of forms

APF forms are simily to the HTML templates discussed under templates. Each form can be seen as a child object of the current DOM node. To get a reference on this object each document controller feature the __getForm() method. The form class has the following API:
  • addFormElement()
    Adds a form element at the end of the current form. This method can be used for dynamic form creation.
  • addFormContent()
    Adds content (HTML or text) to the end of the currend form. This method can be used for dynamic form creation.
  • addFormContentBeforeMarker()
    Adds content (HTML or text) before a marker tag to the current form. This method can be used for dynamic form creation.
  • addFormContentAfterMarker()
    Adds content (HTML or text) after a marker tag to the current form. This method can be used for dynamic form creation.
  • addFormElementBeforeMarker()
    Adds a form element before a marker tag to the current form. This method can be used for dynamic form creation.
  • addFormElementAfterMarker()
    Adds a form element after a marker tag to the current form. This method can be used for dynamic form creation.
  • setPlaceHolder()
    Fills a place holder defined within the form. Please refer to standard taglibs for more details.
  • setAction()
    Sets the "action" attribute do define the target to POST or GET against.
  • getFormElementByName()
    Returns a reference an any form object defined by a name.
  • getFormElementByID()
    Returns a reference an any form object defined by an id.
  • getFormElementByObjectID()
    Returns a reference an any form object defined by an internal object id.
  • transformForm()
    Creates the HTML output of a form and returns it.
  • transformOnPlace()
    Indicates, that the form will be displayed where it was defined within the template file. Though it is not necessary to transform the form object with transformForm() and assign the content to a place holder.
To use the tag it must be announced using the
  <core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
directive before using it. After that a login form may be defined like this:
  <html:form name="AdminLogin" method="post" action="">
    <form:placeholder name="LogInError" />
    Username: <form:text name="Username" class="input_feld" style="width: 200px; margin-left: 20px;"
    validate="true" button="AdminLogin" />
    <br />
    Password: <form:password name="Password" class="input_feld" style="width: 200px; margin-left: 16px;"
    validate="true" button="AdminLogin" />
    <br />
    <br />
    <form:button name="AdminLogin" value="Login" class="input_feld" style="margin-left: 227px;"/>
  </html:form>
In detail: the <html:form /> XML tag possesses the attribute name to be able to get reference on the form and the attribute method to define the send mode. action defines the target to send the form to. This attribute most not be defined due to the fact, that the taglib behind the form tag adds the action automatically if the attribute is not present in the template file.

Within forms many form elements can bedefined: place holders to display hints or legends, text or password fields or buttons. Please refer to standard taglibs to find a detailed description of the available tag libs. To use the previously defined form the following code can be used:
  $Form__AdminLogin = &$this->__getForm('AdminLogin'); 
The variable $Form__AdminLogin now contains a reference on the form object. Further the place holder's content of the previously defined form can be filled by
  $Form__Placeholder_LogInError = &$Form__AdminLogin->getFormElementByName('LogInError');
  
$Form__Placeholder_LogInError->setPlaceHolder('Login failed!'); 
The form object internally stores the current status of the form. To gather the information whether a form was sent or filled correctly concerning the defined validation methods the subsequent lines of code help to achieve this:
  if($Form__AdminLogin->get('isValid') && $Form__AdminLogin->get('isSent')){

     
// Do something that should be done if the form is sent and valid ...

   // end if
  
In order to display a form you have two possibilities: assigning the content to any place holder defined within the template file of make use of the transformOnPlace() function:
   function transformContent(){

      ...

      
// Transform and output form by assigning the content to any placeholder ...
      
$this->setPlaceHolder('...',$Form__AdminLogin->tranformForm());

      
// ... display the form in place
      
$Form__AdminLogin->tranformOnPlace();

      ...

    
// end function
   

2. Validation

As mentioned above validation of form elements can be configured out-of-the-box. For this purpose the attributes
  • validate
  • validator
  • button
must be added to a form element. For details please refer to the XML tag definition under standard taglibs, Kapitel 2.3. In order to validate the fields of the above defined form the text field must be adjusted as performed afterwards:
  <form:text name="Username" validate="true" button="AdminLogin" />
Please note that for correct validation the name of the button must be present. If the attribute button is not set the taglib implementation raises an error. In order to format a form element with CSS attributes, the attributes "style" or "class" can be used as desired.
  <form:text name="Username" class="eingabe_feld" style="width: 200px; margin-left: 20px;"
  validate="true" button="AdminLogin" />
If the attribute "validator" is not set the standard validator (validateText) is used instead.


3. Manipulation of form elements

Die Implementierung der Formular-TagLibs des Frameworks bringt einige Möglichkeiten zur Manipulation von Formularelementen oder deren Werte mit. Die folgenden Kapitel zeigen häufig auftretende Anwendungsbeispiele.


3.1. Prefilling of forms

In order to prefill forms (e.g. in edit dialoges) the methods getFormElementByID(), getFormElementByID() or getFormElementByObjectID() can be used to get a reference on the desired form element. Subsequently, the standard methods get() and getAttribute() and set() and setAttribute() respectivly are avaliable for data manipulation of an form element.

The following box defines an example form, that will be filled by the PHP code printed below:
  <core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
  <html:form name="UserEdit" method="post">
    <strong>FirstName</strong>:
    <form:text name="FirstName" validate="true" button="Edit" />
    <br />
    <strong>LastName</strong>:
    <form:text name="LastName" validate="true" button="Edit" />
    <br />
    <br />
    <form:button name="Edit" value="Save" />
    <form:hidden name="userid" />
  </html:form>
   // get the form object
   
$Form__Edit = &$this->__getForm('UserEdit');

   
// get the hidden field object and fill the value
   
$UserID = &$Form__Edit->getFormElementByName('userid');
   
$UserID->setAttribute('value','...');

   
// get the FirstName field and fill the value
   
$FirstName = &$Form__Edit->getFormElementByName('FirstName');
   
$FirstName->setAttribute('value','...');

   
// get the LastName field and fill the value
   
$LastName = &$Form__Edit->getFormElementByName('LastName');
   
$LastName->setAttribute('value','...'); 

3.2. Prefilling of select fields

Dealing with select or multiselect fields is a little bit different to "normal" form elements. But the framework provides common methods to fill these types of fields as well. The following form contains two select fields in addition to the four "normal" form elements:
  <core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
  <html:form name="UserCreate" method="post">
    <strong>Salutation</strong>:
    <form:select name="Salutation" />
    <br />
    <strong>FirstName</strong>:
    <form:text name="FirstName" validate="true" button="Edit" />
    <br />
    <strong>LastName</strong>:
    <form:text name="LastName" validate="true" button="Edit" />
    <br />
    <br />
    <strong>Salutation</strong>:
    <br />
    <form:multiselect name="Group[]" validate="true" button="Edit" />
    <br />
    <br />
    <form:button name="Edit" value="Save" />
    <form:hidden name="userid" />
  </html:form>
As the tag definition of the Groups[] fiels shows, the name of a multiselect field must contain brackets. If the template developer forgets to put them in, a error message will be displayed.

In order to fill the select fields, the following PHP code can be used: Der folgende PHP-Code befüllt das Formular:
   // get the form object
   
$Form__Create = &$this->__getForm('UserCreate');

   ...

   
// get the Salutation field and add some options
   
$Salutation = &$Form__Create->getFormElementByName('Salutation');

   for(
$i 0$i count($Salutations); $i++){
      
$Salutation->addOption($Salutations[$i]['Value'],$Salutations[$i]['DisplayName']);
    
// end for
   
}


   
// get the Groups[] field and add some options
   
$Group = &$Form__Create->getFormElementByName('Groups[]');

   for(
$i 0$i count($Groups); $i++){
      
$Group->addOption($Groups[$i]['Value'],$Groups[$i]['DisplayName']);
    
// end for
   
}

   ... 

3.3. Readout form element values

Readout of form elements is similar to the filling of form elements. In both situations, the getFormElementByName() method can be used to obtain a reference on any form element. Please note, that select and multiselect fields are here also treated a little bit different. The next few lines describe, how to gather values of form elements:
   // get the form object
   
$Form__Edit = &$this->__getForm('UserEdit');

   
// get the value of the hidden field
   
$UserID = &$Form__Edit->getFormElementByName('userid');
   echo 
$UserID->getAttribute('value');

   
// read the content of the FirstName field
   
$FirstName = &$Form__Edit->getFormElementByName('FirstName');
   echo 
$FirstName->getAttribute('value');

   
// read the content of the LastName field
   
$LastName = &$Form__Edit->getFormElementByName('LastName');
   echo 
$LastName->getAttribute('value'); 
To read the content of select or multiselect fields the getSelectedOption() and getSelectedOptions() function can be used:
   // get the form object
   
$Form__Create = &$this->__getForm('UserCreate');

   
// prefill the Salutation field
   
$Salutation = &$Form__Create->getFormElementByName('Salutation');
   for(
$i 0$i count($Salutations); $i++){
      
$Salutation->addOption($Salutations[$i]['Value'],$Salutations[$i]['DisplayName']);
    
// end for
   
}

   
// get the selected option of the Salutation field and print it to screen
   
$Option = &$Salutation->getSelectedOption();
   echo 
$Option->getAttribute('value').', '.$Option->get('Content');


   
// prefill the Group field
   
$Group = &$Form__Create->getFormElementByName('Groups[]');

   for(
$i 0$i count($Groups); $i++){
      
$Group->addOption($Groups[$i]['Value'],$Groups[$i]['DisplayName']);
    
// end for
   
}

   
// get the selected options of the Groups[] field and print them to screen
   
$SelectedGroups = &$Group->getSelectedOptions();
   for(
$i 0$i count($SelectedGroups); $i++){
      echo 
$SelectedGroups[$i]->getAttribute('value').', '.$SelectedGroups[$i]->get('Content');
    
// end for
   


4. Dynamic Forms

In some cases it is necessary to generate forms dynamically. For this reason, the form taglib (html_taglib_form) features the methods
  • addFormElement()
  • addFormContent()
and as of release 1.7
  • addFormContentBeforeMarker()
  • addFormContentAfterMarker()
  • addFormElementBeforeMarker()
  • addFormElementAfterMarker()
The first two functions can be used to add content (i.e. plain text or html) or form elements at the end of the form. The latter ones are intended to add content or form at certain positions. For this reason, the <form:marker /> tag was introduced. The tag itself does not generate any output, but can be used for positioning purposes along with the "addForm*[Before|After]Marker()" methods.

The following chapters describe, how a dynamic form can be generated displaying form coordinate fields (triangle, square, ...). Depending on the type, the corresponding fields are displayed. If the type is set to "square", four fields are displayed ...

APF - dynamische Form generation; selection of the 'square' type

... in case of "triangle" three fields are presented:

APF - dynamische Form generation; selection of the 'triangle' type


4.1. Form definition

As already mentioned, the dynamic definition can be done in two flavours. While using addFormElement() and/or addFormContent(), no marker is needed. Instead, the following example uses marker, because the form already contains structural elements (e.g. table).

The following code box shows the form definition needed to display the form denoted above. To keep things simple, no CSS was added. Taking a closer look at the definition, you can see, that the form consists of a static select field, that defines the types available and a marker tag for positioning. Further, a document controller is specified, to add the desired form elements in front of the marker:
<@controller namespace="..." file="..." class="select_controller" @>
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
<html:form name="type" method="post">
  <table>
    <tr>
      <td>
        Please choose the desired form type:
        <form:select name="type">
          <select:option value="triangle">triangle</select:option>
          <select:option value="square">square</select:option>
        </form:select>
      </td>
      <td>
        <form:button name="submit" value="send" />
      </td>
    </tr>
    <tr>
      <td>
        <form:marker name="fields" />
      </td>
    </tr>
  </table>
</html:form>

4.2. Controller

The document controller is responsible for generating the form field, that depends on the type of the geometrical shape. For this reason, the constructor contains a definition of the form fields that should be displayed for a concrete type. Afterwards, the typ is read from the select field and the form is enhanced with additional content and fields. The following code box presents the implementation of the document controller needed for this functionality:
class select_controller extends baseController
{

   
// specify form element container
   
var $__FormElements = array();


   function 
select_controller(){

      
// define form elements for the triangle
      
$this->__FormElements['triangle'][] = array('label' => 'coord 1','name' => 'coordone');
      
$this->__FormElements['triangle'][] = array('label' => 'coord 2','name' => 'coordtwo');
      
$this->__FormElements['triangle'][] = array('label' => 'coord 3','name' => 'coordthree');

      
// define form elements for the square
      
$this->__FormElements['square'][] = array('label' => 'coord 1','name' => 'coordone');
      
$this->__FormElements['square'][] = array('label' => 'coord 2','name' => 'coordtwo');
      
$this->__FormElements['square'][] = array('label' => 'coord 3','name' => 'coordthree');
      
$this->__FormElements['square'][] = array('label' => 'coord 4','name' => 'coordfour');

    
// end function
   
}


   function 
transformContent(){

      
// get form reference
      
$Form = &$this->__getForm('type');

      
// get current decision
      
$Select = &$Form->getFormElementByName('type');
      
$Option = &$Select->getSelectedOption();
      if(
$Option === null){
         
$CurrentType 'triangle';
       
// end if
      
}
      else{
         
$CurrentType $Option->getAttribute('value');
       
// end else
      
}

      
// add form elements
      
for($i 0$i count($this->__FormElements[$CurrentType]); $i++){

         
// add label
         
$Form->addFormContentBeforeMarker('fields',$this->__FormElements[$CurrentType][$i]['label'].': ');

         
// add text field (name attribute is present to enable validation and presetting!)
         
$CurrentElementID $Form->addFormElementBeforeMarker(
                                          
'fields',
                                          
'form:text',
                                          array(
'name' => $this->__FormElements[$CurrentType][$i]['name'])
                                                              );

         
// configure further form element attributes
         
$CurrentElement = &$Form->getFormElementByObjectID($CurrentElementID);
         
$CurrentElement->setAttribute('style','width: 200px;');

         
// add a line break
         
$Form->addFormContentBeforeMarker('fields','<br />');

       
// end for
      
}

      
// display form
      
$Form->transformOnPlace();

    
// end function
   
}

 
// end class

4.3. Notes

A APF form element does need information about the name of itself already at creation time. If the element doesn't know it's own name, presetting and validation cannot be enabled. In order to use presetting and validation in combination with dynamic form elements, the addFormElement(), addFormElementBeforeMarker() and addFormElementBeforeMarker() functions possess a third parameter. This parameter expects an associative list of tag attributes, that are applied to the form object on creation time. Creating dynamic form elements, it is thus recommended to at least apply the name of the tag to the third argument:
array(
      'name' => 'currentname'
     )
Please note, that the tag attributes are also interesting for addressing the form objects after appending them to the form via the getFormElementByName() or getFormElementByID() methods.


Comments

Do you want to add a comment to the article above, or do you want to post additional hints? So please click here. Comments already posted can be found below.


There are no comments belonging to this article.


Powered by WebRing.