How can I use zend form decorator to render errors inside my paragraph tag wrapping label and input - zend-framework

I would like to render the following markup:
<div class="row">
<p>
<label>Your Name</label>
<input type="text" class="text_field" name="name">
<ul class="errors">
<li>Waarde is vereist en kan niet leeg worden gelaten</li>
</ul>
</p>
</div>
This is my Zend form element + decorator:
$this->addElement('text', 'name', array(
'label' => 'Naam:',
'class' => 'text_field',
'required' => true,
'decorators' => array(
'ViewHelper',
'Label',
'Errors',
array(array('row' => 'HtmlTag'), array('tag' => 'p')),
array(array('content' => 'HtmlTag'), array('tag' => 'div', 'class' => 'row'))
)));
But this always renders the ul list below the p tag and never inside. It also adds an additional p tag below the list.
<div class="row">
<p>
<label class="required" for="name">Naam:</label>
<input type="text" class="text_field" value="" id="name" name="name">
</p>
<ul class="errors">
<li>Waarde is vereist en kan niet leeg worden gelaten</li>
</ul>
<p></p>
</div>
What am I doing wrong?

Found it! My stupid mistake. I did only check the final rendered output in my browser. I am using a template which also loads javascript and this changes the DOM which creates the unwanted result.
So the first decorator setup was working correct.

Try to do the following:
$this->addElement('text', 'name', array(
'label' => 'Naam:',
'class' => 'text_field',
'required' => true,
'decorators' => array(
'ViewHelper',
'Label',
'Errors',
array(array('content' => 'HtmlTag'), array('tag' => 'p')),
array(array('content' => 'HtmlTag'), array('tag' => 'div', 'class' => 'row'))
)));

Related

Zend Form Decorator on 1.12 version

Hi all I'm trying to render this html structure with Zend :
<div id="medias" class="item">
<h2> Medias </h2>
<a id="addmedia" href="#">
<img alt="" src="images/bigbtn-add.png">
</a>
</div>
Update 1 :
This is how I create the media_img element :
$media_img = new Zend_Form_Element_Image('media_img');
$media_img->setImage("/img/bigbtn-add.png");
$this->addElement($media_img);
Using this :
$this->setElementDecorators(array(
'ViewHelper',
'HtmlTag', array('HtmlTag', array('tag' => 'a', 'id' => 'addmedia','href' => '#'))
),
array('media_img')
);
I properly render this part of my code :
<a id="addmedia" href="#">
<img alt="" src="images/bigbtn-add.png">
</a>
How can I prepend the h2 and then wrap these elements inside my div ?
Update 2 :
Thanks to #Mubo's help, I render this html :
<h2 class="hint">Medias</h2>
<a id="addmedia" href="#">
<input id="media_img" type="image" src="/img/bigbtn-add.png" name="media_img">
</a>
Now I only need to wrap all of these lines in a div.
The decorator looks like this now :
$this->setElementDecorators(array(
'ViewHelper',
'HtmlTag', array('HtmlTag', array('tag' => 'a', 'id' => 'addmedia','href' => '#')),
array('Description', array('tag' => 'h2', 'placement' => 'prepend')),
),
array('media_img')
);
What's missing ?
Thanks for your help.
Update 3 : I still can't figure it out...
You can use setDescription and prepend it with decorator like this.
This is very tricky and not straightforward.
$myElement = new Zend_Form_Element_Text('name');
$myElement->setLabel('Label');
$myElement->setRequired(true);
$myElement->setDescription('Medias');
$myElement->setDecorators( array( 'DijitElement', 'Errors',
array(array('data' => 'HtmlTag'), array('tag' => 'td')),
array('Label', array('tag' => 'td')),
array('Description', array('tag' => 'h2', 'placement' => 'prepend')),
array(array('row' => 'HtmlTag'), array('tag' => 'tr', 'class' => 'form_row'))
));
$this->addElement($myElement);
Wow, I finally found a solution. Here is my decorator :
$media_img->setDecorators(array(
'ViewHelper',
'Errors',
array('HtmlTag', array('tag' => 'a', 'id' => 'addmedia','href' => '#')),
array('Description', array('tag' => 'h2', 'placement' => 'prepend')),
array(
array('fieldDiv' => 'HtmlTag'),
array(
'tag' => 'div', 'class' => 'item', 'id' => 'medias'
)
)
));

Zend Framework 2 formInput or formElement ID tag not rendering

In Zend framework 2, when I use the view's formRow method like so
$this->formRow($form->get('product_name'));
it will generate HTML like this
<label for="product_name">
<span>Name</span>
<input type="text" id="product_name" name="product_name">
</label>
but if I use formInput
<div class="control-group">
<?php echo $this->formLabel($form->get('product_name')->setLabelAttributes(array('class'=>'control-label'))); ?>
<div class="controls">
<?php echo $this->formInput($form->get('product_name')); ?>
</div>
</div>
$this->formInput($form->get('product_name'));
i don't get the id tag
<input type="" name="product_name">
I've tried with formElement with same results.
How can I get it to render just the input with all attributes and values?
This is how my Zend Framework 2 View looks like (simplified)
<?php echo $this->form()->openTag($form); ?>
<div class="control-group">
<?php echo $this->formLabel($form->get('product_name')->setLabelAttributes(array('class'=>'control-label'))); ?>
<div class="controls"><?php echo $this->formInput($form->get('product_name')); ?></div>
</div>
<div class="control-group">
<div class="controls"><?php echo $this->formSubmit($form->get('submit')); ?></div>
</div>
<?php echo $this->form()->closeTag(); ?>
and the Zend Framework 2 Form
<?php
namespace Product\Form;
use Zend\Form\Form;
class ProductForm extends Form
{
public function __construct($name = null)
{
// we want to ignore the name passed
parent::__construct('product');
$this->setAttribute('method', 'post');
$this->setAttribute('class','form-horizontal');
$this->add(array(
'name' => 'product_name',
'attributes' => array(
'type' => 'text',
),
'options' => array(
'label' => 'Name',
),
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Save',
'id' => 'submitbutton',
'class'=>'btn btn-success btn-large'
),
));
}
}
?>
Change:
$this->add(array(
'name' => 'product_name',
'attributes' => array(
'type' => 'text',
),
'options' => array(
'label' => 'Name',
),
));
to:
$this->add(array(
'name' => 'product_name',
'attributes' => array(
'type' => 'text',
'id' => 'product_name',
),
'options' => array(
'label' => 'Name',
),
));
Actually this code:
$this->add(array(
'type' => 'Zend\Form\Element\Text',
'name' => 'product_name',
'attributes' => array(
'id' => 'product_name',
'class' => 'span3',
),
'options' => array(
'label' => 'Your label',
),
));
could be used correctly by a css renderer like Bootstrap due to fact that the $this->formRow(...) form helper will produce:
<label for="product_name">Your label</label><input type="text" name="product_name" class="span3" id="product_name" value="">
which is more readable than the original formRow output (without id neither class attributes)

How to apply decorators on the Input Title of radio button in Zend Framework

I have a zend form and a I need the final Output HTML of the Radio Group to be like this :
<div>
<span class='radio_title'>Gender</span> <!-- The issue is in this line -->
<span class='felement'>
<label ....> <input type="radio" ...... value="male" /></label>
<label ....> <input type="radio" ...... value="female" /></label>
</span>
</div>
(i.e.) Replace the default dt and dd with customized div or span tags
I created a decorator as follows:
$decorator = array(
'ViewHelper',
'Errors',
array(array('data' => 'HtmlTag'), array('tag' => 'span', 'class'=> 'felement')),
// the next line is never applied
array('Label', array('tag' => 'span', 'class'=> 'fradio' , 'placement'=>'prepend') ),
array(array('row' => 'HtmlTag'), array('tag' => "div"))
);
$gender = new Zend_Form_Element_Radio("gender",
array(
"label"=>"Gender",
'multiOptions'=>array(
'male'=>'Male',
'female'=>'Female'
),
"decorators"=>$decorator
));
and I got this output instead:
<dt id="gender-label">
<label class="optional">Gender</label>
</dt>
<!-- i don't know why the Main Label of the radio group didn't
have the Label decorator applied to it -->
<div>
<span class="felement">
<label for="gender-male"><input type="radio" disablefor="1" checked="checked" value="male" id="gender-male" name="gender">Male</label>
<label for="gender-female"><input type="radio" disablefor="1" value="female" id="gender-female" name="gender">Female</label>
</span>
</div>
I Applied this Decorator:
array(
'ViewHelper',
'Errors',
array(array('data' => 'HtmlTag'), array('tag' => 'div', 'class'=> 'fradioelement')),
array('Label', array('tag' => 'span', 'class'=> 'fradiotitle') ),
array('description', array('tag' => 'span')),
array(array('row' => 'HtmlTag'), array('tag' => "div","class"=>"radioelement"))
);
And it gave me this output:
<div class="radioelement">
<span id="gender-label"><label class="fradiotitle optional" for="gender">Gender</label></span>
<div class="fradioelement">
<label for="gender-male"><input type="radio" checked="checked" value="male" id="gender-male" name="gender">Male</label>
<label for="gender-female"><input type="radio" value="female" id="gender-female" name="gender">Female</label>
</div>
</div>
Which is almost what I needed.
** I had to add :
'disableLoadDefaultDecorators' => true
in the options of the element

Zend Framework: Captcha problem

Iam using following code to generate CAPTCHA :
$captcha = $this->createElement('captcha', 'captcha',
array('required' => true,
'captcha' => array('captcha' => 'Image',
'font' => 'resource/fonts/arial.ttf',
'fontSize' => '24',
'wordLen' => '5',
'height' => '50',
'width' => '150',
'imgDir' => 'resource/captcha',
'imgUrl' => 'resource/captcha',
'gcFreq'=>'10',
'dotNoiseLevel' => '10',
'lineNoiseLevel' => '2')));
$captcha->setLabel('Captcha');
Following code is generated:
<label for="captcha-input" class="login_label required">Captcha</label>
<img width="150" height="50" alt="" src="captcha/eb3a592c8b1c7a71b0c7ce5179422be2.png" />
<input type="hidden" name="captcha[id]" value="eb3a592c8b1c7a71b0c7ce5179422be2" id="captcha-id">
<input type="text" name="captcha[input]" id="captcha-input" value="">
<input type="text" name="captcha" id="captcha" value="eb3a592c8b1c7a71b0c7ce5179422be2">
Can someone guide me how can I remove extra input text fields like
<input type="text" name="captcha" id="captcha" value="eb3a592c8b1c7a71b0c7ce5179422be2">
Thanks in advance
It's important to do the
$this->getElement('captcha')->removeDecorator("viewhelper");
after you have enabled the ElementsDecorators (which sets the ViewHelper in the first place - don't delete this, it's required anyway)
For me it looks like this:
$this->setElementDecorators(array(
'ViewHelper',
'Errors',
array(array('data' => 'HtmlTag'), array('tag' => 'td')),
array('Label', array('tag' => 'td')),
array(array('row' => 'HtmlTag'), array('tag' => 'tr'))
));
$this->getElement('captcha')->removeDecorator("viewhelper");
That input is not "extra" - it's essential.
When the CAPTCHA is validated, the value of that field is used to look up the correct solution to the CAPTCHA, which is then compared against the user's input.
Without that field, your CAPTCHA will break.
Why would you want to remove it in the first place?
You can try this:
$this->getElement('captcha')->removeDecorator("viewhelper");
I had the same problem. Remove the "ViewHelper" decorator and the captcha will render properly.

using zend form decorators

<div class="field50Pct">
<div class="fieldItemLabel">
<label for='First Name'>First Name:</label>
</div>
<div class="fieldItemValue">
<input type="text" id="firstname" name="firstname" value="" />
</div>
</div>
<div class="clear"></div>
I want the code to appear like this in source code . how do i write the same thing in zend using decorators ?
The element is like
$firstname = new Zend_Form_Element_Text('FirstName');
$firstname->setLabel('FirstName')
->setRequired(true)
->addFilter('StripTags')
->addFilter('StringTrim')
->addErrorMessage('Error in First Name')
->addValidator('NotEmpty');
This seems to work for me:
(with <div class="clear"></div> after the input)
$firstname->setDecorators(array(
'ViewHelper',
'Description',
'Errors',
array('HtmlTag', array('tag' => 'div', 'class' => 'fieldItemValue')),
array(array('labelDivOpen' => 'HtmlTag'),
array('tag' => 'div',
'placement' => 'prepend',
'closeOnly' => true)),
'Label',
array(array('labelDivClose' => 'HtmlTag'),
array('tag' => 'div',
'class' => 'fieldItemLabel',
'placement' => 'prepend',
'openOnly' => true)),
array(array('fieldDiv' => 'HtmlTag'),
array('tag' => 'div', 'class' => 'field50Pct')),
array(array('divClear' => 'HtmlTag') ,
array('tag' => 'div' ,
'class' => 'clear',
'placement' => 'append'))
));