English
version 2.9.5

  PClib - PHP component library

•TOC

Ex.3: Using form.

Let's see the next PClib class - the form class. Here is example of template: 5.1 Form template file orderform.tpl
<?elements
class form name "orderform" action "index.php?modul=orderform&id={GET.id}"
input NAME
input ADDRESS size "50"
input BDATE   date "d/m/Y"
radio EXPRESS  list "Y,Yes,N,No" size "2"
select MOTOR  query "select ID, LABEL from MOTORS"
check  ACC query "select ID,LABEL from ACCESSORIES" size "2x5"
text COMMENT size "50x2"
check AGREE value "Y" default "Y"
button submit lb "Order"
button cancel lb "Cancel" attr "onclick=""history.back()"""
?>
You are purchasing  {productName}, price {buyPrice} USD.<BR><BR>

Your name: {NAME}<BR>
Your address: {ADDRESS}<BR>
Birth date: {BDATE} (Example: "10/1/1975")<BR>
Express service: {EXPRESS}<BR>
Motor: {MOTOR}<BR>
Accessories:<BR>
{ACC}<BR>
Do you have any message for us?<BR>
{COMMENT}<BR>
I agree with including my personal data to customer database {AGREE}<BR>
{submit} {cancel}
We have bunch of new tags here, which define elements of html form. Here is a short description of each used element type:
  • class form global parameters, here: FORM NAME and FORM ACTION attributes of <FORM> tag. By default form will be submitted using POST. For GET - put "get" attribute on this line.

  • input - Represents html INPUT element. It can have many attributes, here you can see setting of size of the input and setting date attribute, which contain informations for validator. Date in proper format will be transformed into correct database format, before form will be saved.
    For other attributes which can be used, look for paragraph "Shared attributes".

  • radio - define group of radio buttons. In our example two radios with label "Yes" and "No" will be generated. When submitted, it will send value "Y" or "N" respectively.

  • select - Represents html SELECT element. His content will be loaded according SQL query defined in query attribute. Note that you can use query for radio and check elements too.

  • check - define group of checkboxes. Its attributes are almost same like for radio or select element. Values of checkbox group are stored into db like bitfield. (Let's say that you check first, second and fourth checkbox. If so, number 1011b = 11 will be saved into database)
    It means that here is limit of maximum 64 checkboxes for 64-bit integer field. You can found useful MySQL SET datatype for checkbox field.
    It is also possible create one single checkbox tag: just omit list/query/lookup atributes. Example is field AGREE in our form. When submitted, it will send value "Y". By default it returns value "1".

  • text - Represents html TEXTAREA element. Attribute size can be used for any other form elements too. For one-row elements as INPUT or SELECT it is just number, here as "ROWSxCOLUMNS".

  • button represents html BUTTON element. After form has been sent, you can found name of pressed button in variable $_REQUEST['action']. Button "cancel" has attribute attr which can be used for any form element. It just put value of attr into html tag.
Note: For detail description of all tags and their attributes check the reference guide, page Template tags implemented by class form. 5.2 Managing basic form
require 'pclib/pclib.php';                           //Include pclib framework
$pclib->db = new PCDb('pdo_mysql://root@localhost/test');  //Open database

$form = new PCForm('tpl/orderform.tpl'); //create form

if ($form->submitted) {               //if form has been submitted...
  
$form->insert('ORDERS');            //insert form into table ORDERS..
  
header('Location:?action=done');    //do redirect here
}

$form->out();                         //else print form on the screen
 


You can store form to database by calling method $form->insert('TABLENAME') and $form->update('TABLENAME', 'WHERE_COND'). Form is stored into one row of table and column names must correspond with form field names. After form has been submitted, you can found filled values into $form->values array. Insert/update methods iterates this array, so you can add/modify values before saving.
To send form by mail call $form->mailto($to, $subject) method. You can validate form using method $form->validate(). See following more complex example for demonstration of this features.

Regarding CSS: Each generated element has CSS-CLASS set to his type and id set to his element's id. IE. checkbox AGREE in our example looks like <input type="checkbox" id="AGREE" class="check" value="Y" ...> You can take advantage of this for applying styles or javascripts on form elements.

Shared attributes In this paragraph we will discuss attributes which can be used for any form element.
  • default "value" - set value which will be filled (selected, checked) in form by default. For elements which can take more values (like checkbox array) separate values by comma.
    Ex: check DISCOUNTS lookup "discounts" default "1,2,5"

  • required Elements with this attribute must be filled (selected, checked). If not so, method form->validate() return false.

  • attr "text" "text" will be included into html tag.
    Ex: input PRICE attr "onchange='recalculate()'" will generate <input type="text" id="PRICE" onchange='recalculate()' ...>

  • lb "label" Label of the element. You can print label using template tag {element_id.lb}. See using labels in grid above. It can be useful when you need translate form labels. Also labels are included into mail message, if you send form by mail and shown in error messages generated by validator (described below). If field is required, his label is marked with text "(*)".

  • size "size" For input, it set his html size attribute. For checkbox and radio arrays and for textarea, you can specify here "ROWSxCOLUMNS".
  • noedit If set, element will be read-only.
  • nosave Method form->insert() and form->update() will ignore fields with this attribute.
  • noprint Elements with this attribute will not be shown on the screen.

Next attributes can be used for any lookup elements as resource of data. Lookup elements are: select, radio, check and bind (for bind see Ex.2: Template elements).
  • list "id1,label1,id2,label2,..." Generate select, radio or check items from specified list.
  • query "select id,label from table" Generate select, radio or check items from query.
  • lookup "lkpname" Load items from lookup table. Lookup table can contain values for every lookup field. It has columns LKPNAME, ID, LABEL, POSITION, GUID - see file install/pclib.sql. It is preffered method for filling lookup fields.
Note: Remember that you can set element's attributes from php code too. For example:
if (!$is_logged($user)) $orderform->elements['EMAIL']['required'] = 1;



Now more complex example. We create interface for adding, editing and deleting products in table CATALOG. For this purpose we create form with buttons insert, update and delete. Form will show error message on invalid input. Button "insert" will be shown only if we are adding product, buttons "update" and "delete" only if we are editing. First, the form template. 5.2 CRUD form template - file productform.tpl
<?elements
class form name "productform" action "index.php"
input productCode lb "Product code:" required size "10"
input productName lb "Product name:" required size "40"
input PICTURE lb "Picture of product:" file into "images/catalog/"
select productLine lb "Product line:" query "select distinct productLine from PRODUCTS" required
radio productScale lb "Scale:"  query "select distinct productScale from PRODUCTS" required size "3x5"
text productDescription lb "productDescription" size "50x10"
input quantityInStock
input buyPrice

button insert lb "Insert" noprint
button update lb "Update" noprint
button delete lb "Delete" attr "onclick=""if (!confirm('Really delete?')) return false;""" noprint
?>
<input type="hidden" name="id" value="{ID}">
<div class="errors">{errors}</div>
<div class="itm">{productCode.lb}</div> <div class="itm">{productCode}</div>
<div class="itm">{productName.lb}</div> <div class="itm">{productName}</div><br/>
<div class="itm">{PICTURE.lb}</div> <div class="itm">{PICTURE}
  Assigned picture: {PICTURE.filename}</div><br/>
<div class="itm">{productLine.lb}</div> <div class="itm">{productLine}</div><br/>
<div class="itm">{productScale.lb}</div><br/><div>{productScale}</div><br/>
<div class="itm">{productDescription.lb}</div><br/><div>{productDescription}</div><br/>
<div class="itm">{quantityInStock.lb}</div> <div class="itm">{quantityInStock}</div><br/>
<div class="itm">{buyPrice.lb}</div> <div class="itm">{buyPrice} USD</div><br/>

{insert} {update} {delete}

<br><br>Fields marked <font color="red">(*)</font> are required.
And code: 5.3 Managing CRUD form - file product.php
/* project: CRUD, file: index.php */

//Include pclib framework
require 'pclib/pclib.php';                           
//Open database
$pclib->db = new PCDb('pdo_mysql://root@localhost/test');  

//Get control variables
$action     $_GET['action'];
$id         = (int)$_GET['id'];

$pform = new PCForm ("tpl/productform.tpl");

//In edit mode, load data from database into form
if ($action == 'edit') {
  
$product $db->select('PRODUCTS''ID='.$id);
  if (!
$product) { print "Product $id does not exists!"; return 0; }
  
$pform->values $product;
  
$pform->enable('update','delete');
}
else
  
$pform->enable('insert');

//if form is submitted and validated, check which button pressed & do action
if ($pform->submitted and $pform->validate()) {
  switch (
$action) {

  
//button 'insert': save form values to db
  
case 'insert':
    
$pform->values['CREATED_AT'] = date("Y-m-d H:i:s"); //store timestamp
    
$id $pform->insert('PRODUCTS'); //insert into table PRODUCTS and return mysql_insert_id()
    //redirect to this script with action=finish
    
header('Location:?action=finish');
  break;

  
//button 'update': perform UPDATE PRODUCTS SET ...(form values)... WHERE ID='$id' query
  
case 'update':
    
$pform->update('PRODUCTS''ID='.$id);
    
header('Location:?action=finish');
  break;

  
//button 'delete': remove row from database
  
case 'delete':
   
//perform "delete from PRODUCTS where ID='$id'"
    
$pform->delete('PRODUCTS''ID='.$id);
    
header('Location:?action=finish');
  break;

  }
}

//At last, when form has been processed, show message and quit the script
if ($action == 'finish') {
  print 
"Row $id of products has been modified.";
  return 
1;
}

$pform->out();
 
If you go to this page without parameters, it will open empty form for inserting. It will skip whole action code and go to the last line. In template we made "update" and "delete" buttons invisible, so only "insert" button will be shown.
When submitted, it call this script again (consider attribute "form action" in form template) with variable $action="insert".
In case that form is validated, it goes to "case 'insert'" and store form into db. All form field values are in $pform->values array and you can modify them. Here we add timestamp of creation.
If form data aren't valid (User doesn't fill required PRODUCTNAME, for example), action code is skipped and form is shown again. It contains all values filled by user before - and moreover - tag {errors} at the top of template is filled with error messages. This tag is set in method $pform->validate(). User can fix problem and submit form again.

Now edit form works very similar. We call page index.php?action=edit&id=10, where 10 is ID of edited record in database. Data from database are loaded into the form, middle action block is skipped and form is shown on last line. We will show buttons "update" and "delete" before showing form.
When submitted, it process 'update' or 'delete' action code.

Finally, after processing of form data, it is redirected to action "finish" and print message. That's all.

Note: If you need more complex storing mechanism and methods form->insert() and form->update() are not good enough, you can write it by your own - just iterate through form->values array, where all submitted data reside.

Of course it is easy write some controller class or function, which will do all this code for you and automate whole process. Let's say: $fc = new form_controller($theform,FORM_TABLE);
$resultaction $fc->process($action);
$fc->redirect($resultaction);
 


«PREV Using grid