I am using Zend Framework in my project. I want to add a description/note to my forms, like
fields marked by * are mandatory
But i didn't found how to add a description to a form and how to use it with decorators.
Any help will be highly appreciated. Thanks.
There are two options:
Use a from decorator or
Extend Zend_Form_Element to create a custom
element
I would go with the latter, since it is very common to add parts of raw html code to forms not only before elements or after, but among them also.
You should do something like this:
class My_Form_Element_Raw extends Zend_Form_Element
{
protected $raw_html;
public function setRawHtml($value)
{
$this->raw_html = $value;
return $this;
}
public function getRawHtml()
{
return $this->raw_html;
}
public function render()
{
// you can use decorators here yourself if you want, or wrap html in container tags
return $this->raw_html;
}
}
$form = new Zend_Form();
// add elements
$form->addElement(
new My_Form_Element_Raw(
'my_raw_element',
array('raw_html' => '<p class="highlight">fields marked by * are mandatory</p>')
)
);
echo $form->render();
When extending Zend_Form_Element you dont need to overide setOption/s, getOption/s methods.
Zend internally uses set* and get* and protected properties to detect element options like in this case protected $raw_html; and public function setRawHtml($value) and public function getRawHtml()
Also naming your property $raw_html will accept both options of 'raw_html' and 'rawHtml' respectively
The easiest way to add additional text to your forms is to just add the appropriate html to the page view:
<div>
<h4>fields marked by * are mandatory</h>
<?php echo $this->form ?>
</div>
or use the viewScript decorator to control the entire form experience:
<article class="login">
<form action="<?php echo $this->element->getAction() ?>"
method="<?php echo $this->element->getMethod() ?>">
<table>
<tr>
<th>Login</th>
</tr>
<tr>fields marked by * are mandatory</tr>
<tr>
<td><?php echo $this->element->name->renderViewHelper() ?></td>
</tr>
<tr>
<td><?php echo $this->element->password->renderViewHelper() ?></td>
</tr>
<tr>
<td><?php echo $this->element->submit ?></td>
</tr>
</table>
</form>
</article>
However you can add a description to your form using $form->setDescription() then you can render that description with echo $this->form->getDescription(). It would probably be better to use these methods at the element level along with set and getTag() instead of the form level.
To provide the asterisk clue I just use css:
dt label.required:before {
content: "* ";
color: #ff0000;
}
I'm sure you can display any note you want using just css if you want.
class FormDecorators {
public static $simpleElementDecorators = array(
array('ViewHelper'),
array('Label', array('tag' => 'span', 'escape' => false, 'requiredPrefix' => '<span class="required">* </span>')),
array('Description', array('tag' => 'div', 'class' => 'desc-item')),
array('Errors', array('class' => 'errors')),
array('HtmlTag', array('tag' => 'div', 'class' => 'form-item'))
);
}
These are decorators for elements i usually use, they contain prefix with * and also description decorator.
then use code:
$element->setDescription('fields marked by * are mandatory');
Add description to one element,after that You can style description to appear somewhere in the bottomt, I hope this helps, have a nice day.
Related
I want to add red border around Input Text Box when ZF2 Validation failed. I am thinking if ZF2 provide way to add/set css class in case of validation failure.
It is better if it is possible using only Zend Validation/Form API. I am not considering client side (javascript/jQuery) solutions.
UPDATE :
I am using Form Row element like that
<div class="row">
<div><?php echo $this->formLabel($form->get('first_name')); ?></div>
<div><?php echo $this->formElement($form->get('first_name')); ?></div>
<div><?php echo $this->formElementErrors($form->get('first_name'), array('class' => "field-validation-error")); ?></div>
</div>
You can use FormRow view helper, which will render non-valid elements with CSS class ("input-error" by default).
Usage is very simple, in your template:
echo $this->formRow($element);
or if you want custom class:
echo $this->formRow()->setInputErrorClass('my-error-class')->render($element);
If you wish to add specific 'error' classes to the input will need to modify the related Zend\Form\View\Helper\Form* classes as these are what introspect the Zend\Form\ElementInterface objects and render the required HTML.
For example:
// \MyModule\Form\View\Helper\MyCustomFormElement.php
class MyCustomFormElement extends \Zend\Form\View\Helper\FormElement
{
public function render(Element $element)
{
$errors = $element->getMessages();
if (! empty($errors)) {
$classes = $element->getAttribute('class');
if (null === $classes) $classes = array();
if (! is_array($classes)) $classes = explode(' ', $classes);
$classes = array_unique(array_merge($classes, array('my-error-class')));
$element->setAttribute('class', implode(' ', $classes));
}
return parent::render($element);
}
}
Then just replace the default form element helper by registering a invokable with the same name.
// Module.php
public function getViewHelperConfig()
{
return array(
'invokables' => array(
'form_element' => 'MyModule\Form\View\Helper\MyCustomFormElement',
),
);
}
I have this code Im trying to save the content and the title from a form I made..It has an id that autoincrement the id number adds in the database but the title and the content isn't/cant be save in the database. Can you please check my code if I've done something wrong? or what I'm lacking at.
Here is my model ContentForm.php
<?php
class ContentForm extends CActiveRecord{
public $content;
public $title;
public function tableName(){
return 'tbl_content';
}
public function attributeLabels()
{
return array(
'contentid' => 'contentid',
'content' => 'content',
'title' => 'title',
// 'email' => 'Email',
// 'usrtype' => 'Usrtype',
);
}
Here is my view content.php
<div>
<p>User: <a href="viewuserpost">
<?php
echo Yii::app()->session['nameuser'];
?>
</a>
</p>
</div>
<h1>Content</h1>
<?php
$form=$this->beginWidget('CActiveForm', array(
'id'=>'contact-form',
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
));
?>
Title:
<div class="row">
<?php
echo $form->textfield($model,'title');
?>
</div>
</br>
Body:
<div class="row">
<?php
echo $form->textArea($model,'content',array('rows'=>16,'cols'=>110));
?>
</div>
<div class="row buttons">
<?php
echo CHtml::submitButton($model->isNewRecord? 'Create':'Save');
?>
</div>
<?php $this->endWidget(); ?>
and here is my content action in my sitecontroller.php
public function actionContent(){
$model=new ContentForm;
if(isset($_POST['ContentForm'])) {
$model->attributes=$_POST['ContentForm'];
if($model->save())
$this->redirect(array('content','contentid'=>$model->contentid));
$this->redirect(array('content','title'=>$model->title));
$this->redirect(array('content','content'=>$model->content));
}
$this->render('content',array('model'=>$model));
}
Please help.
Remove
public $content;
public $title;
from your class.
Yii uses PHP magic methods. And when you add attributes to your class, PHP doesn't call them but references to your explicitly written attributes.
Moreover, you should add some validation, if you use $model->attributes=$_POST['ContentForm'];. Another variant is to use unsecure $model->setAttributes($_POST[ContentForm], false) where false tells Yii to set all attributes, not only that are considered safe.
Note, that attributes is not real Model attribute, this is virtual attribute accessed through magic methods.
Also, you don't need three redirects. This is HTTP redirect to other page. This time, you just should just specify route to model view action and its parameter that is id, for example. Like this $this->redirect(array('content/view','id'=>$model->contentid));.
Of course, simplest way for you is to create new model and controller with actions using Gii.
you may missed rules , add this in your model ContentForm.php
public function rules()
{
return array(
array('content,title', 'safe'),
);
}
For more about model validation
http://www.yiiframework.com/wiki/56/reference-model-rules-validation/
I cant get the value in the placeholder,the placeholder is empty
<div class="form_element">
<?php
//$name = $form->get('name');
$this->placeholder('name')->data="text value";
$name= $form->get('name');
echo $formLabel->openTag().$name->getOption('label')." ";
echo $this->formInput($name);
echo $formLabel->closeTag();
?>
</div>
In your code you used placeholder view helper (more about), and I don't see where you trying to get placeholder's value. It seems you asked about form input field placeholder attribute. If it true, then you must specify it as attribute. View helper placeholder is for different tasks.
Your form view helpers usage a little strange. May suggest my version of your code.
<div class="form_element">
<?php $name = $form->get('name'); ?>
<?php $name->setAttribute('placeholder', 'placeholder text'); ?>
<?php echo $formLabel($name); ?>
<?php echo $formInput($name); ?>
</div>
The better solution is to set placeholder in form element definition. For example:
<?php
use Zend\Form\Form;
class MyForm extends Form
{
public function __construct()
{
parent::__construct('<FORM_NAME>');
$this->add(array(
'name' => 'name',
'type' => 'Zend\Form\Element\Text',
'attributes' => array(
'placeholder' => '<PLACEHOLDER_TEXT>',
),
));
}
}
In CListView there is a property called "itemsCssClass" which basically adds HTML class attribute to the Itemwrapper.
What if I like to add an ID or any other htmlOptions how will I do it on that wrapper..?
My code is :
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$model->search(),
'viewData'=>array('x'=>''),
'itemView'=>'_classifieds',
'id'=>'boa_ads',
'itemsCssClass'=>'test'
));
This code will produce this HTML:
<div id="boa_ads" class="list-view">
<div class="summary">Displaying 1-4 of 4 results.</div>
<div class="items"><!-- HERE ID LIKE TO ADD AN ID-->
----ITEMS GOES HERE ----
</div>
</div>
</div>
Thanks for your help in advance
From the Yii's source:
public function renderItems()
{
echo CHtml::openTag($this->itemsTagName,array('class'=>$this->itemsCssClass))."\n";
.....
echo CHtml::closeTag($this->itemsTagName);
}
I just see class attribute is passed to the itemsTagName so you probably have to extend CListView to do it.
You can create a CCustomListView class (inside application/widgets folder) which extends from CListView and overwrite renderItems() function. For example:
<?php
Yii::import("zii.widgets.CListView");
class CCustomListView extends CListView
{
public $itemsHtmlOptions;
/**
* Renders the data item list.
*/
public function renderItems()
{
echo CHtml::openTag($this->itemsTagName, array_merge(array('class'=>$this->itemsCssClass), $this->itemsHtmlOptions))."\n";
$data=$this->dataProvider->getData();
if(($n=count($data))>0)
{
$owner=$this->getOwner();
$viewFile=$owner->getViewFile($this->itemView);
$j=0;
foreach($data as $i=>$item)
{
$data=$this->viewData;
$data['index']=$i;
$data['data']=$item;
$data['widget']=$this;
$owner->renderFile($viewFile,$data);
if($j++ < $n-1)
echo $this->separator;
}
}
else
$this->renderEmptyText();
echo CHtml::closeTag($this->itemsTagName);
}
}
In your view, you can use it like:
<?php $this->widget('application.widgets.CCustomListView', array(
'dataProvider'=> 'your_data_provider',
'itemsHtmlOptions' => array('style' => 'color:blue', 'id' => 'your_id'),
'itemView'=>'your_item_view',
'template'=>'your_template',
)); ?>
So the style which in itemsHtmlOptions will be applied for the listview.
This link is also useful for you: How to extend CListView in order to remove extra yii added markup?
I have a case where the UX/Designer laid out a form design that requires me to create the <form></form> tags on my own in the phtml template, rather than have Zend_Form automatically generate them due to some non input related markup I need to fill in.
How do you keep Zend_Form from rendering the form tags? I wrote the following override of the render function that could surely be improved upon, but I can't seem to do anything by manipulating the decorators.
public function render(Zend_View_Interface $view = null)
{
$content = parent::render($view);
$content = str_replace('</form>','',$content);
$idx = strpos($content,'>',4) + 1;
$content = substr($content,$idx);
return $content;
}
If I read your question correctly, the answer is quite simple:-
$form = new Zend_Form();
$text = new Zend_Form_Element_Text('text');
$text->setLabel('text');
$form->addElement($text);
$form->removeDecorator('form'); // the bit you are looking for :)
Zend_Debug::dump($form->render());
Gives the following output:-
<dl class="zend_form">
<dt id="text-label">
<label for="text" class="optional">text</label>
</dt>
<dd id="text-element">
<input type="text" name="text" id="text" value="">
</dd>
</dl>
ie no <form> tag rendered. I think that is what you need.
If you want to do this in every form automatically by extending Zend_Form then overiding the render() method as follows works:-
public function render(Zend_View_Interface $view = null)
{
$this->removeDecorator('form');
$content = parent::render($view);
return $content;
}
I imagine that's a more satisfactory solution for you than doing it seperately for each individual form.
You're looking for the Zend_Form_Decorator_Form within Zend_Form.
$form->setDecorators(array(
'Form',
array(array('tag' => 'HtmlTag'), array('tag' => '')),
));
should work.