Zend: ViewScript decorator and array notation - zend-framework

I have a matrix of checkboxes which I am laying out in a table. I need to pull this matrix into a number of forms, and sometimes multiple times on one form, so I have set it up as a subform.
After much research and deliberation, I decided the best way to decorate the subform was using the viewScript decorator. The code for adding the subform to the form looks something like this:
$this->addSubForm(new Test_Form_Connection_Config_Base(), 'user');
$this->user->setDecorators(array(
array('viewScript', array('viewScript' => '_forms/userConfig.phtml')),
'Description',
'FieldSet',
));
For the most part this works fine however the one problem I have is that I can't get array notation to work. Obviously this becomes a problem when I include the matrix more than once on a particular form.
I tried using setIsArray(true) however this had no effefct. It seems that I need to run the FormElements decorator to get the array notation, but this then gives me a duplicate set of fields on the page (rendered once by FormElements, and once by viewScript).
I could manually construct the name of each element to reflect array notation, but this seems like the long way around. Are there any other options that I'm missing?
Thanks...!

Before using the ViewScript decorator, you should always use the PrepareElements decorator to normalize names.
See http://framework.zend.com/manual/en/zend.form.standardDecorators.html#zend.form.standardDecorators.prepareElements

Related

How can I get the Zend_Form object via the Zend_Form_Element child

I've built a Zend_Form_Decorator_Input class which extends Zend_Form_Decorator_Abstract, so that I could customize my form inputs -- works great. I ran into a problem in the decorate class, in trying to get the form name of the element, so as to built a unique id for each field (in case there are multiple forms with identical field names).
There is no method like this: Zend_Form_Element::getForm(); It seems Zend_Form_Decorator_Abstract doesn't have this ability either. Any ideas?
I don't think changing the id from the decorator is the right approach. At the time the decorator is called the element already has been rendered. Thus changing the id would have no effect to the source code. Additionally, as you already have pointed out, the relation between a form and its elements is unidirectional, i.e. (to my best knowledge) there is no direct way to access the form from the element.
So far the bad news.
The good news is, that there actually is a pretty easy solution to your problem: The Zend_Form option elementsBelongTo. It prevents that the same ID is assigned to two form elements that have the same name but belong to different forms:
$form1 = new Zend_Form(array('elementsBelongTo' => 'form1'));
$form1->addElement('Text', 'text1');
$form2 = new Zend_Form(array('elementsBelongTo' => 'form2'));
$form2->addElement('Text', 'text1');
Although both forms have a text field named 'text1', they have different ids: 'form1-text1' and 'form2-text1'. However, there is a major drawback to this: This also changes the name elements in such a way that they are in the format formname[elementname]. Therefore $this->getRequest()->getParam('formname') will return an associative array containing the form elements.

Zend Form changing element type in controller

I have my Zend_Form, and sometimes, one of the fields should be hidden, and not seen by the user. Is there a way when I call the form in my controller, I could change one of the fields to be hidden?
Thanks
Kousha
You can remove the element using:
$form->removeElement('my-element-name');
in the controller.
You could also create two forms, one overriding the other, in which the child calls $this->remove('my-element-name').
Or, you could make the form constructor accept a boolean $flag that determines whether to add the field to the form.
So, as you can see, lots of different ways to structure it.
To change that field to one of type "hidden" (i.e. <input type="hidden">) is a different thing, but I'm not sure that's what you mean/need/want.
The best solution I have for this is to add a specific class to the element when it needs to be hidden. It may not be the perfect solution, but let me explain.
First, its very difficult to switch from one element type to another in Zend Form. Your elements are actually classes. So the text is Zend_Form_Element_Text - so its not just as easy as changing the 'type' attribute.
If the element must remain on the form (so, not removing it like the answer above suggests), your only other option would be hiding it with CSS.
Try the following code when it needs to be hidden:
$element = $form->getElement('MyElement');
$newClass = trim($element->getAttrib('class') . ' hidden');
$element->setAttrib('class', $newClass);
Then, of course, create CSS for the .hidden class.
Hope this helps!

Displaying Float on Input Forms

I'm fairly new to the CakePHP game and need some insight on how to resolve a seemingly simple issue. I've inherited a few internal websites at my new job that utilize the framework and am struggling to tackle this issue with Google alone.
What I have is a view that loads a form and populates it with data already in the database. There are three fields that have this behavior and all have the same issue.
The fields are declared as such on the View:
echo $this->Form->input('hotel_costs');
echo $this->Form->input('misc_costs');
Within the database they're declared as float DataTypes and therefore, when loaded to the browser will sometimes display as floats do: (15.7 becoming 15.699999999...)
Looking around it seems there are Helpers such as NumberHelper able to tackle my issue but I have no clue how to include the functionality with the form values. Am I looking in the wrong place entirely?
Thanks!
It has nothing to do with forcing the input type to text. Are you saying that you don't want the float's value in the field, but you want a rounded (to how many decimal places) number instead? It would have to apply across the board. Do you have a custom view or a baked one?
(I'd ask these as comments to your question, but my rep aint high enough.)
you can try to force input[type=text], so that cake doesn't try to guess input type.
$this->Form->input('hotel_costs', array(
'type' => 'text'
));
$this->Form->input('misc_costs', array(
'type' => 'text'
));
if this still doesn't work, post back with more details.
Which Controller Action(add/index/edit)?
Code of that action
var_dump() of data from the database

Zend framework form hash not working

I have a simple ZF form that includes a hash element:
$hash = new Zend_Form_Element_Hash('hash');
$hash->setSalt('hf823hflw03j');
$hash->addErrorMessage('Form must not be resubmitted');
This works ok, but if I choose to strip out all the decorators and format the form using :
$this->setDecorators( array( array('ViewScript', array('viewScript' => '_form_register.phtml'))));
Then it seems that the hash value is renewed each time it is submitted and thus doesn't work.
In addition, PHPunit thinks the form element hash is invalid and so doesn't test the form processing.
Is there any solution to this?
Do you really need to use viewScript Decorator? Otherwise try to use this:
$this->setDecorators(array('ViewHelper','Errors'));
If you want to change the look of the Errors, you could create your own ErrorDecorator and then use it as follows:
$this->setDecorators(array('ViewHelper', new My_ErrorDecorator()));

How do I get a regular Checkbox in a Zend Form?

I have a form in Zend_Form that needs some checkboxes and I'd like them to be regular old checkboxes. You know, you give em a name and a value. If they are checked your post data contains name=>value.
Zend_Form is generating two inputs fields. One, the checkbox with a value=1 and the second a hidden input with a value=2. Both have the same name. I understand in theory how Zend expects the checkbox to work, but that's not how I expect it to work and it's not how I want it to work. How do I get my old fashion HTML checkbox back?
I have tried using $this->createElement, $this->addElement and creating a Zend_Form_Element_Checkbox manually. None allow me to set the checkbox's value and all generate the hidden input.
The final and REALLY correct answer is to add an option to the element :
$this->addElement('checkbox', 'my_element', array(
'label' => 'My Element Label',
'name' => 'my_element_name',
'disableHidden' => true
));
Zend_Form_Element_MultiCheckbox is what you're looking for.
The standard Checkbox element is meant to represent "yes/no" scenarios.
You could extend Zend library and add your own custom form element to render it just like you expect it. I did it for having a date field and it worked just fine.
I wonder why that does not work for you. You can set the values to anything you want (setCheckedValue() and setUncheckedValue()). So the only difference to normal checkbox is
if (null == $this->_getParam('checkbox', null)) {
//vs.
if ($unchecked == $this->_getParam('checkbox')) {
What exactly are you trying to do?