Zend_Form - How to addValidator after the form has been submitted - zend-framework

I have 2 text fields in my form.
TextFieldA - not required
TextFieldB - not required
After user submitted the form,
How to add validator / setRequired(true) to TextFieldB if the value of TextFielA is not empty?

I see two approaches in addition to #Marcin's idea.
Conditionally call setRequired() on the relevant elements by creating a preValidate() method on the form and calling it in your controller. [Really the same idea as #Marcin, but pushed down into the form itself, keeping the controller a bit leaner.]
Create a custom validator called something like ConditionallyRequired that accepts as an option the fieldname of the "other field". Then attach this validator to each element, configuring it with the name of the "other" element. Then in the validator's isValid($value, $context) method, conditionally test $value if $context['otherfield'] is non-empty.

You could do as follows:
if ($this->getRequest()->isPost()) {
$textFieldA = $yourForm->getElement('TextFieldA');
$textFieldB = $yourForm->getElement('TextFieldB');
if (!empty($_POST['TextFieldA'])) {
$textFieldB->setRequired(true);
}
if (!empty($_POST['TextFieldB'])) {
$textFieldA->setRequired(true);
}
if ($mainForm->isValid($_POST)) {
// process the form
}
}
Basically, you add the validators after the post, but before the form is validated.
Hope this helps.

Related

how do you get a variable from a post address in zendframework 1

I am still new to Zend Framework and confused about a few concepts.
I have built a POST form and attached a unique Id to the URL at the end of the form. I now want to collect that Id when the form is submitted but I am unclear how to do that
I will show you want I have done:
Below is the function that renders the form from my controller page to the view. You will note that I have fed into the parameter, for the form, a return Action address with the ID
$action = "{$this->view->baseUrl()}/sample-manager/process-price/{$sampleId}";
$this->view->Form = $model= $this->_model->createForm($action);
The function to receive the post is below. However, I want to collect the Id that should have come back with the post return values, but I have no idea where to find it or how to attach it.
public function processPriceAction()
{
$this->requirePost();
if($this->_model->processTieredPriceForm($this->view->form, $this->getRequest()->getPost()))
{
$this->_helper->FlashMessenger('Changes saved');
return $this->_redirect("/product-ecommerce/{$this->_model->getProduct()->id}");
}
else
{
return $this->render('index');
}
}
In summary, when a post is returned, does the return address come with the post in Zend Framework?
Could you not supply the id into the construction of the form and assign it to a hidden element? For example, in your controller:
$action = "{$this->view->baseUrl()}/sample-manager/process-price";
$this->view->Form = $model= $this->_model->createForm($action, $sampleId);
In your form model (not provided so best guess here):
$sampleId = new Zend_Form_Element_Hidden('sampleId');
$sampleId->setValue($sampleId);
$form->addElement($sampleId);
Then once the form is posted, you should be able to get the sample id in your controller in the standard way:
$sampleId = $this->getParam('sampleId');
The answer depends a bit on how your routing is setup. If you're using the default setup, after the action name the default route allows for key/value pairs of additional data. So, you might have more luck with a URL like this:
{$this->view->baseUrl()}/sample-manager/process-price/id/{$sampleId}
That'll put your sampleId in a named parameter called 'id', which you can access in your controller action with $this->_getParam('id').

grails: custom validation of just one field/property

I have a "Thing" domain class, where each Thing has an record number (which is not the automatically generated id), that the user will use to access a Thing:
class Thing {
...
String recordNumber
...
}
There is a form to look for a Thing, knowing its recordNumber:
<g:form action="search">
<input name="recordNumber">
<g:submitButton name="btn" value="go to this Thing"/>
</g:form>
I would like to use a validation process in this form: if the recordNumber is not found (Thing.findByRecordNumber(recordNumber) == null), then the input field must turn in red, and a tooltip must show the error message "record number not found".
As far as I know/read (I'm a grails rookie), this has to be written as a constraint in the Thing class:
static constraints = {
recordNumber validator: { n -> Thing.findByRecordNumber(recordNumber) }
}
The problem is: I do not have in this form all the "Thing" properties to populate, just the recordNumber one, so I just can't call
new Thing(params).validate()
How to call validation on just one field, not on the whole object ?
If this is your main question, although I see others there:
"How to call validation on just one field, not on the whole object ?"
You can pass a list of values to validate and it will only validate those properties
new Thing(params).validate(["recordNumber"])
http://grails.org/doc/latest/ref/Domain%20Classes/validate.html
Validation is for constraints for domain class properties. You need an action in your controller:
def search = {
if(params.recordNumber && Thing.findByRecordNumber(params.recordNumber)){
redirect(action: "show", params:[id:Thing.findByRecordNumber(params.recordNumber).id])
}else{
flush.message = "No record found"
render(view:'VIEW_WITH_SEARCH_FORM')
}
}
If you want to validate without refreshing page, write a javascript code.

Symfony2 - Multiple forms in one action

I implemented a page to create an instance of an entity and a user related to this. My problem is to bind the request after the submit.
Now i have this :
$formA = $this->createForm(new \MyApp\ABundle\Form\AddObjectForm());
$formB = $this->createForm(new \MyApp\UserBundle\Form\AddUserForm());
if ($request->getMethod() == 'POST')
{
$formA->bindRequest($request);
$formB->bindRequest($request);
if ($formA->isValid() && $formB->isValid())
{
}
// ...
}
With formA and formB extends AbstractType. But, naturally, $formA->isValid() returns false. How can I do to "cut" the request for example ?
If your forms are related and need to be processed and validated at once, consider using embedded forms. Otherwise, use a separate action for each form.
If you need to provide a select field to choose a user from existing ones, consider using an entity type field.
I know that has been a long time since the answer, but maybe if someone is looking for it this could be helpfull.
I've got two forms: user_form and company_form, and the submit has take place in the same function of the controller. I can know wich form has been submit with the follow code:
if ($request->getMethod() == 'POST') {
$data = $request->request->all();
if (isset($data['user_form'])) //This if means that the user_form has been submit.
{
The company_form will pass through the else.

Zend Form MutliCheckbox Validate Number of Checked Items

I have a Zend Form with a MutliCheckbox element.
I would like to validate the number of checked items, i.e. verify that exactly 3 items are checked.
Can I do it with any current validates or do I have to write my own?
Thanks.
You will have to write your own, but that's quite simple. There is a second optional argument on the isValid() method that gives you access to all the form values, and enables this way to validate against multiple inputs.
class MyValidator extends Zend_Validate_Abstract {
public function isValid($value, $formData = null){
//you can access to all the form values in the $formData, and check/count
//the values of your multicheckbox
//this is the super-quick way, but you could also add error messages
return $isValid;
}
}
and then add it to your element
$myElement->addValidator( new MyValidator());

Zend Avoid submit button value in GET parameters in url

I have a form, created with Zend_Form, with method = GET used for searching records with elements as below:
[form]
user name [input type="text" name="uname"]
[input type="submit" value="Search" name="search"]
[/form]
After form is submitted all the GET parameters along with submit button value are appearing in the url.
http://mysite.com/users/search?uname=abc&search=Search
How to avoid submit button value appearing in the url? is custom routing the solution ?
When you create your element, you can simply remove the name attribute that was automatically set at creation
$submit = new Zend_Form_Element_Submit('search')->setAttrib('name', '');
Or inside a Zend_Form
// Input element
$submit = $this->createElement('submit', 'search')->setAttrib('name', '');
// Or Button element
$submit = $this->createElement('button', 'search')->setAttribs(array
(
'name' => '', 'type' => 'submit',
);
When a form gets submitted, all of its elements with their names and values become a part of a GET / POST - query.
So, if you don't want an element to appear in your GET - query, all you need to do is to create this element without a name. That's probably not the best approach, but since we're talking about the 'submit' element, I guess it doesn't matter that much.
Looking at Zend_View_Helper_FormSubmit helper, you can see that it's creating the 'submit' element and setting its name. So, the possible solution would be to create your own view helper and use it for rendering the 'submit' element instead of the default helper.
You can set a custom helper with
$element->setAttribs( array('helper' => 'My_Helper_FormSubmit') );
Then build your own form element class and remove the name attribute from the element with preg_replace. The beauty of it is, it will not interfere with the other decorators.
So the something like this:
class My_Button extends Zend_Form_Element_Submit
{
public function render()
{
return preg_replace('/(<input.*?)( name="[^"]*")([^>]*>)/', "$1$3", parent::render(), 1);
}
}
You can remove name attribute for submit button in javascript.
jQuery example:
$('input[name="submit"]').removeAttr('name');
In the controller that represents the form's action, redirect to another (or the same controller) only including the relevant params.
Pseudocode:
$params = $this->getRequest()->getParams();
if isset($params['search'])
unset($params['search']);
return $this->_helper->Redirector->setGotoSimple('thisAction', null, null, $params);
handle form here
This is basically the same idea as Post/Redirect/Get except that you want to modify the request (by unsetting a parameter) in between the different stages, instead of doing something persistent (the images on that Wiki-page shows inserting data into a database).
If I were you, I would leave it in. IMO it's not worth an extra request to the webserver.