I'm just starting to use Zend Framework and was following the quick start documentation for the latest version (1.11.10). Everything was going just fine, but when I placed the form code and ran the application, the form did not render. My code is exactly like http://framework.zend.com/manual/en/learning.quickstart.create-form.html
On the view, I can dump the form just fine with var_dump($this->form);
I've tried echo $this->form(), echo $this->form->render(), but nothing appeared... What could it be?
This problem can occur when Zend can't find the template file for an element. Look at following code:
$element->setDecorators(array(
array('ViewScript',
array(
'viewScript' => 'directory/_input.phtml'
)
)
));
The file _input.phtml must be in the right folder for this Controller. Otherwise Zend can't find the template for input and can't successfully render your element and will not show anything.
Make sure you pass the form to the view from the controller.
In your action handler:
$this->view->form = $my_form;
In your view:
echo $this->form;
I suspected that this was the cause of your problem because Zend Framework doesn't complain if you try to echo a parameter that doesn't exist. (i.e. echo $this->some_fake_parameter won't do anything)
Ok so i tried your code, and it worked for me no problem.
Here is everything:
Controller
<?php
class IndexController extends Zend_Controller_Action
{
public function myTestAction()
{
$form = new Form_Guestbook();
// ... processing logics
if($this->getRequest()->isPost())
{
if($form->isValid($this->getRequest()->getPost()))
{
var_dump($form->getValues());
}
}
$this->view->assign('form', $form);
}
}
Form
<?php
class Form_Guestbook extends Zend_Form
{
public function init()
{
// Set the method for the display form to POST
$this->setMethod('post');
// Add an email element
$this->createElement('text', 'email', array(
'label' => 'Your email address:',
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
'EmailAddress',
)
));
// Add the comment element
$this->addElement('textarea', 'comment', array(
'label' => 'Please Comment:',
'required' => true,
'validators' => array(
array('validator' => 'StringLength', 'options' => array(0, 20))
)
));
// Add a captcha
$this->addElement('captcha', 'captcha', array(
'label' => 'Please enter the 5 letters displayed below:',
'required' => true,
'captcha' => array(
'captcha' => 'Figlet',
'wordLen' => 5,
'timeout' => 300
)
));
// Add the submit button
$this->addElement('submit', 'submit', array(
'ignore' => true,
'label' => 'Sign Guestbook',
));
// And finally add some CSRF protection
$this->addElement('hash', 'csrf', array(
'ignore' => true,
));
}
}
?>
View
<?php echo $this->form->render(); ?>
can be seen on: http://yaconiello.com/index/my-test
If this isnt working for you, you may be having a configuration error.
I had a problem like that (exact same form, since it is eclipse example)
My problem was due to misunderstanding. Since I thought that I have to directly access to the view script. I entered in the browser something like: hostname/application/view/script/something.php
But in zend all accesses should be through public folder. You have to access to the view like this: hostname/app_name/public/guestbook
hope that would help you
Related
I have a form in which im using this element
$this->addElement('Select', 'parent', array(
'label' => 'Parent',
));
I want to set Multiple Options Which i do usually like this
$this->addElement('Select', 'parent', array(
'label' => 'Parent',
'multiOptions' => $profileTypes
));
Where $profileTypes is array
Now how can I do this in Controller?
My code in Controlller is
$form->parent->multiOptions($parent);
it throws error
exception 'Zend_Form_Element_Exception' with message 'Method
multiOptions does not exist'
What am I missing?
controller file
$profileTypes= array(''=>'Select',
'1'=>'test',
'2'=>'test',
'3'=>'test',
);
$objForm->addForm($profileTypes);
$this->view->objForm = $objForm;
form file
$objparent = $this->formElement('Select', 'parent');
$objparent->addMultiOptions($profileTypes);
view file
<?php echo $this->objForm->parent; ?>
try this one for use multiple option in zend framework
I want to disable the validation on one of the zend form element based on the input on another element on the same form. I need to achieve this using javascript/jquery. Something very common but very surprisingly couldn't find it over the internet.
e.g.
In the controller:
$oFormMassEdit = new Account_Form_Returns_Return();
$this->view->form = $oFormMassEdit;
In Account_Form_Returns_Return's constructor:
$oNoteElement = new Zend_Form_Element_Textarea('option', array(
'required' => true,
));
$this->addElemet($oNoteElement)
$oReasonElement = new Zend_Form_Element_Select('note', array(
'multiOptions' => array (
'return' => 'return',
'defect' => 'Kaput',
'other' => 'Anderer Grund'
),
'required' => true,
));
$this->addElement($oReasonElement);
$this->addDisplayGroup(array('note', 'option'), 'main', array('legend' => 'Retouren'));
$this->addElement('button','send', array(
'type' => 'submit',
'label' => 'Methode speichern',
));
and finally in the view,
<?= $this->form; ?>
Javascript can't (not in a sensible way) switch Zend_Form configuration. What you can do is changing the 'required' param for certain form fields on validation. For example; If you want to allow fieldTwo to be empty if fieldOne has 'desiredValue' as value you can achieve this using the following function in your form:
public function isValid($data) {
if('desiredValue' == $data['fieldOne'])) {
$this->getElement('fieldTwo')->setRequired(false);
}
return parent::isValid($data);
}
I'm working on my custom User module, which basically uses ZfcUser as the foundation. Since every application is different and requires different meta information about users I want this to be easily configurable using a config array.
In my module's global config file I define the custom form fields and in the Module's onBootstrap I extend the ZfcUser registration form using the init event of ZfcUser\Form\Register. So in short I want to do something like this:
$sharedEvents->attach('ZfcUser\Form\Register',
'init',
function($e) use ($sm)
{
/* #var $form \ZfcUser\Form\Register */
$form = $e->getTarget();
// Get relevant config
$config = $sm->get('config');
if ( array_key_exists('redev_user', $config) && is_array($config['redev_user']) )
{
if ( array_key_exists('custom_fields', $config['redev_user']) && is_array($config['redev_user']['custom_fields']) )
{
foreach ($config['redev_user']['custom_fields'] as $curCustomField)
{
$form->add($curCustomField);
}
}
}
[...]
In my config file I then define the custom form fields like this:
<?php
return array(
'redev_user' => array(
'custom_fields' => array(
// Custom fields which will be added to the registration form
array(
'name' => 'firstname',
'type' => 'text',
'options' => array(
'label' => 'First name',
),
),
I do the same thing for the validators; they are being defined in the config file and attached to the form elements in the onBootstrap.
This all works nice and dandy, except when I need a Doctrine form element. In my specific case I would like to use a DoctrineModule\Form\Element\ObjectSelect for the country selectbox. In my config this would look like this:
array(
'name' => 'country',
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'options' => array(
'label' => 'Country',
//'object_manager' => $sm->get('Doctrine\ORM\EntityManager'),
'target_class' => 'RedevUser\Entity\Country',
'property' => 'countryname',
'is_method' => false,
'find_method' => array(
'name' => 'findBy',
'params' => array(
'criteria' => array(),
'orderBy' => array('countryname' => 'ASC'),
),
),
),
),
Note the commented out line for the object_manager. The ObjectSelect element obviously needs the ObjectManager. The question is how do I inject the ObjectManager while rendering the form based on the config.
I was thinking to render the form element myself and then check if it's an instance of some interface or base class of DoctrineModule\Form\Element. However it turns out there is no such base class or interface. The only thing those elements have in common is that they have a getProxy. Right now my code in onBootstrap looks like this:
foreach ($config['redev_user']['custom_fields'] as $curCustomField)
{
$formElemFactory = $form->getFormFactory();
$elem = $formElemFactory->createElement($curCustomField);
if ($elem instanceof \DoctrineModule\Form\Element\ObjectSelect)
{
// Inject ObjectManager
$elem->getProxy()->setObjectmanager($sm->get('Doctrine\ORM\EntityManager'));
}
$form->add($elem);
}
But I don't really want to check for the different Doctrine form element types. Also it seems a bit dirty to do it like this. Any opinions or ideas of how to do this better/cleaner?
I´m developing an application using Zend Framework 2 and I use FormRow helper to render a label, the input and errors (if present) in a Form.
//within the view
echo $this->formRow($form->get('Name'));
When a user submits the form without filling the required input text field FormRow render´s it with the following error message:
<label>
<span>Name: </span>
<input class="input-error" type="text" value="" placeholder="Insert Name Here" name="Name">
</label>
<ul>
<li>Value is required and can't be empty</li>
</ul>
How can I set a class for the li tag to style it afterwards?
I know that I can echo the formElementErrors with the desired class attribute via..
<?php echo $this->formElementErrors($form->get("Name"), array('class' => "valuerequired", 'message' => "errortestmessage")); ?>
..but FormRow will still render the error message without the class.
Just for reference I´m setting the entity this way:
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'Name',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 100,
),
),
),
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
See the code of formElementErrors
Basically you could do something like:
$this->formElementErrors($elem)
->setMessageOpenFormat('<ul%s><li class="some-class">')
->setMessageSeparatorString('</li><li class="some-class">');
But that is quite unhandy...
The better solution would be to extend the Zend\Form\View\Helper\FormElementErrors by your own class and then register the view-helper formElementErrors to your class. So basically you'd have something like this:
namespace Mymodule\Form\View\Helper;
use Zend\Form\View\Helper\FormElementErrors as OriginalFormElementErrors;
class FormElementErrors extends OriginalFormElementErrors
{
protected $messageCloseString = '</li></ul>';
protected $messageOpenFormat = '<ul%s><li class="some-class">';
protected $messageSeparatorString = '</li><li class="some-class">';
}
Last thing then would be to register the view helper with this new Class. For this you provide the following code inside your Modules Module.php
public function getViewHelperConfig()
{
return array(
'invokables' => array(
'formelementerrors' => 'Mymodule\Form\View\Helper\FormElementErrors'
),
);
}
displaimer: This code isn't tested, let me know if there are some errors, but i think this should work out quite well.
Ok, the solution to my own problem was right in front of me, instead of using:
//within the view
echo $this->formRow($form->get('Name'));
I called each element of the form individually:
//within the view
echo $this->formLabel($form->get('Name'));
echo $this->formInput($form->get('Name'));
echo $this->formElementErrors($form->get("Name"), array('class' => "some_class", 'message' => "errormessage"));
Don´t know if it´s the most efficient way of doing it, plz drop a line if you think otherwise.
FormRow check if "form_element_errors" plugin registered. And if so use it as default to display error messages.
So Sam's example work. You should redefine standard plugin and inform mvc about it.
I'v done it in module.config.php
'view_helpers' => array(
'invokables' => array(
'formElementErrors'=> 'MyModule\View\Helper\FormElementErrors',
and FormRow start display errors as I wish :)
As your problem, please try
Change
//within the view
echo $this->formRow($form->get('Name'));
to
//within the view
echo $this->formRow($form->get('Name'),null,false);
// Note: add more 2 last parameters, false- for $renderErrors => will NOT render Errors Message.
//Look original function in helper/formrow.php: function __invoke(ElementInterface $element = null, $labelPosition = null, $renderErrors = null, $partial = null)
Render Errors Message as your funciton
echo $this->formElementErrors($form->get('name'), array('class' => 'your-class-here'));
From the documentation of ZF2. Here's the link: http://framework.zend.com/manual/2.0/en/modules/zend.form.view.helpers.html#formelementerrors
echo $this->formElementErrors($element, array('class' => 'help-inline'));
// <ul class="help-inline"><li>Value is required and can't be empty</li></ul>
I use echo $this->formElementErrors($form, array('class' => "error-messages")); to show all error messages in one place:
echo $this->formElementErrors($form, array('class' => "error-messages"));// Print all error messagess
echo $this->formLabel($form->get('Name'));
echo $this->formInput($form->get('Name'));
echo $this->formLabel($form->get('Name2'));
echo $this->formInput($form->get('Name2'));
I have a little experience with Zend Framework, but I like to fiddle with it until it works.
But now I cannot resolve this problem.
I have a form:
<?php
class Application_Form_Login extends Zend_Form
{
protected $notEmpty;
public function init()
{
// Create NotEmpty validator
$notEmpty = new Zend_Validate_NotEmpty();
// Configure validators for username element
$notEmpty->setMessage('Gelieve dit veld in te vullen');
$this->setMethod('post');
// emailAddress
$this->addElement('text', 'emailAddress', array(
'filters' => array('StringTrim', 'StringToLower'),
'required' => true,
'validators' => array(
array('validator' => $notEmpty),
),
'label' => 'Emailadres:'
));
// password
$this->addElement('password', 'password', array(
'filters' => array('StringTrim'),
'required' => true,
'validators' => array(
array('validator' => $notEmpty),
),
'label' => 'Wachtwoord:'
));
// submit
$this->addElement('submit', 'submit', array(
'ignore' => true,
'label' => 'Inloggen'
));
}
}
A view:
<?= $this->form ?>
<?= $this->postdata ?>
And a AccountController:
<?php
class AccountController extends Zend_Controller_Action
{
public function init()
{
echo 'data:'.$this->getRequest()->getPost('emailAddress');
/* Initialize action controller here */
}
public function indexAction()
{
$this->view->postdata = var_dump($this->getRequest()->getParams());
$form = new Application_Form_Login();
$request = $this->getRequest();
if ($request->isPost()){
// THIS POINT IS NEVER REACHED
if ($form->isValid($request->getPost())){
if ($this->_isValidLogin($form->getValues())){
// Succes Redirect to the home page
$this->_helper->redirector('index', 'home');
}
else // Not succes Redirect to account page
{
$this->_helper->redirector('index', 'account');
}
}
As you see I put in a comment: // THIS POINT IS NEVER REACHED.
There are more functions in this controller, but those are not relevant for my problem.
Let explain it a bit more.
The very strange behavior is that when I put data in my fields, $this->view->postdata = var_dump($this->getRequest()->getParams() returns no POST data.
But when I put notting in the login form fields, then I see the POST data. Of course it is empty.
Like this:
array
'controller' => string 'account' (length=7)
'action' => string 'index' (length=5)
'module' => string 'default' (length=7)
'emailAddress' => string '' (length=0)
'password' => string '' (length=0)
'submit' => string 'Inloggen' (length=8)
Thus, //THIS POINT IS NEVER REACHED is actually reached when putting no data in the login form fields :-)
The question is, what are I am doing wrong? Do I deal with the Zend_Controller_Request_Http in the wrong way?
If you need more info, I should give it.
Typing down the problem gives new insights!
The problem is in my own code. On some point I redirect to the same page. A redirect means that the $_POST data is also cleared. Those data does - of course - not go with the new page request.
So if someone encounter this problem with Zend Framework, namely you get no POST or GET data on submit of your form, then you need to check your redirects.