1

I'm dissatisfied with the way Zend_Form renders form elements by default, and want to override it for all forms produced by instantiating a helper class I have that inherits from Zend_Form to take care of some things that I do on all of my forms.

The changes I want to make seem more complicated than is reasonable/possible with decorators, so I'd like to use a custom HTML template to accomplish this, where I get to plug form values into a custom HTML snippet.

How can I set all HTML elements rendered by my class to use an HTML template? And what properties/functions should I call from the template to get the stuff Zend_Form renders by default? Lastly, I would prefer to do this without having to manually set the template on each input element I create in my code.

3 Answers 3

1

You can extend the defualt Zend_Form class with your own Custom_Form class. In the init() method overwrite the default element decorators. Here my code snippet:

//class Custom_Form extends Zend_Form
public function init()
{
    $this->setElementDecorators(
            array(array('ViewScript', array('viewScript' => '/controller_name/forms/fields/input-text.phtml'))),
            array('email', 'firstname', 'lastname')
        );
}
Sign up to request clarification or add additional context in comments.

2 Comments

Is there any documentation for how I should write viewscripts that work for individual, generic form elements? All I've seen is how to write a viewscript for an entire form, which isn't what I'm after. I love that I can just pass element objects to Zend_Form and it renders stuff without me writing HTML for each form I need, I just want it to render stuff differently.
search for setElementDecorators()
1

I've done my share of coding with ZF1 and the best way I found to render nice forms was to use Twitter Bootstrap along with it.

Check the following links to see if that's also a satisfactory solution for you too:

  1. how to use the twitter bootstrap framework in a zend framework 1 application?
  2. http://twitter.github.io/bootstrap/

Comments

1

I wound up using a custom viewscript that I genericized to work with arbitrary forms.

Using this approach, I was able to do the following things:

  • Add an asterisk after the label of required form elements
  • Group inputs and errors together in one div, so that when I float the labels to the left things still line up
  • Add a special class to erroring inputs so I can highlight them
  • Change certain error messages to include the name of the element instead of "Value"
  • Pass a text note along with the form elements to be displayed under the input
  • Not wrap labels and inputs in special elements

Some of these things are impossible without a viewscript, and some are just a pain to implement. I think this solution will be much more flexible for me going forward.

In my helper class' render() function:

$view = new Zend_View();
$view->setBasePath(SRC_ROOT . "/templates/forms");
$this->setDecorators(array(array('ViewScript', array('viewScript' => 'viewscript.php'))));

And here's my viewscript:

<link rel="stylesheet" type="text/css" href="/styles.css" />

<form id="<?php echo $this->element->html_id ?>" class="<?php echo $this->element->html_class ?>" enctype="application/x-www-form-urlencoded" action="" method="post">
    <?php foreach($this->element as $element) { ?>
        <?php

        $decorators = $element->getDecorators();
        if(isset($decorators["Zend_Form_Decorator_Label"])) {
            $label = $element->getLabel();
        } else {
            $label = "";
        }

        if($element->isRequired() === true) {
            $label .= " *";
        }
        ?>
        <label class="label" for="<?php echo $element->getName(); ?>"><?php echo $label; ?></label>

        <div class="formInput">
            <?php
            // Add the error class to make the form inputs highlight in red
            if($element->hasErrors()) { 
                $attribs = $element->getAttribs();
                if(!isset($attribs["class"])) {
                    $attribs["class"] = "";
                }
                $attribs["class"] .= " inputError";
                $element->setAttribs($attribs);
            }

            // Print the input using Zend_Form's own mechanisms
            $element->setDecorators(array('ViewHelper'));  // Removes all decorators (labels, etc.)
            $v = new Zend_View();
            $element->setView($v);
            echo $element->render();

            if(isset($element->note)) {
                echo "<p>{$element->note}</p>";
            }

            // Print the error messages
            if($element->hasErrors()) {
                $errors = $element->getMessages();
            ?>
                <ul class="errors <?php echo sizeof($errors) == 1 ? "noDecorations" : "" ?>">
                <?php 
                foreach($errors as $error => $message) {
                    // Custom error messages
                    if($error === "isEmpty") {
                        $message = $element->getLabel() . " cannot be empty";
                    } ?>
                    <li><?php echo $message ?></li>
                <?php } ?>
                </ul>
            <?php } ?>
        </div>
        <div style="float: clear;"></div>
    <?php } ?>
</form>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.