class
// Render out the form.
$myform->renderActive(new Horde_Form_Renderer(), $vars, 'form.php', 'post');
// Example 3: validating parameters
$vars = Horde_Variables::getDefaultVariables();
$myform = new Horde_Form($vars, 'A simple form');
$myform->setButtons('Submit this form', true);
$myform->addVariable('Insert some text', 'some_text', 'text', true, false, 'Insert in this box some text');
$choices = array('big' => 'BIG',
'small' => 'small',
'mixed' => 'mIxED');
$myform->addVariable('Select something', 'choices', 'enum', false, false, 'Use the selection box to make your choice', array($choices, true));
if ($myform->validate($vars)) {
$myform->getInfo($vars, $info);
echo 'You have submitted:
';
var_dump($info);
echo '
';
}
// Render out the form.
$myform->renderActive(new Horde_Form_Renderer(), $vars, 'form.php', 'post');
// Example 4: a chain of forms
class TestForm1 extends Horde_Form {
var $_useFormToken = false;
function TestForm1(&$vars)
{
parent::__construct($vars, _("Step 1")); // _() for gettext()
$enum = array('' => _("Select:"),
1 => _("Yes"),
0 => _("No"));
// addVariable( Visible Text, name, type, required, readonly,
// description, params)
$this->addVariable(_("Enum"), 'opciones', 'enum', false, false, _("Simple description"), array($enum));
$this->addVariable(_("Boolean"), 'bool', 'boolean', false, false );
$this->addVariable(_("Integer"), 'number', 'int', true, false );
$this->addVariable(_("A Date"), 'mybday', 'date', false, false );
}
}
class TestForm2 extends Horde_Form {
var $_useFormToken = false;
function TestForm2(&$vars)
{
parent::__construct($vars, _("Step 2"));
$this->addVariable(_("Email"), 'email_address', 'email', true, false );
}
}
$r = new Horde_Form_Renderer();
$vars = Horde_Variables::getDefaultVariables();
$form1 = new TestForm1($vars);
$form2 = new TestForm2($vars);
$form1Valid = $form1->validate($vars, true); // Form1 can be autofilled: highlight incorrect fields right away
$form2Valid = $form2->validate($vars);
// Check if one form is not valid.
if (!$form1Valid || !$form2Valid) {
if ($form1Valid) {
$form2->open($r, $vars, 'form.php', 'post');
// show fields of Form1 as inactive
$r->beginInactive($form1->getTitle());
$r->renderFormInactive($form1, $vars);
$r->end();
// include TestForm1 variables as invisible form elements
$form1->preserve($vars);
// render TestForm2 as active
$r->beginActive($form2->getTitle());
$r->renderFormActive($form2, $vars);
$r->submit();
$r->end();
$form2->close($r);
} else {
$form1->open($r, $vars, 'form.php', 'post');
$r->beginActive($form1->getTitle());
$r->renderFormActive($form1, $vars);
$r->submit();
$r->end();
$form1->close($r);
}
} else {
$form1->getInfo($vars, $info);
$form2->getInfo($vars, $info);
echo '';
print_r($info);
echo '
';
}
Horde_Form design issues
Constructors
some PHP 4 constructors are left
Fix:
singletons
Construct & pass dependencies. There should be no reason for a singleton.
Fix:
inheritance + method signature mismatch
- Form_Type's init() pseudo constructor
Fix:
- Use proper constructors
- Provide a builder with a fluent interface?
inconsistent class names
- lowercase field types
Fix:
- Namespaces and structured class names
Internally uses the Horde:: shortcuts (separate package, hard to test)
Fix:
Multiple classes in one file
- Most field types are attached to the Horde_Form_Type base package.
Fix:
- one class per file
Extensive use of reference signatures
Fix: Check if we really need these.
hard-coupled javascript
- parts rely on scriptaculous and hence prototypjs
- parts rely on redboxjs
Fix:
- check if we can factor out the JS
Uses globals
- registry
- injector
- session
- browser
uses var keyword
- At least in renderer
Autowire-unfriendly constructors
- untyped variables and array parameters
Anatomy
A Horde_Form has FormVariables.
A HordeForm may have sections.
A HordeForm may use tokens to validate interactions.
A HordeForm may emit FormErrors for submitted state which is invalid/inconsistent.
It is displayed through a FormRenderer either in "active" (usage) or inactive (readonly) presentation.
FormVariables have FormTypes.
FormVariables have references back to their Form.
FormVariables may have FormActions such as submit the form, ConditionalEnable another Variable.