#native_company# #native_desc#
#native_cta#

PEAR’s HTML_QuickForm Page 2

By Ian Gilfillan
on October 25, 2006

Let’s look at some more examples and features. One extremely useful feature is that you can also validate on the client-side as well, using the ‘client’ flag. It’s good practice to validate on the client-side, as this makes the user’s life that much easier (they don’t need to wait for a response from the server), but you should always validate on the server-side as well, as not all clients have JavaScript enabled. We also look at the comparison rule (in this example two fields cannot be the same), and a custom rule, which allows you to write a function to use any criteria you wish.
<?
  require_once "HTML/QuickForm.php";

  $form = new HTML_QuickForm('register', 'post');
  $form->addElement('text', 'firstName', 'Enter first name');
  $form->addElement('password','password', 'Enter your password');
  $form->addElement('text','customer_email','Enter an email');
  $form->addElement('textarea','ta','Description');
  $form->addElement('submit','sb','Submit form');

  $form->addRule('firstName', 'Your name is required', 'required');
  $form->addRule('firstName', 'Your name can only contain letters','lettersonly');
  $form->addRule('firstName', 'You must enter a first name', 'required', null, 'client');
  $form->addRule('firstName', 'Your name cannot be less than two characters!','minlength',2,'client');
  $form->addRule('customer_email', 'Please enter a valid email','email',true,'client');
  $form->AddRule(array('password','firstName'),'Your password and first name cannot be the same!','compare','!=');
  
  $form->registerRule('no_symbol','function','no_symbol_f');
  $form->addRule('firstName','Sorry, your name cannot be Symbol','no_symbol');

  if ($form->validate()) {
    // processing code goes here.
    echo 'Success!';
  }
  else {
    $form->display();
  }
  
  function no_symbol_f($element_name,$element_value) {
    if ($element_value == 'Symbol') {
      return false;
    }
    else {
      return true;
    }
  }

?>
And here’s what’s generated:
 <script type="text/javascript">
//<![CDATA[
function validate_register(frm) {
  var value = '';
  var errFlag = new Array();
  var _qfGroups = {};
  _qfMsg = '';

  value = frm.elements['firstName'].value;
  if (value == '' && !errFlag['firstName']) {
    errFlag['firstName'] = true;
    _qfMsg = _qfMsg + 'n - You must enter a first name';
  }

  value = frm.elements['firstName'].value;
  if (value != '' && value.length < 2 && !errFlag['firstName']) {
    errFlag['firstName'] = true;
    _qfMsg = _qfMsg + 'n - Your name cannot be less than two characters!';
  }

  value = frm.elements['customer_email'].value;
  var regex = /^(("[^"fnrtvb]+")|([w!#$%&'*+-~/^`|{}]+(.[w!#$%&'*+-~/^`|{}]+)*))@(([(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])).((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])).((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])).((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))])|(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])).((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])).((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])).((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9-])+.)+[A-Za-z-]+))$/;
  if (value != '' && !regex.test(value) && !errFlag['customer_email']) {
    errFlag['customer_email'] = true;
    _qfMsg = _qfMsg + 'n - Please enter a valid email';
  }

  if (_qfMsg != '') {
    _qfMsg = 'Invalid information entered.' + _qfMsg;
    _qfMsg = _qfMsg + 'nPlease correct these fields.';
    alert(_qfMsg);
    return false;
  }
  return true;
}
//]]>
</script>

<form action="/phpbuilder/html_quickform33.php" method="post" name="register" id="register" onsubmit="try { var myValidator = validate_register; } catch(e) { return true; } return myValidator(this);">
<div>
<table border="0">

	<tr>
		<td align="right" valign="top"><span style="color: #ff0000">*</span><b>Enter first name</b></td>
		<td valign="top" align="left">	<input name="firstName" type="text" /></td>

	</tr>
	<tr>
		<td align="right" valign="top"><b>Enter your password</b></td>
		<td valign="top" align="left">	<input name="password" type="password" /></td>
	</tr>
	<tr>
		<td align="right" valign="top"><b>Enter an email</b></td>

		<td valign="top" align="left">	<input name="customer_email" type="text" /></td>
	</tr>
	<tr>
		<td align="right" valign="top"><b>Description</b></td>
		<td valign="top" align="left">	<textarea name="ta"></textarea></td>
	</tr>
	<tr>

		<td align="right" valign="top"><b></b></td>
		<td valign="top" align="left">	<input name="sb" value="Submit form" type="submit" /></td>
	</tr>
	<tr>
		<td></td>
	<td align="left" valign="top"><span style="font-size:80%; color:#ff0000;">*</span><span style="font-size:80%;"> denotes required field</span></td>
	</tr>

</table>
</div>
</form>
The compare rule allows other operators besides the not equal to (!=) used in this example, such as < or >. If you leave out the operator altogether, it’s assumed to be =, meaning that the two elements must be the same (typically used to check whether a user has entered their password or email address correctly).

Processing the form data

Up till now, we’ve simply displayed Success! if the form has been validated. That’s not particularly useful. Of course, we could put as much code as we want there, but that’s not particularly elegant. HTML_QuickForm provides a process() method, which calls a function and passes the submitted values. Here’s the method in action:
<?
  require_once "HTML/QuickForm.php";

  $defaults_= array("firstName"=>"Ian",
                 "password"=>"abc",
                 "ta"=>"Describe yourself here");

  $form = new HTML_QuickForm('register', 'post');
  $form->addElement('text', 'firstName', 'Enter first name');
  $form->addElement('password','password', 'Enter your password');
  $form->addElement('textarea','ta','Description');
  $form->addElement('submit','sb','Submit form');

  $form->addRule('firstName','Your name is required', 'required');

  if ($form->validate()) {
    // processing code goes here.
    $form->process('process_data', false);
  }
  else {
    $form->setDefaults($defaults);
    $form->display();
  }

  // For now just display the submitted vales, but you'll want to do a lot more
  function process_data ($values) {
    foreach ($values as $key=>$value) {
      echo $key."=".$value."<br>";
    }
  }
?>

Formatting the form

Early versions of HTML_QuickForm were not that flexible when it came to changing the layout. However, since version 3.0, behaviour became based on the the well-known Visitor design pattern. There are eight renderers available, and the following template engines are supported directly: Smarty, HTML_Template_Sigma, HTML_Template_IT, HTML_Template_Flexy. Looking at these various renderers and template engines in detail is beyond the scope of this article, but the following example shows briefly that it is possible to substantially customise your form output. My example is fantastically ugly just so you don’t miss the effects! Rest assured that if you know a particular template engine, you’ll find it quite easy to make use of.
<?
  require_once "HTML/QuickForm.php";

  $defaults_= array("firstName"=>"Ian",
                 "password"=>"abc",
                 "ta"=>"Describe yourself here");

  $form = new HTML_QuickForm('register', 'post');
  $form->addElement('text', 'firstName', 'Enter first name');
  $form->addElement('password','password', 'Enter your password');
  $form->addElement('textarea','ta','Description');
  $form->addElement('submit','sb','Submit form');

  $form->addRule('firstName','Your name is required', 'required');

  $renderer =& $form->defaultRenderer();

  $special_element_template='
<tr>
  <td align="right" valign="top">
    <!-- BEGIN required --><span style="color: magenta">*</span><!-- END required -->
    <font size="+22">{label}</font>
  </td>
    <td valign="top" align="left">
    <!-- BEGIN error --><span style="color: magenta">{error}</span><br /><!-- END error -->
  {element}</td>
</tr>';

  $renderer->setElementTemplate($special_element_template);

  if ($form->validate()) {
    // processing code goes here.
    echo 'Success!';
  }
  else {
    $form->setDefaults($defaults);
    $form->display();
?>

Conclusion

I’m sure you’ve found it quite easy to use, but there’s a lot more to this package. The official HTML_QuickForm page on the PEAR website has an API and, unusual for most PEAR packages, end-user documentation as well. And don’t forget to look out for the PHP5 version of the package, HTML_QuickForm2, when it’s released. Good luck!