Add some html to Zend Forms

2019-01-07 12:35发布

问题:

Im looking for a simple bit of code that will let me add the following html into my zend form:

<div id="wmd-button-bar" class="wmd-panel"></div>

Thats it, it needs to be above my 'method' element in the form but thats it. For such a simple action I cant find any methods that don't involve me learning rocket science (i.e Zend Decorators).

回答1:

The only way I can think of at the moment is to add a dummy element to the form and remove all decorators except an 'HtmlTag' with the attributes you specified in your question. Removing the decorators means that the actual element will not be rendered - only the HtmlTag decorator will be rendered.

so assuming your form is $form:

$form->addElement(
    'hidden',
    'dummy',
    array(
        'required' => false,
        'ignore' => true,
        'autoInsertNotEmptyValidator' => false,
        'decorators' => array(
            array(
                'HtmlTag', array(
                    'tag'  => 'div',
                    'id'   => 'wmd-button-bar',
                    'class' => 'wmd-panel'
                )
            )
        )
    )
);
$form->dummy->clearValidators();

Note that you want to prevent any validation of the element. This is only one way - there are likely others.

Output:

<div id="wmd-button-bar" class="wmd-panel"></div>

There is a good article describing decorators.



回答2:

You can create your own view helper libraray--App>View>Helper>PlainTextElemet.php

Create a folder in your library folder that name is App so a folder that name is View so in View create Helper Folder so in Helper folder create a class with PlainTextElement name same following

 class App_View_Helper_PlainTextElement extends Zend_View_Helper_FormElement {

        public function PlainTextElement($name, $value = null, $attribs = null) {
            $info = $this->_getInfo($name, $value, $attribs);
            extract($info); // name, value, attribs, options, listsep, disable
            if (null === $value) {$value = $name;}

            return $value;
          }

    }

Then in libray same above create a class App>Form>Element>PlainText.php

And put folowing code in this class

class App_Form_Element_PlainText extends Zend_Form_Element_Xhtml {

    public $helper='PlainTextElement';

    public function isValid($value){

        return true;
    }
}

Now in your form you can create each html code you like:

$someValue = '<div id="wmd-button-bar" class="wmd-panel"></div>';

        $this->addElement(new App_Form_Element_PlainText('pliantext1', array(
                            'value'=>$someValue,
        )));

Don't forget in your application.ini add fllowing lines too:

 autoloaderNamespaces.app = "App_"
 resources.view.helperPath.App_View_Helper="App/View/Helper"


回答3:

You can try this way, no config, just one extension class reference: http://www.zfsnippets.com/snippets/view/id/50

<?php

/**
 * Form note element
 *
 * @author Ruslan Zavackiy <ruslan.zavackiy@gmail.com>
 * @package elements
 */

/**
 * Loads helper Zend_View_Helper_FormNote
 */

class Custom_Form_Element_Note extends Zend_Form_Element_Xhtml
{
    public $helper = 'formNote';
}
?>

then

$companies->addElement('note', 'companyNote', array(
            'value' => '<a href="javascript:;" id="addCompany">Add Company</a>'
        ));


回答4:

How about using some JQuery:

Something like:

<script language="javascript">
    $(document).ready(function() {
        $('#submit-element').append('<div id="wmd-button-bar" class="wmd-panel"></div>');
    });
</script>


回答5:

  • Create a custom Decorator that return the label(or anything else):

    class My_Decorator_CustomHtml extends Zend_Form_Decorator_Abstract {
                public function render($content)
            {
                $element = $this->getElement();
                if (!$element instanceof Zend_Form_Element) {
                    return $content;
                }
                if (null === $element->getView()) {
                    return $content;
                }
                $html = $element->getLabel();
                return $html;
           }
    
    
    }
    
  • Place this in the decorator path

    <pre>$form->addElementPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');</pre>

  • Create the element and put the custom html in the label

    $html = '<div id="wmd-button-bar" class="wmd-panel">some text....</div>'; $element = new Zend_Form_Element_Hidden('hidden-input', array( 'label'=>$html, ));
    $element->setDecorators(array('CustomHtml')); //add it to the form $form->addElement($element);

and that's it



回答6:

I come with a Html element that you can include in you own library

class Application_Form_Element_Html extends Zend_Form_Element_Xhtml
{
    /**
     * Build the element and set the decorator callback to generate the html.
     */
    public function __construct($name, $options)
    {
        // Get the HTML to generate.
        $html = $options['html'];

        // Set the decorators for the generation.
        $this->setDecorators(array
        (
            array('Callback', array
            (
                'callback' => function($content) use ($html)
                {
                    return $html;
                }
            ))
        ));
    }
}

To include it, don't forget to do

$form->addPrefixPath('Application_Form_Element', APPLICATION_PATH . '/forms/Element', 'element');

Then in you form initialization simply call:

$form->addElement($this->createElement('html', 'info', array
(
    'html' => '<div>My awesome HTML</div>';
)));


回答7:

SOLUTION CODE add this class to your /application/form and extend all your forms from this class

  class Application_Form_SpecialSubform extends Zend_Form_SubForm
{
    protected $_openTag = '<form>';
    protected $_closeTag = '</form>';
    protected $_htmlIniCloseTagChars = '</';

    public function render(\Zend_View_Interface $view = null) {
        if (!$this->isPartOfAForm())
           $this->addDecorator('Form'); 
        return parent::render($view);
    }

    protected function isPartOfAForm(){
        return (!is_null($this->getElementsBelongTo()));
    }

    public function initForm()
    {       
        $defaultZendCloseTag = $this->getDefaultFormViewCloseTag();      
        $completeTag='';
        $this->addDecorator('Form'); 
        $this->getDecorator('Form')->setElement($this);
        $completeTag=$this->getDecorator('Form')->render('');
        $this->set_openTag(str_replace($defaultZendCloseTag, '', $completeTag));
        return $this->get_openTag();
   }

    public function endForm()
    {
        return $this->get_closeTag();
    }

    protected function getDefaultFormViewCloseTag()
    {
        $defaultFormTag = $this->get_closeTag();
        $view = $this->getView();
        $defaultTag = $view->form('',null,true);
        $pos = strrpos ($this->get_htmlIniCloseTagChars(),$defaultFormTag);
        if ($pos !== false) {
            $defaultFormTag =  substr($defaultTag, $pos); 
        }
        $this->set_closeTag($defaultFormTag);
        return $defaultFormTag;
    }
    protected function get_openTag() {
        return $this->_openTag;
    }

    protected function get_closeTag() {
        return $this->_closeTag;
    }

    protected  function get_htmlIniCloseTagChars() {
        return $this->_htmlIniCloseTagChars;
    }

    protected function set_openTag($_openTag) {
        $this->_openTag = $_openTag;
    }

    protected  function set_closeTag($_closeTag) {
        $this->_closeTag = $_closeTag;
    }

    protected function set_htmlIniCloseTagChars($_htmlIniCloseTagChars) {
        $this->_htmlIniCloseTagChars = $_htmlIniCloseTagChars;
    }  
    }

at your view, you must call initForm() when you want to open the form tag and endForm() to close it, as you can see ALL ZF behaviour is untouched so its totally compatible.

MORE TECH EXPLANATION:

To add or inject any code between our zend forms the best and cleanest way it use SubForms in all of your forms, Subforms are forms so you got all features like validation, filter .... and also you can reuse it easy and stack as many as you want inside your form or inside any other subform. Also handle the resulting post its trivial.
so lets do an example supouse you got an admin of user information like address, telephone number etc, lets say userInfo another part of yout site handles more private information like banck account and religion. and at least one more restricted area admin protected who handle user pasword and role. you of course has your 3 forms, at different controllers and actions of your code. And now you need to put it all together, but you need a lot of markup to show it in labels or to explain any area. with subforms its trivial just echo $this->form->subformName at your view. at this point you will notice that the form tag will not appear and you are unable to send the post. this is the only problem of this tecnique and it will solve with a simple and (let me tell it) elegant class extend and overload of render method.



回答8:

Put it in your view script...

<!-- /application/views/scripts/myController/myAction.phtml -->

<div id="wmd-button-bar" class="wmd-panel"></div>
<?php echo $this->form ;?>


回答9:

You have to add decorator.

Any markup decorator may be helpful.

For further information about decorators see: http://www.slideshare.net/weierophinney/leveraging-zendform-decorators



回答10:

This functionality is built into Zend via Zend_Form_Element_Note.

new Zend_Form_Element_Note('forgot_password', array(
    'value' => '<a href="' . $this->getView()->serverUrl($this->getView()->url(array('action' => 'forgot-password'))) . '">Forgot Password?</a>',
))