Zend_Dojo and ValidationTextBox - invalid message does not always appear - zend-framework

I am using Dojo ValidationTextBox through Zend Framework in the following way:
$form->addElement('ValidationTextBox', 'procedureName', array(
'label' => _('Procedure Name'),
'value' => $alarm->procedureName,
'attribs' => array(
'required' => true,
'invalidMessage' => 'Required!'
)
));
Likewise, my form validation is set up in this way:
if (formWidget.isValid()) {
return true;
} else {
alert('Invalid form.');
return false;
}
Form validation will prevent the form from submitting if "procedureName" text box is blank, but Dojo will not mark the form element as invalid, nor display the "Required!" message. In fact, it will mark the form element only if I click it previously (but still, will not display the invalid message).
How can I reconstruct the behavior from this page, where you can click the submit button without clicking on any of required fields previously, and Dojo will mark all required fields?
Thanks.

Dojo allows both declarative and programmatic usage of many of its features.
Declarative usage uses standard HTML elements with non-standard attributes that are parsed when the page is loaded. Can cause issues so Zend Framework uses programmatic usage by default; the various view helpers will generate javascript and push it to the dojo() view helper for inclusion when rendered.
To specify declarative usage, simply call the static setUseDeclarative() method:
Zend_Dojo_View_Helper_Dojo::setUseDeclarative();
When in your form initialization.
This will allow any non standard options like "required" = "true" to be included in your input tag.
dojox.validate function will then work.
I use
<script type="dojo/method" event="onSubmit">
if (this.validate()) {
//return confirm('Form is valid, press OK to submit');
} else {
//alert('Form contains invalid data. Please correct first');
return false;
}
return true;
</script>
inside my form tags as my validation setup.

The error was that I should've used formWidget.validate(), instead of formWidget.isValid().

Related

Symfony 2 Forms - add new item to Collection server-side, depending on button clicked

I have a form which contains a Collection of an unspecified number of subforms. I want to have functionality allowing the user to add a new, blank item to the Collection for them to fill in. The Symfony docs tell us how to do this using Javascript clientside to add new blank form controls, which are then submitted and persisted as normal, but I'd like to do it serverside in the controller, without Javascript.
The problem I'm encountering is to do with the way Symfony Forms work. I have an "Add" button added to my main form, and I intend to detect whether it is that button which has been clicked, so that I can add the blank item to the Collection and re-render the form. But to detect the click I need to call $this->createForm and at that point the form is fixed with the original set of items, it's too late to add an extra one.
//Symfony Action
//A Person has many Selections
$person = $this->getPerson($id)
//All fields are frozen at this point, according to data in $person!
$form = $this->createForm(new SelectionsType($lookups), $person);
$form->handleRequest($request);
//Ideally I'd somehow do this test earlier, but I need $form to do it...
if ($form->get('add')->isClicked() )
{
//TOO LATE!
$person->getSelections()->add(new Selection() );
}
if ($form->isValid())
{
if ($form->get('save')->isClicked() )
{
//Persist
}
}
//Render page etc
Things I've thought about:
Putting the Add button in a completely different form on the same page, which submits to a different Action which can then do some preparatory work before forwarding to the main Action above
Inspecting submitted HTTP data directly to note that Add has been clicked (shame not to use the standard Symfony method)
Give up and use Javascript as suggested (it might work in this example, but I'd like to have the option of carrying out server-side activity (without AJAX...) as part of adding the new blank item)
How can I best achieve this in a proper Symfony way?
EDIT Just seen this: https://github.com/symfony/symfony/issues/5231, which is essentially a feature request to allow what I'm after. One suggestion a commenter makes is to add a blank item to the Collection and then remove it if it's not needed - I don't know how one would do that, but it sounds promising.
ANOTHER EDIT It occurs to me that, because I need two different aspects of the $form I'm creating, I could maybe just make the $form, use it to handle the request, detect the button click, and then throw that $form away, before altering my model and creating another $form. I don't know if that would somehow fall foul of some rules about handling the submission twice.
I'm not 100% but I think you could do the following...
//Symfony Action with (Request $request, ...)
//A Person has many Selections
$person = $this->getPerson($id)
//All fields are frozen at this point, according to data in $person!
$form = $this->createForm(new SelectionsType($lookups), $person);
if ($request->isMethod('POST')) {
$form->submit($request);
if ($form->get('add')->isClicked()) {
// Add thing
} elseif ($form->isValid()) {
// or
// } elseif ($form->get('save')->isClicked() && $form->isValid()) {
// Persist and what not
}
}
//Render page etc
I haven't tested it so I don't know whether it will trigger the form errors (or if it will actually work) so if it does (or it doesn't) I apologise.
What I did in the end was have my Add button hit a separate Action, which then delegates to the main action with a flag to say "add a new Selection", as below:
public function selectionsAddAction(Request $request, $id)
{
return $this->selectionsAction($request, $id, true);
}
public function selectionsAction(Request $request, $id, $addNew = false)
{
$person = $this->getPerson($id);
//Also use "add mode" if we just deleted the last one!
if (!$person->getSelections()->count())
{
$addNew = true;
}
//$addNew is set by a separate action, hit by a different form with the Add button in
if ($addNew)
{
$person->getSelections()->add(new Selection() );
}
//We now have the right number of items, and can build the form!
$form = $this->createForm(new SelectionsType($lookups), $person);
//...
}

Zend Framework 2 Translating the text of the radio buttons

I´m developing an application using Zend Framework 2 and I need to translate the text of the radio buttons ("Show", "Hide") that I´ve created in my form:
//within the Form
public function addRadioButtons ()
{
$isPublicRadioButtons = new Element\Radio('isPublic');
$isPublicRadioButtons->setAttribute('id', 'isPublic')
->setAttribute('value', '0')
->setValueOptions(array(
'0' => 'Show',
'1' => 'Hide',
));
$this->add($isPublicRadioButtons);
}
What do I have to do in the view side to be able to translate them?
I know that to render translations to the views I need to use $this→translate() view helper. So within the view I´ll have to somehow call the text of the radio buttons..
//Whithin the view
echo $this->translate($someHowCallTheTextOfRadioButton('isPublic') , $textDomain, $locale);
Look at FormLabel section to read about translating labels in zend framework 2. I think that most important thing to remember is:
If you have a translator in the Service Manager under the key,
‘translator’, the view helper plugin manager will automatically attach
the translator to the FormLabel view helper. See
Zend\View\HelperPluginManager::injectTranslator() for more
information.
How to properly setup translator you have in ZendSkeletonApplication
In your view you can do something like this:
$this->formRadio()->setTranslatorTextDomain('textdomainhere');
You can have your form implement the TranslatorAwareInterface and, if you are using PHP 5.4+, have it use the TranslatorAwareTrait (otherwise you simply have to implement the interface yourself). You can now inject a translator instance into your form, e.g. in the form's factory. Then you can translate the labels as follows:
//within the Form
public function addRadioButtons ()
{
$isPublicRadioButtons = new Element\Radio('isPublic');
$isPublicRadioButtons->setAttribute('id', 'isPublic')
->setAttribute('value', '0')
->setValueOptions(array(
'0' => $this->getTranslator()->translate('Show'),
'1' => $this->getTranslator()->translate('Hide'),
));
$this->add($isPublicRadioButtons);
}

adding Zend_Form_Element_Captcha to form causes form to not display

I am having trouble getting a captcha element to display in a signup form. It was working previously, but now for some reason when I try to add the captcha element to the form the entire form does not display.
Below is the function in my controller file to create the form
private function getSignupForm()
{
// create form
$form = new Zend_Form();
$form->setAction('success');
$form->setMethod('post');
$form->setAttrib('sitename', 'loudbite');
// add elements
require "form/elements.php";
$loudbiteElements = new Elements();
// create username field
$form->addElement($loudbiteElements->getUsernameTextField());
// create email field
$form->addElement($loudbiteElements->getEmailTextField());
// create password field
$form->addElement($loudbiteElements->getPasswordTextField());
// add captcha
$form->addElement($loudbiteElements->getCaptcha());
// create submit button
$form->addElement('submit', 'submit');
$submitElement = $form->getElement('submit');
$submitElement->setLabel('Create My Account!');
return $form;
}
and here is the action to pass the form to the corresponding view
public function newAction()
{
// get the form
$form = $this->getSignupForm();
// add the form to the view
$this->view->form = $form;
}
If I comment out the line in my getSignupForm() function where I add the captcha to the form then the form will display ok minus the captcha element. This leads me to assume that there is a problem with the captcha contruction.
Below is the function in an external model file where the captcha is constructed
public function getCaptcha()
{
$captchaElement = new Zend_Form_Element_Captcha(
'signup',
array('captcha' => array(
'captcha' => 'Figlet',
'wordLen' => 6,
'timeout' => 600))
);
$captchaElement->setLabel('Please type in the words below to continue:');
return $captchaElement;
}
All the other form elements are created in this external model file. Based on the fact that the other elements display correctly if I do not add the captcha element, I assume it is not a problem with accessing the model file.
The last time I used this signup form everything was working ok! And I don't remember having changed anything between then and now.
Any help is greatly appreciated.
Regards
Roan

Symfony2: get rid of "This form should not contain extra fields"

I have added a second submit button to my form, now Symfony2 complains about it: "This form should not contain extra fields"
Although I added this option in the formtype:
public function getDefaultOptions(array $options)
{
return array(
'csrf_protection' => false,
);
}
Any ideas?
You can most certainly have multiple submit buttons. Make sure the button is not in the same array as the other form fields.
So, for example, if your form fields have a name FormType[field_name], you can't have FormType[submit_btn] as the name of the button and you must choose a different one.
Your controller can act differently depending on the button pressed. If your submit buttons are named submit_1 and submit_2 you can have something similar to
if($this->getRequest()->request->has('submit_1')) {
// do stuff
} else {
// do other stuff
}

How to submit a Zend Dojo subForm

I have spent hours on the net to find a solution, but nothing works.
I have a form divided into 2 subForms (I couldn't get the accordion pane to work)
like this :
$sfBase = new Zend_Dojo_Form_SubForm('base_info');
$sfBase->setName('base_info')
->setAction('/product/add?f=1');
$id = new Zend_Form_Element_Hidden('id');
$id->addFilter('Int')
->setAttrib('style', 'display:none');
$nom = new Zend_Dojo_Form_Element_TextBox('name');
$nom->setLabel('Nom du produit')
->setTrim(true)
->setValue("Entrez le nom")
->setPropercase(true);
$sdesc = new Zend_Dojo_Form_Element_TextBox('sdesc');
$sdesc->setLabel('Courte description du produit')
->setTrim(true)
->setValue("Description")
->setPropercase(true);
$sfBase->addElements(array($id, $nom, $sdesc);
$submitSubBase = new Zend_Dojo_Form_Element_SubmitButton('sub1');
$submitSubBase->setLabel('ok');
$sfBase->addElement($submitSubBase);
and another subform which contains few other elements :
$sfComp = new Zend_Dojo_Form_SubForm('comp_info');
$sfComp->setName('comp_info')
->setAction('/product/add?f=2');
...
$submitSubComp = new Zend_Dojo_Form_Element_SubmitButton('sub2');
$submitSubComp->setLabel('envoyer');
$sfComp->addElement($submitSubComp);
$this->addSubForms(array('base_info' => $sfBase,
'comp_info' => $sfComp
));
In my controller I display the entire instanciated form :
$this->view->base = $form;
but whenever I click on a submit button nothing happens. I tried placing a single submit button added to the form (not to a subForm)
with setAction :
$baseForm->setAction($this->view->url(
array('controller' => 'Product', 'action' => 'add', 'id' => '1'), 'default',
true));
but it is the same, finally I divided the form into two distinct Zend_Form instead of subforms, but that is not very clean...
So having tried multi page forms, subForms and dojo containers unsuccessfully I don't know what to do, and any help would be welcome !
thank you
I don't know if this will help at all but here is my answer.
If the MAIN form is not Dojo enabled, have you called Zend_Dojo::enableForm() in the init method? Is the MAIN form extending frorm Zend_Dojo_Form? If it's extending from Zend_Dojo_Form then you don't have to call Zend_Dojo::enableForm().
The Dojo forms submit through the use of javascript. You should have some javascript on the client side that can handle the responses from the server that will come back. If you don't have javascript on the client side to handle these returns, then you won't 'see' the results of the submit.
Try this, write some javascript using the dojo toolkit that will create an alert box when it receives something from the server. This way, if you click on the submit button and an alert box comes up you'll know that the form was submitted.