Adding Custom Renderers To HTML_QuickerForm.

November 29, 2007

In a previous post, I talked about how to get the most out of the HTML_QuickForm PEAR library. I then wrote an improved version for ONLamp. A reader there asked how to implement a custom form renderer using my HTML_QuickerForm class.

As it turns out, after I wrote this article, I encountered the same need, and realized that my HTML_QuickerForm as it was written made specifying custom renders difficult. (I hadn’t originally needed a custom renderer.) Google has always helped me quickly understand things like this, and sure enough, I found a very clear and complete explanation of custom renderers in the blog post Making HTML_QuickForm CSS and XHTML 1.0 Strict friendly by Troy Mcilvena. I adapted his approach to HTML_QuickerForm and ended up with the following update to HTML_QuickerForm.php:

<?php

// includes ideas from:
// http://www.troymcilvena.com/html_quickform-css-xhtml/

require_once('HTML/QuickForm.php');
require_once('HTML/QuickForm/Renderer/Default.php');

class HTML_QuickForm_Renderer_Default_CSSRender extends HTML_QuickForm_Renderer_Default {
	var $_headerTemplate =
"<tr>
	<td colspan="2" scope="row"><h3 class="_header">{header}</h3></td>
</tr>";

	var $_elementTemplate =
"<tr>
	<th class="label"><!-- BEGIN required --><span class="_required">*</span><!-- END required -->{label}</th>
	<td><!-- BEGIN error --><span class="_error">{error}</span><br /><!-- END error -->
		{element}
	</td>
</tr>";

	var $_formTemplate =
"<form{attributes}>
	{hidden}
	<table border="0" cellspacing="2" cellpadding="3">
		{content}
	</table>
</form>
";

	var $_requiredNoteTemplate =
"<tr>
	<td> </td>
	<td>{requiredNote}</td>
</tr>";

}

  class HTML_QuickerForm extends HTML_QuickForm {
    var $renderer;

    ...

    function display() {
       $this->renderer = new HTML_QuickForm_Renderer_Default_CSSRender();
       $this->accept($this->renderer);
       echo $this->renderer->toHtml();
    }

    ...

  }

?>

In case you didn’t figure it out, the ellipses (”…”) represents code that is unchanged from the previous version of this file.

Essentially, I imported the HTML_QuickForm_Renderer_Default class and subclassed it with my custom renderer code. Then in my HTML_QuickerForm class, I overrode the display() method of HTML_QuickForm to use that renderer class.

Obviously, this code needs more refactoring, so that the renderer can be specified more dynamically/declaratively, but its a working start.

11 Comments »

Comment by Nasser
2007-11-30 10:08:26

Thanks Adam very much.
I modified the script per the new one but I am getting this:
PHP Parse error: syntax error, unexpected T_LNUMBER, expecting ‘,’ or ‘;’ in ../HTML_QuickerForm.php on line 9
If I change the double qoutes for the “…”; into single qoute, I dont get the error but instead I get error messages “{error}” for each lable.

Comment by admin
2007-11-30 10:11:46

Nasser,

I’m not sure I understand what you’re describing, can you show me your code?

 
 
Comment by Nasser
2007-11-30 10:32:06

My apology Adam,
Unless I replace the double qoutes enclosing the
var $_headerTemplate = and others into a single qoute, I get the parsing error I sent you earlier.

Here is the code:
‘Please enter your %s.’, ‘email’ => ‘Please enter a valid %s.’);
$form->addDefaultMessages($default_messages);

$form->addQuickElement(’name’, ‘text’, ‘required’, ‘class=name’);
$form->addQuickElement(’address’, ‘text’ );
$form->addQuickElement(’email_address’, ‘text’, ‘required,email’);
$form->addQuickElement(’home_phone’, ‘text’, ‘required’ );
$form->addQuickElement(’cell_phone’, ‘text’ );
$form->addQuickElement(’subject’, ‘text’ );

$textareaAttributes = array(”wrap” => “virtual”,
“cols” => “30″
);

$form->addQuickElement(’message’, ‘textarea’, ”, $textareaAttributes);
$form->addQuickElement(’submit’, ’submit’ );
$form->display();

function process_data ($values) {
require_once “emailHelper.php”;
emailValues($values);
}
?>

Comment by admin
2007-11-30 11:00:44

Nasser,

I’m so sorry, this is my fault. In the actual text of the blog post, the code has the double-quotes escaped, but this got lost in translation when put through WordPress, and it didn’t occur to me to check it. I’ll do some behind-the-scenes fussing and see if I can fix that.

 
Comment by admin
2007-11-30 11:03:49

Nasser,

OK, I think I’ve got it fixed now, and accounted for every double-quote. Let me know if you still have a problem.

 
 
Comment by JoE
2008-01-11 18:57:35

Only got the chance to look at your code quickly but was wondering what the ellipsis are suppose to represent? Just more stuff in between?

Gonna try and implement the code tomorrow, but thought I’d post the question out now. Thank you so much for this. I’m just now getting into PEAR.

Comment by admin
2008-01-11 20:33:41

Yes, the ellipses represents the code from the previous post I mentioned. I hope you find this tutorial helpful.

 
 
Comment by JoE
2008-01-13 14:19:26

Hmmmm, can’t seem to get it working. It’s giving me a “Parse error: syntax error, unexpected T_VARIABLE, expecting T_FUNCTION” at this line: $form = new HTML_QuickForm('contact', 'post', basename(__FILE__));

Not sure if I’m just not combining my functions correctly here, but here’s the full list of code if you’ve got a chance to take a look since I’m sure it’s something quick and simple. Thanks in advance. I truly appreciate people like you willing to help out those of us less educated.

{header}";

var $_elementTemplate =
"{label}
{error}
{element}
";

var $_formTemplate =
"
{hidden}
{content}

";

var $_requiredNoteTemplate =
"

{requiredNote}
";

}

class HTML_QuickerForm extends HTML_QuickForm {
var $renderer;

// Instantiate our form, called 'Create'
$form = new HTML_QuickForm('contact', 'post', basename(__FILE__));

// Our Default Form Options
//$opts = array('size' => 20, 'maxlength' => 255);
$textOpts = array('rows' => 5, 'cols' => 8);

// Add our form elements
$form->addElement('static', 'header', null, 'Quick Contact');
$form->addElement('text', 'name', 'Name', $opts);
$form->addElement('text', 'email', 'E-Mail', $opts);
$form->addElement('textarea', 'message', 'Message', $textOpts);
$form->addElement('submit', 'submit', 'Submit');

$form->addRule('name', 'You must enter your name', 'required', null, 'client');
$form->addRule('name', 'Your name must be at least 3 letters', 'minlength', '3', 'client');
$form->addRule('email', 'You must enter your email address', 'required', null, 'client');
$form->addRule('email', 'Please enter a valid email address', 'email', FALSE, 'client');
$form->addRule('message', 'Form must contain a message', 'required', null, 'client');
$form->addRule('message', 'Message must be a minimum of 10 characters', 'minlength', '10', 'client');

// Process Form
if ($form->validate())
{
// Form Validates
// Handle Form here
$values = $form->exportValues();
// Include the DB access credentials
require 'dbcred.php';

try
{
$db = new PDO($dsn, $user, $password);
$db->setAttribute(PDO::ATTR_ERRMODE,
PDO::ERRMODE_WARNING);

$sql = 'INSERT INTO allamianQC (name, email, message) VALUES (:name, :email, :message)';

$stmt = $db->prepare($sql);
$stmt->bindParam(':name', $values['name']);
$stmt->bindParam(’:email’, $values['email']);
$stmt->bindParam(’:message’, $values['message']);
$stmt->execute();

$form->removeElement(’validemail’);
$form->removeElement(’reqs’);
$form->removeElement(’submit’);
$form->freeze();

$formsource = $form->toHtml() . ‘The above information has been successfully submitted.’;
}
catch (PDOException $e)
{
error_log(’Registration form error: ‘. $e->getMessage());
// Remove unnecessary elements and show result
$form->removeElement(’validemail’);
$form->removeElement(’reqs’);
$form->removeElement(’submit’);
$form->freeze();

error_log(’Error in ‘.$e->getFile().’ Line: ‘.$e->getLine().’ Error: ‘.$e->getMessage());

$formsource = $form->toHtml() . ‘An error has occurred. The above information was not successfully submitted.’;
}
}
else
{
// Form has not yet been submitted, or is invalid, show form
$formsource = $form->toHtml();
}

function display() {
$formsource->renderer = new HTML_QuickForm_Renderer_Default_CSSRender();
$formsource->accept($formsource->renderer);
echo $formsource->renderer->toHtml();
}
?>

 
Comment by JoE
2008-01-13 14:21:56

Tried posting a comment with my code, but doesn’t seem to have gone through. Might try again as I’m having some problems.

Comment by JoE
2008-01-13 14:35:33

So I’m getting a “Parse error: syntax error, unexpected T_VARIABLE, expecting T_FUNCTION in ~/quickContact.php on line 34″

Not sure where I’m messing up, but if you’ve got the chance, I’d love some feedback about what I may be doing wrong and how to implement your method correctly. Thanks in advance, I really appreciate it.

Code: http://www.telegraphicsinc.net/clients/allamian/help.php

Comment by admin
2008-01-13 14:59:00

If the help.php code is correct, you are missing the PHP declarations and the final closing parens on the class. Or is this just a Web publishing error? You can send a file to me at blogger at stonemind dot net also, and I will try to diagnose the issue.

 
 
 
Name (required)
E-mail (required - never shown publicly)
URI
Your Comment (smaller size | larger size)
You may use <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> in your comment.