kevin.jalais
kevin.jalais

Reputation: 60

Zend Form Warning: htmlspecialchars() ... when Element_Text is set as array

I'll try to be as clear as possible. I'm using a zend form with a text element which is using ->setIsArray(true);

$submenu2 = new Zend_Form_Element_Text('submenu2');
$submenu2->setValue('Sous menu 2')
     ->setIsArray(true)
     ->setAttrib('class', 'cloneSub')
     ->setAttrib('id', 'sub1')
     ->setAttrib('onFocus', 'javascript:myFocus(this); return;')
     ->setAttrib('onBlur', 'javascript:myBlur(this); return;');
$this->addElement($submenu2);

I set the element as array because i'm using javascript to dynamically add new elements.
In html, it means :

<input type="text" name="submenu2[]" />

My problem : When i submit the form it generate me the following error

Warning: htmlspecialchars() expects parameter 1 to be string, array given in /usr/local/zend/share/ZendFramework/library/Zend/View/Abstract.php on line 905

After looking everywhere on the web i found the reason but not the solution. It's due to the _escape() method using by zend_form::isValid() which is only expecting strings.

I found a beginning of solution in the Rob Allen's DevNotes here :

http://akrabat.com/page/29/?flattrss_redirect&id=31&md5=b369e042145cc83b1dd4b0031132b801

look at the section : "Simple Zend_Form File Upload Example Revisited"

But when i try to bend the code to resolve my problem, it generates me the following error :

Fatal error: Class 'App_Form_Element_Text' not found in ...

By the way, i encounter the same problem if simply try to populate datas into the same kind of field.

Does anyone has any idea ? Thanks a lot.



UPDATE:

$submenu2 = new Custom_Elements_ArrayElement('submenu2');
$submenu2->setValue('Sous menu 2')
     ->setIsArray(true)
     ->setAttrib('class', 'cloneSub')
     ->setAttrib('id', 'sub1')
     ->setAttrib('onFocus', 'javascript:myFocus(this); return;')
     ->setAttrib('onBlur', 'javascript:myBlur(this); return;');
$this->addElement($submenu2);

I created the Class you gave me in "APPLICATION_PATH "/../library/Custom/Elements"
And i get :

Fatal error: Class 'Custom_Elements_ArrayElement' not found

Upvotes: 0

Views: 2343

Answers (2)

bstricks
bstricks

Reputation: 923

That code was forgetting a getValues function. Also, be sure to remove the ViewHelper Decorator. As far as your element not being found, you need to add it to your class path and then probably

$this->addPrefixPath(
                     'Custom_Zend_Form_Element', 
                     'Custom/Zend/Form/Element', 
                     'element'
                   );

Upvotes: 0

Vytautas
Vytautas

Reputation: 3539

Here is example:

Create your own element type that will accept an array of values, and then a decorator that will output the various input items.

class My_Element_ArrayElement extends Zend_Form_Element 
{ 
    public function init() 
    { 
        $this->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator'); 
    } 

    public function setValue($value) 
    { 
        $this->_value = (array) $value; 
    } 

    public function getValues() 
    { 
        return $this->_value; 
    } 


    public function loadDefaultDecorators() 
    { 
        if ($this->loadDefaultDecoratorsIsDisabled()) { 
            return; 
        } 

        $decorators = $this->getDecorators(); 
        if (empty($decorators)) { 
            $this->addDecorator('ArrayElement'); 
        } 
    } 

} 

class My_Decorator_ArrayElement extends Zend_Form_Decorator_Abstract 
{ 
    public function render($content) 
    { 
        $element = $this->getElement(); 
        $view    = $element->getView(); 
        $markup  = ''; 
        $name    = $element->getName() . '[]'; 

        foreach ($element->getValues() as $value) { 
            $markup .= $view->formHidden($name, $value) . "\n"; 
        } 

        $separator = $this->getSeparator(); 
        switch ($this->getPlacement()) { 
            case 'PREPEND': 
                return $markup . $separator . $content; 
            case 'APPEND': 
            default: 
                return $content . $separator . $markup; 
        } 
    } 
} 

Upvotes: 2

Related Questions