How to create elements in Zend Form with array names - arrays

I am trying to create a very complex form with ZF2, and I can't find a solution to implement array based names in input elements.
This is a chunck of code from my actual form:
<input type=text name=table[name] value="Table Name">
<input type=text name=table[title] value="Table Title">
<input type=text name=table[columns][names][] value="Column Name 1">
<input type=text name=table[columns][names][] value="Column Name 2">
<input type=text name=table[columns][names][] value="Column Name 3">
<input type=text name=table[columns][labels][] value="Column Label 1">
<input type=text name=table[columns][labels][] value="Column Label 2">
<input type=text name=table[columns][labels][] value="Column Label 3">
I know how to work with Zend/Form, but this is an advanced usaged I can`t master.

Your code looks like a dynamic form rendered into table format. One possibility besides Zend Fieldsets is to generate your basic form structure dynamically wihtin OOP-Constructor, like #Sam said.
In your case, you should have a concept of which the form is structured. E.g. you have an array with data from a database, which gives you for example the number and names of your "columns" and so the structure how to build your dynamic form.
Following example uses Zend Form constructor to generate a dynamic form. Number of columns are dynamic and specified by given array $tableColumns
<?php
class DynamicForm extends Form {
/**
* This constructor builds a Zend Form dynamically
*
* #param array $tableColumns Dynamic data e.g. 'Column Name 1'
*/
public function __construct($tableColumns) {
// Add table name input
$this->add(array(
'type' => 'text',
'name' => 'name'
));
// Add table title input
$this->add(array(
'type' => 'text',
'name' => 'title'
));
// iterate each dynamic data
foreach($tableColumns as $column) {
$this->add(array(
'type' => 'text',
'name' => $column['name']
));
}
}
}
This is how you generate the Zend form structure. Rendering works similar, but within yout view code.
<?php
echo "<table>";
echo "<tr>";
echo "<td>". $this->formElement($form->get('name')) . "</td>";
echo "<td>". $this->formElement($form->get('title')) . "</td>";
foreach($tableColumns as $column) {
echo "<td>". $this->formElement($column) ."</td>";
}
echo "</tr>";
echo "</table>";
?>
In my opinion it is much more comfortable to render a form dynamically into a table format, than it's possible a Fieldset.
But nevertheless Zend Form Collection (e.g. Fieldsets) is a good choice, if you have to add or remove Form-elements dynamically with Javascript and handle your form data also highly dynamically.
More information about Zend From Collections are described at the ZF2 Reference Manual

You make use of Zend\Form\Element\Fieldset for this kind of scenario. It helps a great deal with proper OOP-Construction of Forms.

Related

Cakephp 3 Automatically set values to a user defined form

I am able add/edit/delete with a form created using Cakephp FormHelper.
But I want to use my own form without html helper. And it is a big form. In edit, I set an entity to view. I gave names to elements same as column names.
But the values are not set.
The view is in a plugin.
Can anybody please tell me how to automatically set values in a user-defined form.
I have created a form tag in the form as follows, hoping that "context" will be set and values will appear
<?php echo $this->Form->create( $company ); ?>
and also end , end of the form.
<?php echo $this->Form->end(); ?>
In between the form tags there are many html form elements.
I am posting one of them for which i have set the name same as column name
<div class="form-group panel">
<h6 for="pt-name">Former Name1</h6>
<input type="text" name="company_former_name_one" placeholder="Former Name 1" class="form-control">
</div>
My Controller Code :
public function profile( $id = null )
{
$company = $this->Companies->get( $id );
if ($this->request->is(['post','put']))
{
$post = $this->Companies->patchEntity($post, $this->request->data);
// $post->modified = date("Y-m-d H:i:s");
if( $this->Companies->save($post) )
{
}
}
$this->set('company', $company);
}
CakePHP is not magic
i cannot put the form helpers now, given the time line
The simplest and fastest way to do what you're asking is to use helpers.
I was wondering if there is any default way to set form "context" when not using form helpers
No.
For that to work would require the framework to parse the static html from the template, figure out which bits are supposed to be dynamic, apply some magic/assumptions and then dump the html. CakePHP does not work in this way.
Use helpers
Instead of static html, use appropriate helper methods. For example FormHelper::text
<div class="form-group panel">
<h6 for="pt-name">Former Name1</h6>
<?= $this->Form->text('former_name1') ?>
</div>
Which will generate something like:
<div class="form-group panel">
<h6 for="pt-name">Former Name1</h6>
<input name="former_name1" value="default" type="text">
</div>

How to format the name of the checkbox while send by a GET cakephp

I would like to know if it's possible to format the name of the checkbox when I try to send it to my other page via a GET method.
Actually I've got a multiple checkboxes that generate something like:
<div class="checkbox"><input type="checkbox" name="test[]" value="1" id="ResearchTest1" /><label for="ResearchTest1">First Test</label></div>
<div class="checkbox"><input type="checkbox" name="test[]" value="2" id="ResearchTest2" /><label for="ResearchTest2">Second Test</label></div>
<div class="checkbox"><input type="checkbox" name="test[]" value="3" id="ResearchTest3" /><label for="ResearchTest3">Third Test</label></div>
And when I send my form, my URL looks like:
research%3D%26test%3D%26test%5B%5D%3D1%26test%5B%5D%3D2%26test%5B%5D%3D3
Which is :
research=&test=&test[]=1&test[]=2&test[]=3
And what I would like, will be:
research=&test1=1&test2=2&test3=3
Or
research=&test=1&test=2&test=3
Or, much better:
research=&test=1,2,3
Any ideas ?
That is how checkboxes work, if you want test1=1&test2=2&test3=3 then you should name each checkbox individually.
echo $this->Form->checkbox('foo', array('name' => 'test1'));
echo $this->Form->checkbox('foo', array('name' => 'test2'));
echo $this->Form->checkbox('foo', array('name' => 'test3'));
This will make your processing much harder.
You can do research=&test=1,2,3 with JS join(). Why you want to make this difficult for yourself I dont know. You can easily get that same format in the controller doint the GET with implode(',', $theData)
I would recommend using standards for submitting your form and process the data later.
You can define the name of the input using the FormHelper:
echo $this->Form->checkbox('yourInputId', array('name' => 'yourInputName'));
The problem is that I use a multiple checkboxes:
$this->Form->input('tests', array('type' => 'select', 'multiple' => 'checkbox', 'options' => $options));
So I can't rename each checkbox individually.
Maybe I should not use cakephp for this, but try to write my own checkboxes directly in html?

Cakephp - Change validation errors div structure?

Is there any way of changing the validation error div structure? I want to insert an image just before the div.
Each error will be displayed inline with the input field, so I want to insert a left arrow image before the validation div.
Currently I am getting this:
<div class="input password required error">
<label for="StudentPassword1">Password</label>
<input type="password" name="data[Student][password1]" value="" id="StudentPassword1" class="form-error">
<div class="error-message">notempty</div>
</div>
I'd like:
<div class="input password required error">
<label for="StudentPassword1">Password</label>
<input type="password" name="data[Student][password1]" value="" id="StudentPassword1" class="form-error">
<img src='...' />
<div class="error-message">notempty</div>
</div>
How would you accomplish this? I'm guessing that I have to modify the core? Thanks
I'm guessing that I have to modify the core?
No. If your app requires changing Cake's core you are likely doing something wrong. Cake has a lot going on and it takes care of a lot of things for you. This happens to be one of the things you can customize to your liking.
When you create your Forms with the FormHelper you can specify default options for input() and one of those options includes the HTML structure and class used to wrap error messages.
I would just modify the CSS of the error-message class to include the image.
.error-message {
background:url( path/to/img.png ) no-repeat top left;
padding-left:40px; /* or whatever you need for the image to fit */
}
<?php echo $this->Form->create('User', array('class'=>'form-horizontal',
'inputDefaults' => array('error' => array(
'attributes' => array(
'wrap' => 'label', 'class' => 'text-error'
)
) )
)); ?>
This will make you customize the error output.

CakePHP Form Helper just generated too much code for me

I am using cakePHP.
I used the cakePHP built-in Form Helper to generate an input text box:
echo $form->input('quote', array('label'=>'Post Number', 'class'=>''));
But when I looked at the HTML source code, I found out these:
<div class="input text">
<label for="ReplyQuote">Post Number</label>
<input name="data[Reply][quote]" type="text" class="" maxlength="12" value="1" id="ReplyQuote" />
</div>
It's really more than enough. I mean the code generated by the Cake built-in Form Helper.
Those DIV tags with class named in a strange naming convention way are not helpful,
because there is space in between the Class name like:
<div class="input text">
Does CakePHP have any options for users to omit those DIV Tags?
Yes.
Check out the options array that you can pass to the FormHelper::input() method. Book reference is at http://book.cakephp.org/view/189/Automagic-Form-Elements
In short, the form helper is adding two distinct classes to the div -- input, and text. If you don't want a div, just do:
echo $form->input( 'quote', array( 'label' => 'Post Number', 'div' => false ) );
Setting the options['class'] value only affects the class selector assigned to the actual input itself (see in your HTML code how the input tag has class=""?)
you can also use $form->text() for input box.

How can I display CakePHP input validation errors in a different spot the default?

Let's say I have field that looks like this in the view:
<li class="bigfield">
<?php echo $form->input('phone', array(
'placeholder' => 'Phone',
'label' => false,
'between' => '<br />'
)); ?>
</li>
If I have a validation rule on this field and validation fails, I see the following HTML:
<li class="bigfield">
<div class="input text required error">
<br>
<input name="data[Appointment][email]" type="text" placeholder="Email"
maxlength="45" value="" id="AppointmentEmail" class="form-error">
<div class="error-message">Please enter a valid email address</div>
</div>
</li>
I'm like to do something like move the error message div to an entire different part of the page rather then have it inside with the same <li> as the field itself. What would be the most straight forward way of doing this?
Just updating an old post.
The validations errors are automatically passed on to view (as pointed out by #Angel S. Moreno)
$this->validationErrors
In you controller:
$this->set('validationErrorsArray', $this->ModelName->invalidFields());
You will have $validationErrorsArray in your views.
UPDATE (Sept. 2014):
From the view
From CakePHP 2.3 you can access validation errors array from the view:
$this->validationErrors;
From the controller
If you tried to save data in the controller you can access validation errors this way:
$this->ModelName->validationErrors;
If you want to validate data before saving do it this way:
$this->ModelName->set($this->request->data);
if ($this->ModelName->validates()) {
$this->ModelName->save();
} else {
$errors = $this->ModelName->validationErrors;
// handle errors
}
Validating Data from the Controller
From controller you can use:
$this->Modelname->validationErrors['TheFieldYouWantToDisplay'] = 'This is not correct'
In your case it would be like this in your controller:
$this->Appointment->validationErrors['email'] = 'Error message'
This code is just to make a custom error message on the fly. But you can also define $validate in the model and do it like how brancer has described it.

Resources