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);
}
Related
I'm having trouble formulating a solution for 'editing' a field of my form in my controller.
Here's what I have:
I have a symfony2 form registered as a service that I call in a function in my controller. I am removing a bunch of fields that aren't necessary for this other form I am directing my users to and then adding a few others.
(I realize I could create another form and create another service and such but for my purpose this would be a bit overkill. I'm doing it this way because the form functions the same, however some fields are not needed and a few new specific ones are.)
I would now like to essentially 'edit' one field in this form... The 'occupation' field. This field is a choice field acting as radio buttons populated by an array of choices. It's required and has no empty_value requirement in its original state.
I would like to edit it in my controller function to have the same exact values however with a required value of false and an empty_value of null.
With the commented out code below the result is a dissapearance of the occupation field in my 'new' form and it is replaced by an empty drop down. I realize it's because I'm overriding the whole field below, but I cannot figure out how to simply edit it.
Code:
/**
* Explanation of addAndRemoveFieldsInRegisterForm function:
* The function gets the 'registration' form and removes any
* fields not needed for the 'in_registration' form
* and then adds the necessary fields to the form.
*/
private function addAndRemoveFieldsInRegisterForm($user)
{
$form = $this->createForm('user_registration', $user);
// http://stackoverflow.com/questions/10920006/pass-custom-options-to-a-symfony2-form ---
// --- use that to help. Look at changing the value of array.
$form->remove('title');
$form->remove('company');
$form->remove('username');
$form->remove('city');
$form->remove('state');
$form->remove('country');
$form->remove('gender');
$form->remove('age');
$form->remove('roles');
// $form->remove('occupation');
// $pr = $form->get('occupation');
// $pr->set('required' => false);
// $form->get('occupation')->add('required'=>false, 'empty_value'=>null);
// $form->add('occupation','choice', array(
// 'required' => false,
// 'empty_value' => null,
// ));
// echo "<pre>";
// var_dump(get_class_methods($form));die;
$form->add('occupation','choice', array(
'required' => false,
'empty_value' => null,
));
$form->add('canEmail', 'checkbox', array(
'label' => 'Can Email?',
'required' => false,
));
$form->add('sendEmail', 'choice', array(
'label' => 'Send Welcome Email? ',
'required' => true,
'mapped' => false,
'expanded' => true,
'choices' => array(
"yes" => "Yes",
"no" => "No"
),
));
return $form;
}
Original Form (the one that's used as a service)
private $requireOccupation;
$this->requireOccupation = true;
->add('occupation','choice', $options['occupation'])
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$occupation = array(
"label" => "Which of these currently describes you best? (Occupation):",
"expanded" => true,
'required'=> $this->requireOccupation,
"choices" => array(
"X" => "X",
"B" => "B",
"C" => "C",
"J" => "J",
),
'constraints' => array(
new NotBlank()
));
$resolver->setDefaults(array(
'occupation' => $occupation,
));
}
I think it is better to create another form. It can herit from your already defined form to change only the field you want
class SomeFormType extends OriginalFormType {
public function buildForm(FormBuilderInterface $builder, array $options) {
parent::buildForm($builder, $options);
$builder
->remove('someField')
->add('someField', 'choice', [
"expanded" => true,
"choices" => $yourArray
]);
}
It has the advantage to be mapped on different object
Firstly, I realize the way I wanted to solve this issue is odd when considering I could have created another form with either the fields I wanted to use or just the one field that needed to change and register the form as a service to use it elsewhere, but I was tasked to complete it this way.
Second, my solution is quite simple. I pass values into my form with a default value set in the form.
In the form:
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$requireOccupation = true;
$emptyValue = null;
//whatever other values you want to set here
$resolver->setDefaults(array(
'requireOccupation' => $requireOccupation,
'emptyValue' => $emptyValue,
));
}
and then on the field's properties:
$builder->add('occupation', 'choice', array(
"label" => "Some sort of label",
"required" => $options['requireOccupation'],
"empty_value" => $options['emptyValue'],
...
));
Now in the controller:
$form = $this->createForm('registration', $user, array(
'requireOccupation' => false, 'emptyValue' => null
));
call that where you want to generate your form while passing in the values you want to use for that form.
I am by no means an expert on Symfony and this solution would probably generate some issue with those who are. But it works for me.
I've managed to create a multi-checkbox using Zend\Form. Now I have to create a "parent" checkbox. The expected result is quite close from this:
The "Parent 1" action will be to check all childs. This task will be done by JQuery (I guess), but is there a way to generate this pattern using ZF2 form? Or should I manually create the "parent" checkbox with JQuery too (which is quite ugly in my opinion)?
My code for "single level" multi-box:
Controller action:
public function addAction()
{
$form = new RoleForm();
$formattedRights = getStuffFromDb();
$form->get('rights')->setAttribute('options', $formattedRights);
return array(
'form' => $form,
);
}
Zend Form:
...
$this->add(array(
'type' => 'Zend\Form\Element\MultiCheckbox',
'name' => 'rights',
'options' => array(
'label' => 'Associated rights',
)
));
...
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 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
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.